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@1649482 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/.classpath b/.classpath
index f388807..381b33c 100644
--- a/.classpath
+++ b/.classpath
@@ -14,7 +14,6 @@
     <classpathentry kind="lib" path="framework/base/lib/ant-1.9.0-ant-junit.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/ant-1.9.0-ant-launcher.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/ant/ant-1.9.0-ant-apache-bsf.jar"/>
-    <classpathentry kind="lib" path="framework/base/lib/antisamy-bin.1.2.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/avalon-framework-4.2.0.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/barcode4j-2.1-barcode4j-fop-ext-complete.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/batik-all-1.7.jar"/>
@@ -42,7 +41,7 @@
     <classpathentry kind="lib" path="framework/base/lib/log4j-api-2.0.1.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/mail-1.5.1.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/nekohtml-1.9.16.jar"/>
-    <classpathentry kind="lib" path="framework/base/lib/owasp-esapi-full-java-1.4-patched-by-OFBIZ-3135.jar"/>
+    <classpathentry kind="lib" path="framework/base/lib/esapi-2.1.0.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/resolver-2.9.1.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/serializer-2.9.1.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/slf4j-api-1.6.4.jar"/>
diff --git a/LICENSE b/LICENSE
index c545c4f..e5a507e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -111,6 +111,7 @@
 applications/product/lib/dozer-4.2.1.jar
 applications/product/lib/watermarker-0.0.4.jar
 framework/images/webapp/images/date/timezones*
+framework/resources/fonts/NotoSans/*
 =========================================================================
                                  Apache License
                            Version 2.0, January 2004
@@ -436,7 +437,6 @@
 The following libraries distributed with Apache OFBiz are licensed under the
 BSD License:
 applications/content/lib/dom4j-1.6.1.jar
-framework/base/lib/antisamy-bin.1.2.jar
 framework/base/lib/bsh-engine-modified.jar
 framework/base/lib/hamcrest-all-1.2.jar
 framework/base/lib/httpunit-1.7.jar
@@ -444,7 +444,7 @@
 framework/base/lib/javolution-5.4.3.jar
 framework/base/lib/xpp3-1.1.4c.jar
 framework/base/lib/xstream-1.4.6.jar
-framework/base/lib/owasp-esapi-full-java-1.4.jar
+framework/base/lib/esapi-2.1.0.jar
 framework/base/lib/scripting/antlr-2.7.6.jar
 framework/base/lib/scripting/asm-3.2.jar
 framework/base/lib/scripting/jline-0.9.94.jar
diff --git a/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceWorker.java b/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceWorker.java
index eadac66..3e65de9 100644
--- a/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceWorker.java
+++ b/applications/accounting/src/org/ofbiz/accounting/invoice/InvoiceWorker.java
@@ -296,6 +296,7 @@
         if (UtilValidate.isEmpty(locations))    {
             // if no locations found get it from the PartyAndContactMech using the from and to party on the invoice
             String destinationPartyId = null;
+            Timestamp now = UtilDateTime.nowTimestamp();
             if (invoice.getString("invoiceTypeId").equals("SALES_INVOICE"))
                 destinationPartyId = invoice.getString("partyId");
             if (invoice.getString("invoiceTypeId").equals("PURCHASE_INVOICE"))
@@ -303,8 +304,8 @@
             try {
                 locations = EntityQuery.use(delegator).from("PartyContactWithPurpose")
                         .where("partyId", destinationPartyId, "contactMechPurposeTypeId", contactMechPurposeTypeId).queryList();
-                locations = EntityUtil.filterByDate(locations, null, "contactFromDate", "contactThruDate", true);
-                locations = EntityUtil.filterByDate(locations, null, "purposeFromDate", "purposeThruDate", true);
+                locations = EntityUtil.filterByDate(locations, now, "contactFromDate", "contactThruDate", true);
+                locations = EntityUtil.filterByDate(locations, now, "purposeFromDate", "purposeThruDate", true);
             } catch (GenericEntityException e) {
                 Debug.logError("Trouble getting contact party purpose list", module);
             }
@@ -313,8 +314,8 @@
                 try {
                     locations = EntityQuery.use(delegator).from("PartyContactWithPurpose")
                             .where("partyId", destinationPartyId, "contactMechPurposeTypeId", "GENERAL_LOCATION").queryList();
-                    locations = EntityUtil.filterByDate(locations, null, "contactFromDate", "contactThruDate", true);
-                    locations = EntityUtil.filterByDate(locations, null, "purposeFromDate", "purposeThruDate", true);
+                    locations = EntityUtil.filterByDate(locations, now, "contactFromDate", "contactThruDate", true);
+                    locations = EntityUtil.filterByDate(locations, now, "purposeFromDate", "purposeThruDate", true);
                 } catch (GenericEntityException e) {
                     Debug.logError("Trouble getting contact party purpose list", module);
                 }
diff --git a/applications/accounting/src/org/ofbiz/accounting/payment/PaymentMethodServices.java b/applications/accounting/src/org/ofbiz/accounting/payment/PaymentMethodServices.java
index 5f1fce4..453e0e4 100644
--- a/applications/accounting/src/org/ofbiz/accounting/payment/PaymentMethodServices.java
+++ b/applications/accounting/src/org/ofbiz/accounting/payment/PaymentMethodServices.java
@@ -216,8 +216,8 @@
             try {
                 List<GenericValue> allPCWPs = EntityQuery.use(delegator).from("PartyContactWithPurpose")
                         .where("partyId", partyId, "contactMechId", contactMechId, "contactMechPurposeTypeId", contactMechPurposeTypeId).queryList();
-                allPCWPs = EntityUtil.filterByDate(allPCWPs, null, "contactFromDate", "contactThruDate", true);
-                allPCWPs = EntityUtil.filterByDate(allPCWPs, null, "purposeFromDate", "purposeThruDate", true);
+                allPCWPs = EntityUtil.filterByDate(allPCWPs, now, "contactFromDate", "contactThruDate", true);
+                allPCWPs = EntityUtil.filterByDate(allPCWPs, now, "purposeFromDate", "purposeThruDate", true);
                 tempVal = EntityUtil.getFirst(allPCWPs);
             } catch (GenericEntityException e) {
                 Debug.logWarning(e.getMessage(), module);
@@ -391,8 +391,8 @@
             try {
                 List<GenericValue> allPCWPs = EntityQuery.use(delegator).from("PartyContactWithPurpose")
                         .where("partyId", partyId, "contactMechId", contactMechId, "contactMechPurposeTypeId", contactMechPurposeTypeId).queryList();
-                allPCWPs = EntityUtil.filterByDate(allPCWPs, null, "contactFromDate", "contactThruDate", true);
-                allPCWPs = EntityUtil.filterByDate(allPCWPs, null, "purposeFromDate", "purposeThruDate", true);
+                allPCWPs = EntityUtil.filterByDate(allPCWPs, now, "contactFromDate", "contactThruDate", true);
+                allPCWPs = EntityUtil.filterByDate(allPCWPs, now, "purposeFromDate", "purposeThruDate", true);
 
                 tempVal = EntityUtil.getFirst(allPCWPs);
             } catch (GenericEntityException e) {
@@ -732,8 +732,8 @@
             try {
                 List<GenericValue> allPCWPs = EntityQuery.use(delegator).from("PartyContactWithPurpose")
                         .where("partyId", partyId, "contactMechId", contactMechId, "contactMechPurposeTypeId", contactMechPurposeTypeId).queryList();
-                allPCWPs = EntityUtil.filterByDate(allPCWPs, null, "contactFromDate", "contactThruDate", true);
-                allPCWPs = EntityUtil.filterByDate(allPCWPs, null, "purposeFromDate", "purposeThruDate", true);
+                allPCWPs = EntityUtil.filterByDate(allPCWPs, now, "contactFromDate", "contactThruDate", true);
+                allPCWPs = EntityUtil.filterByDate(allPCWPs, now, "purposeFromDate", "purposeThruDate", true);
 
                 tempVal = EntityUtil.getFirst(allPCWPs);
             } catch (GenericEntityException e) {
@@ -861,8 +861,8 @@
             try {
                 List<GenericValue> allPCWPs = EntityQuery.use(delegator).from("PartyContactWithPurpose")
                         .where("partyId", partyId, "contactMechId", contactMechId, "contactMechPurposeTypeId", contactMechPurposeTypeId).queryList();
-                allPCWPs = EntityUtil.filterByDate(allPCWPs, null, "contactFromDate", "contactThruDate", true);
-                allPCWPs = EntityUtil.filterByDate(allPCWPs, null, "purposeFromDate", "purposeThruDate", true);
+                allPCWPs = EntityUtil.filterByDate(allPCWPs, now, "contactFromDate", "contactThruDate", true);
+                allPCWPs = EntityUtil.filterByDate(allPCWPs, now, "purposeFromDate", "purposeThruDate", true);
                 tempVal = EntityUtil.getFirst(allPCWPs);
             } catch (GenericEntityException e) {
                 Debug.logWarning(e.getMessage(), module);
diff --git a/applications/accounting/src/org/ofbiz/accounting/period/PeriodServices.java b/applications/accounting/src/org/ofbiz/accounting/period/PeriodServices.java
index 2c1b848..4da8e42 100644
--- a/applications/accounting/src/org/ofbiz/accounting/period/PeriodServices.java
+++ b/applications/accounting/src/org/ofbiz/accounting/period/PeriodServices.java
@@ -71,7 +71,7 @@
                 // if a periodTypeId was supplied, use it
                 findClosedConditions.add(EntityCondition.makeConditionMap("periodTypeId", periodTypeId));
             }
-            GenericValue closedTimePeriod = EntityQuery.use(delegator).select("customTimePeriodId", "periodTypeId", "isClosed", "fromDate", "thruDate")
+            GenericValue closedTimePeriod = EntityQuery.use(delegator).from("CustomTimePeriod").select("customTimePeriodId", "periodTypeId", "isClosed", "fromDate", "thruDate")
                     .where(findClosedConditions).orderBy("thruDate DESC").queryFirst();
 
             if (closedTimePeriod != null && closedTimePeriod.get("thruDate") != null) {
@@ -88,8 +88,7 @@
                 if (timePeriod != null && timePeriod.get("fromDate") != null) {
                     lastClosedDate = UtilDateTime.toTimestamp(timePeriod.getDate("fromDate"));
                 } else {
-                    return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
-                            "AccountingPeriodCannotGet", locale));
+                    return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingPeriodCannotGet", locale));
                 }
             }
 
diff --git a/applications/accounting/src/org/ofbiz/accounting/thirdparty/clearcommerce/CCPaymentServices.java b/applications/accounting/src/org/ofbiz/accounting/thirdparty/clearcommerce/CCPaymentServices.java
index 47a6c32..eda682e 100644
--- a/applications/accounting/src/org/ofbiz/accounting/thirdparty/clearcommerce/CCPaymentServices.java
+++ b/applications/accounting/src/org/ofbiz/accounting/thirdparty/clearcommerce/CCPaymentServices.java
@@ -865,7 +865,7 @@
         Element instructionsElement = UtilXml.addChildElement(engineDocElement, "Instructions", requestDocument);
 
         String pipeline = "PaymentNoFraud";
-        if (UtilProperties.propertyValueEqualsIgnoreCase(paymentConfig, "payment.clearcommerce.enableFraudShield", "Y")) {
+        if (EntityUtilProperties.propertyValueEqualsIgnoreCase(paymentConfig, "payment.clearcommerce.enableFraudShield", "Y", delegator)) {
             pipeline = "Payment";
         }
         UtilXml.addChildElementValue(instructionsElement, "Pipeline", pipeline, requestDocument);
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/admin/ListInvoiceItemTypesGlAccount.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/admin/ListInvoiceItemTypesGlAccount.groovy
index db5fc00..fa4d548 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/admin/ListInvoiceItemTypesGlAccount.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/admin/ListInvoiceItemTypesGlAccount.groovy
@@ -30,7 +30,7 @@
 
 organizationPartyId = parameters.organizationPartyId;
 exprBldr = new EntityConditionBuilder();
-invoiceItemTypes = delegator.findList("InvoiceItemType", exprBldr.LIKE(invoiceItemTypeId: invItemTypePrefix), null, null, null, false);
+invoiceItemTypes = from('InvoiceItemType').where(exprBldr.LIKE(invoiceItemTypeId: invItemTypePrefix)).queryList();
 
 context.invoiceItemTypes = invoiceItemTypes.collect { invoiceItemType ->
     defaultAccount = true
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/chartofaccounts/TaxAuthorityGlAccounts.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/chartofaccounts/TaxAuthorityGlAccounts.groovy
index d75efce..9be8879 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/chartofaccounts/TaxAuthorityGlAccounts.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/chartofaccounts/TaxAuthorityGlAccounts.groovy
@@ -20,7 +20,7 @@
 import org.ofbiz.base.util.UtilMisc;
 import javolution.util.FastList;
 
-taxAuthorities = delegator.findList("TaxAuthority", null, null, ["taxAuthGeoId", "taxAuthPartyId"], null, false);
+taxAuthorities = from('TaxAuthority').orderBy("taxAuthGeoId", "taxAuthPartyId").queryList();
 
 context.taxAuthorityHavingNoGlAccountList = taxAuthorities.findAll { taxAuthority ->
     !taxAuthority.getRelated('TaxAuthorityGlAccount', [organizationPartyId : organizationPartyId], null, false)
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/fixedasset/FixedAssetGeoLocation.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/fixedasset/FixedAssetGeoLocation.groovy
index 4290d42..8f25454 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/fixedasset/FixedAssetGeoLocation.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/fixedasset/FixedAssetGeoLocation.groovy
@@ -38,7 +38,7 @@
             context.geoChart = geoChart;
         }
         if (latestGeoPoint.elevationUomId) {
-            elevationUom = delegator.findOne("Uom", [uomId : latestGeoPoint.elevationUomId], false);
+            elevationUom = from('Uom').where('uomId', atestGeoPoint.elevationUomId).queryOne()
             context.elevationUomAbbr = elevationUom.abbreviation;
         }
     }
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/EditInvoice.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/EditInvoice.groovy
index f6ca69e..c3f95f5 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/EditInvoice.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/EditInvoice.groovy
@@ -35,7 +35,7 @@
 
 invoiceId = parameters.get("invoiceId");
 
-invoice = delegator.findOne("Invoice", [invoiceId : invoiceId], false);
+invoice = from('Invoice').where('invoiceId', invoiceId).queryOne();
 context.invoice = invoice;
 
 currency = parameters.currency;        // allow the display of the invoice in the original currency, the default is to display the invoice in the default currency
@@ -77,13 +77,17 @@
         // also create a map with tax grand total amount by VAT tax: it is also required in invoices by UE
         taxRate = invoiceItem.getRelatedOne("TaxAuthorityRateProduct", false);
         if (taxRate && "VAT_TAX".equals(taxRate.taxAuthorityRateTypeId)) {
-            taxInfos = EntityUtil.filterByDate(delegator.findByAnd("PartyTaxAuthInfo", [partyId : billToParty.partyId, taxAuthGeoId : taxRate.taxAuthGeoId, taxAuthPartyId : taxRate.taxAuthPartyId], null, false), invoice.invoiceDate);
-            taxInfo = EntityUtil.getFirst(taxInfos);
+            taxInfo = from("PartyTaxAuthInfo")
+                .where('partyId', billToParty.partyId, 'taxAuthGeoId', taxRate.taxAuthGeoId, 'taxAuthPartyId', taxRate.taxAuthPartyId)
+                .filterByDate(invoice.invoiceDate)
+                .queryFirst();
             if (taxInfo) {
                 context.billToPartyTaxId = taxInfo.partyTaxId;
             }
-            taxInfos = EntityUtil.filterByDate(delegator.findByAnd("PartyTaxAuthInfo", [partyId : sendingParty.partyId, taxAuthGeoId : taxRate.taxAuthGeoId, taxAuthPartyId : taxRate.taxAuthPartyId], null, false), invoice.invoiceDate);
-            taxInfo = EntityUtil.getFirst(taxInfos);
+            taxInfo = from("PartyTaxAuthInfo")
+                .where('partyId', sendingParty.partyId, 'taxAuthGeoId', taxRate.taxAuthGeoId, 'taxAuthPartyId', taxRate.taxAuthPartyId)
+                .filterByDate(invoice.invoiceDate)
+                .queryFirst();
             if (taxInfo) {
                 context.sendingPartyTaxId = taxInfo.partyTaxId;
             }
@@ -135,10 +139,10 @@
     terms = invoice.getRelated("InvoiceTerm", null, null, false);
     context.terms = terms;
 
-    paymentAppls = delegator.findByAnd("PaymentApplication", [invoiceId : invoiceId], null, false);
+    paymentAppls = from("PaymentApplication").where('invoiceId', invoiceId).queryList();
     context.payments = paymentAppls;
 
-    orderItemBillings = delegator.findByAnd("OrderItemBilling", [invoiceId : invoiceId], ['orderId'], false);
+    orderItemBillings = from("OrderItemBilling").where('invoiceId', invoiceId).orderBy('orderId').queryList();
     orders = new LinkedHashSet();
     orderItemBillings.each { orderIb ->
         orders.add(orderIb.orderId);
@@ -150,7 +154,7 @@
 
     edit = parameters.editInvoice;
     if ("true".equalsIgnoreCase(edit)) {
-        invoiceItemTypes = delegator.findList("InvoiceItemType", null, null, null, null, false);
+        invoiceItemTypes = from("InvoiceItemType").queryList();
         context.invoiceItemTypes = invoiceItemTypes;
         context.editInvoice = true;
     }
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/GetAccountOrganizationAndClass.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/GetAccountOrganizationAndClass.groovy
index 4924b9a..712fd94 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/GetAccountOrganizationAndClass.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/GetAccountOrganizationAndClass.groovy
@@ -40,8 +40,8 @@
         EQUALS(invoiceItemTypeId: "INV_PROD_ITEM")
         EQUALS(parentTypeId: "INV_PROD_ITEM")
     }
-    invoiceItemTypes = delegator.findList("InvoiceItemType", itemTypesCond, null, ["parentTypeId", "invoiceItemTypeId"], null, false);
-    glAccountOrganizationAndClassList = delegator.findByAnd("GlAccountOrganizationAndClass", [organizationPartyId : invoice.partyIdFrom], null, false);
+    invoiceItemTypes = from("InvoiceItemType").where(itemTypesCond).orderBy(["parentTypeId", "invoiceItemTypeId"]).queryList();
+    glAccountOrganizationAndClassList = from("GlAccountOrganizationAndClass").where('organizationPartyId', invoice.partyIdFrom).queryList();
 } else if ("PURCHASE_INVOICE".equals(invoice.invoiceTypeId)) {
     itemTypesCond = exprBldr.OR() {
         EQUALS(invoiceItemTypeId: "PINVOICE_ADJ")
@@ -51,8 +51,8 @@
         EQUALS(invoiceItemTypeId: "PINV_PROD_ITEM")
         EQUALS(parentTypeId: "PINV_PROD_ITEM")
     }
-    invoiceItemTypes = delegator.findList("InvoiceItemType", itemTypesCond, null, ["parentTypeId", "invoiceItemTypeId"], null, false);
-    glAccountOrganizationAndClassList = delegator.findByAnd("GlAccountOrganizationAndClass", [organizationPartyId : invoice.partyId], null, false);
+    invoiceItemTypes = from("InvoiceItemType").where(itemTypesCond).orderBy(["parentTypeId", "invoiceItemTypeId"]).queryList();
+    glAccountOrganizationAndClassList = from("GlAccountOrganizationAndClass").where('organizationPartyId', invoice.partyId).queryList();
 } else if ("PAYROL_INVOICE".equals(invoice.invoiceTypeId)) {
     itemTypesCond = exprBldr.OR() {
         EQUALS(invoiceItemTypeId: "PAYROL_EARN_HOURS")
@@ -62,8 +62,8 @@
         EQUALS(invoiceItemTypeId: "PAYROL_TAXES")
         EQUALS(parentTypeId: "PAYROL_TAXES")
     }
-    invoiceItemTypes = delegator.findList("InvoiceItemType", itemTypesCond, null, ["parentTypeId", "invoiceItemTypeId"], null, false);
-    glAccountOrganizationAndClassList = delegator.findByAnd("GlAccountOrganizationAndClass", [organizationPartyId : invoice.partyId], null, false);
+    invoiceItemTypes = from("InvoiceItemType").where(itemTypesCond).orderBy(["parentTypeId", "invoiceItemTypeId"]).queryList();
+    glAccountOrganizationAndClassList = from("GlAccountOrganizationAndClass").where('organizationPartyId', invoice.partyId).queryList();
 } else if ("COMMISSION_INVOICE".equals(invoice.invoiceTypeId)) {
     itemTypesCond = exprBldr.OR() {
         EQUALS(invoiceItemTypeId: "COMM_INV_ITEM")
@@ -71,10 +71,10 @@
         EQUALS(invoiceItemTypeId: "COMM_INV_ADJ")
         EQUALS(parentTypeId: "COMM_INV_ADJ")
     }
-    invoiceItemTypes = delegator.findList("InvoiceItemType", itemTypesCond, null, ["parentTypeId", "invoiceItemTypeId"], null, false);
-    glAccountOrganizationAndClassList = delegator.findByAnd("GlAccountOrganizationAndClass", [organizationPartyId : invoice.partyId], null, false);
+    invoiceItemTypes = from("InvoiceItemType").where(itemTypesCond).orderBy(["parentTypeId", "invoiceItemTypeId"]).queryList();
+    glAccountOrganizationAndClassList = from("GlAccountOrganizationAndClass").where('organizationPartyId', invoice.partyId).queryList();
 } else {
-    map = delegator.findByAnd("InvoiceItemTypeMap", [invoiceTypeId : invoice.invoiceTypeId], null, true);
+    map = from("InvoiceItemTypeMap").where('invoiceTypeId', invoice.invoiceTypeId).cache(true).queryList();
     invoiceItemTypes = EntityUtil.getRelated("InvoiceItemType", map, null, false);
 }
 context.invoiceItemTypes = invoiceItemTypes;
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/InvoiceReport.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/InvoiceReport.groovy
index 688182d..d5f0598 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/InvoiceReport.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/InvoiceReport.groovy
@@ -42,10 +42,10 @@
     }
     expr = exprBldr.AND([expr, invoiceStatusesCondition]);
 
-    PastDueInvoices = delegator.findList("Invoice", expr, null, ["dueDate DESC"], null, false);
+    PastDueInvoices = from("Invoice").where(expr).orderBy("dueDate DESC").queryList();
     if (PastDueInvoices) {
         invoiceIds = PastDueInvoices.invoiceId;
-        totalAmount = dispatcher.runSync("getInvoiceRunningTotal", [invoiceIds: invoiceIds, organizationPartyId: organizationPartyId, userLogin: userLogin]);
+        totalAmount = runService('getInvoiceRunningTotal', [invoiceIds: invoiceIds, organizationPartyId: organizationPartyId]);
         if (totalAmount) {
             context.PastDueInvoicestotalAmount = totalAmount.invoiceRunningTotal;
         }
@@ -56,12 +56,10 @@
         EQUALS(invoiceTypeId: invoiceTypeId)
         GREATER_THAN_EQUAL_TO(dueDate: UtilDateTime.nowTimestamp())
     }
-    EntityFindOptions findOptions = new EntityFindOptions();
-    findOptions.setMaxRows(10);
-    InvoicesDueSoon = delegator.findList("Invoice", invoicesCond, null, ["dueDate ASC"], findOptions, false);
+    InvoicesDueSoon = from("Invoice").where(invoicesCond).orderBy("dueDate ASC").maxRows(10).queryList();
     if (InvoicesDueSoon) {
         invoiceIds = InvoicesDueSoon.invoiceId;
-        totalAmount = dispatcher.runSync("getInvoiceRunningTotal", [invoiceIds: invoiceIds, organizationPartyId: organizationPartyId, userLogin: userLogin]);
+        totalAmount = runService('getInvoiceRunningTotal', [invoiceIds: invoiceIds, organizationPartyId: organizationPartyId]);
         if (totalAmount) {
             context.InvoicesDueSoonTotalAmount = totalAmount.invoiceRunningTotal;
         }
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/ListNotAppliedPayments.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/ListNotAppliedPayments.groovy
index 00ccb90..fbc6ac1 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/ListNotAppliedPayments.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/ListNotAppliedPayments.groovy
@@ -32,7 +32,7 @@
 import java.math.*;
 
 invoiceId = parameters.invoiceId;
-invoice = delegator.findOne("Invoice", [invoiceId : invoiceId], false);
+invoice = from("Invoice").where(invoiceId : invoiceId).queryOne();
 
 decimals = UtilNumber.getBigDecimalScale("invoice.decimals");
 rounding = UtilNumber.getBigDecimalRoundingMode("invoice.rounding");
@@ -52,9 +52,9 @@
     EQUALS(actualCurrencyUomId: invoice.currencyUomId)
 }
 
-payments = delegator.findList("Payment", topCond, null, ["effectiveDate"], null, false);
+payments = from("Payment").where(topCond).orderBy("effectiveDate").queryList();
 context.payments = getPayments(payments, false);
-payments = delegator.findList("Payment", topCondActual, null, ["effectiveDate"], null, false);
+payments = from("Payment").where(topCondActual).orderBy("effectiveDate").queryList();
 context.paymentsActualCurrency = getPayments(payments, true);
 
 List getPayments(List payments, boolean actual) {
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/PrintInvoices.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/PrintInvoices.groovy
index b57d8c8..02e5c52 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/PrintInvoices.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/invoice/PrintInvoices.groovy
@@ -25,7 +25,7 @@
 invoiceDetailList = [];
 invoiceIds.each { invoiceId ->
     invoicesMap = [:];
-    invoice = delegator.findOne("Invoice", [invoiceId : invoiceId], false);
+    invoice = from("Invoice").where('invoiceId', invoiceId).queryOne();
     invoicesMap.invoice = invoice;
     
     currency = parameters.currency;  // allow the display of the invoice in the original currency, the default is to display the invoice in the default currency
@@ -98,10 +98,10 @@
         terms = invoice.getRelated("InvoiceTerm", null, null, false);
         invoicesMap.terms = terms;
     
-        paymentAppls = delegator.findList("PaymentApplication", EntityCondition.makeCondition([invoiceId : invoiceId]), null, null, null, false);
+        paymentAppls = from("PaymentApplication").where('invoiceId', invoiceId).queryList();
         invoicesMap.payments = paymentAppls;
     
-        orderItemBillings = delegator.findList("OrderItemBilling", EntityCondition.makeCondition([invoiceId : invoiceId]), null, ['orderId'], null, false);
+        orderItemBillings = from("OrderItemBilling").where('invoiceId', invoiceId).orderBy("orderId").queryList();
         orders = new LinkedHashSet();
         orderItemBillings.each { orderIb ->
             orders.add(orderIb.orderId);
@@ -113,7 +113,7 @@
     
         edit = parameters.editInvoice;
         if ("true".equalsIgnoreCase(edit)) {
-            invoiceItemTypes = delegator.findList("InvoiceItemType", null, null, null, null, false);
+            invoiceItemTypes = from("InvoiceItemType").queryList();
             invoicesMap.invoiceItemTypes = invoiceItemTypes;
             invoicesMap.editInvoice = true;
         }
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/order/BillingAccountOrders.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/order/BillingAccountOrders.groovy
index efe70bd..48aabb8 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/order/BillingAccountOrders.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/order/BillingAccountOrders.groovy
@@ -23,11 +23,11 @@
 
 if (billingAccountId) {
     orderPaymentPreferencesList = [];
-    orderList = delegator.findByAnd("OrderHeader", [billingAccountId : billingAccountId], null, false);
+    orderList = from("OrderHeader").where('billingAccountId', billingAccountId).queryList();
     if (orderList) {
         orderList.each { orderHeader ->
             orderId = orderHeader.orderId;
-            orderBillingAcc = EntityUtil.getFirst(delegator.findByAnd("OrderHeaderAndPaymentPref", [orderId : orderId], null, false));
+            orderBillingAcc = from("OrderHeaderAndPaymentPref").where("orderId", orderId).queryFirst();
             orderBillingAccMap = FastMap.newInstance();
             if (orderBillingAcc.paymentMethodTypeId.equals("EXT_BILLACT") && orderBillingAcc.paymentStatusId.equals("PAYMENT_NOT_RECEIVED")) {
                 orderBillingAccMap.putAll(orderBillingAcc);
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/payment/BillingAccounts.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/payment/BillingAccounts.groovy
index 7957603..8e5d6e7 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/payment/BillingAccounts.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/payment/BillingAccounts.groovy
@@ -24,7 +24,7 @@
 currencyUomId = null;
 billingAccounts = [];
 if (partyId) {
-    billingAccountAndRoles = delegator.findByAnd("BillingAccountAndRole", [partyId : partyId], null, false);
+    billingAccountAndRoles = from("BillingAccountAndRole").where('partyId', partyId).queryList()
     if (billingAccountAndRoles) currencyUomId = billingAccountAndRoles.first().accountCurrencyUomId;
     if (currencyUomId) billingAccounts = BillingAccountWorker.makePartyBillingAccountList(userLogin, currencyUomId, partyId, delegator, dispatcher);
 }
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/payment/DepositWithdrawPayments.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/payment/DepositWithdrawPayments.groovy
index bf037c9..61290e6 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/payment/DepositWithdrawPayments.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/payment/DepositWithdrawPayments.groovy
@@ -25,9 +25,7 @@
 if ("Y".equals(parameters.noConditionFind)) {
     List exprListForParameters = [];
     
-    finAcctCond = EntityCondition.makeCondition([EntityCondition.makeCondition("finAccountId", EntityOperator.EQUALS, finAccountId),
-                                                 EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, "DIVISION")], EntityOperator.AND);
-    finAccountRoles = EntityUtil.filterByDate(delegator.findList("FinAccountRole", finAcctCond, null, null, null, false));
+    finAccountRoles = from("FinAccountRole").where("finAccountId", finAccountId, "roleTypeId", "DIVISION").filterByDate().queryList();
     finAccountPartyIds = EntityUtil.getFieldListFromEntityList(finAccountRoles, "partyId", true);
     finAccountPartyIds.add(organizationPartyId);
     partyCond = EntityCondition.makeCondition([EntityCondition.makeCondition("partyIdTo", EntityOperator.IN, finAccountPartyIds),
@@ -50,12 +48,12 @@
     exprListForParameters.add(EntityCondition.makeCondition("finAccountTransId", EntityOperator.EQUALS, null));
     paramCond = EntityCondition.makeCondition(exprListForParameters, EntityOperator.AND);
     combinedPaymentCond = EntityCondition.makeCondition([partyCond, statusCond, paramCond], EntityOperator.AND);
-    payments = delegator.findList("PaymentAndTypePartyNameView", combinedPaymentCond, null, null, null, false);
+    payments = from("PaymentAndTypePartyNameView").where(combinedPaymentCond).queryList();
     paymentListWithCreditCard = [];
     paymentListWithoutCreditCard = [];
     payments.each { payment ->
         if (cardType && payment.paymentMethodId) {
-            creditCard = delegator.findOne("CreditCard", [paymentMethodId : payment.paymentMethodId], false);
+            creditCard = from("CreditCard").where('paymentMethodId', payment.paymentMethodId).queryOne();
             if (creditCard.cardType == cardType) {
                 paymentListWithCreditCard.add(payment);
             }
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/payment/ListNotAppliedInvoices.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/payment/ListNotAppliedInvoices.groovy
index 87fc482..42bb2d4 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/payment/ListNotAppliedInvoices.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/payment/ListNotAppliedInvoices.groovy
@@ -31,7 +31,7 @@
 import java.math.*;
 
 paymentId = parameters.paymentId;
-payment = delegator.findOne("Payment", [paymentId : paymentId], false);
+payment = from("Payment").where("paymentId", paymentId).queryOne();
 
 decimals = UtilNumber.getBigDecimalScale("invoice.decimals");
 rounding = UtilNumber.getBigDecimalRoundingMode("invoice.rounding");
@@ -51,13 +51,20 @@
 
 topCond = EntityCondition.makeCondition([partyCond, statusCond, currCond], EntityOperator.AND);
 topCondActual = EntityCondition.makeCondition([partyCond, statusCond, actualCurrCond], EntityOperator.AND);
-fields = new HashSet(["invoiceId", "invoiceTypeId", "currencyUomId", "description", "invoiceDate"]);
 
 //retrieve invoices for the related parties which have not been (fully) applied yet and which have the same currency as the payment
-invoices = delegator.findList("Invoice", topCond, fields, ["invoiceDate"], null, false);
+invoices = select("invoiceId", "invoiceTypeId", "currencyUomId", "description", "invoiceDate")
+                .from("Invoice")
+                .where(topCond)
+                .orderBy("invoiceDate")
+                .queryList();
 context.invoices = getInvoices(invoices, false);
 //retrieve invoices for the related parties which have not been (fully) applied yet and which have the same originalCurrency as the payment
-invoices = delegator.findList("Invoice", topCondActual, fields, ["invoiceDate"], null, false);
+invoices = select("invoiceId", "invoiceTypeId", "currencyUomId", "description", "invoiceDate")
+                .from("Invoice")
+                .where(topCondActual)
+                .orderBy("invoiceDate")
+                .queryList();
 context.invoicesOtherCurrency = getInvoices(invoices, true);
 
 List getInvoices(List invoices, boolean actual) {
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/payment/ListNotAppliedPayments.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/payment/ListNotAppliedPayments.groovy
index 65d6f97..e4a2c3c 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/payment/ListNotAppliedPayments.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/payment/ListNotAppliedPayments.groovy
@@ -34,7 +34,7 @@
 import java.text.NumberFormat;
 
 basePaymentId = parameters.paymentId;
-basePayment = delegator.findOne("Payment", [paymentId : basePaymentId], false);
+basePayment = from("Payment").where("paymentId", basePaymentId).queryOne();
 
 decimals = UtilNumber.getBigDecimalScale("invoice.decimals");
 rounding = UtilNumber.getBigDecimalRoundingMode("invoice.rounding");
@@ -62,7 +62,7 @@
 
 topCond = EntityCondition.makeCondition(exprList, EntityOperator.AND);
 
-payments = delegator.findList("Payment", topCond, null, ["effectiveDate"], null, false);
+payments = from("Payment").where(topCond).orderBy("effectiveDate").queryList()
 
 if (payments)    {
     basePaymentApplied = PaymentWorker.getPaymentApplied(basePayment);
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/payment/ManualTx.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/payment/ManualTx.groovy
index 8b5a162..5897a68 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/payment/ManualTx.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/payment/ManualTx.groovy
@@ -20,18 +20,18 @@
 import org.ofbiz.base.util.*;
 
 // stores
-productStores = delegator.findList("ProductStore", null, null, ["storeName"], null, true);
+productStores = from("ProductStore").orderBy("storeName").cache(true).queryList();
 context.productStores = productStores;
 
 // current store
 productStoreId = parameters.productStoreId;
 if (productStoreId) {
-    productStore = delegator.findOne("ProductStore", [productStoreId : productStoreId], false);
+    productStore = from("ProductStore").where("productStoreId", productStoreId).queryOne();
     context.currentStore = productStore;
 }
 
 // payment settings
-paymentSettings = delegator.findByAnd("Enumeration", [enumTypeId : "PRDS_PAYSVC"], ["sequenceId"], false);
+paymentSettings = from("Enumeration").where("enumTypeId", "PRDS_PAYSVC").orderBy("sequenceId").queryList();
 context.paymentSettings = paymentSettings;
 
 // payment method (for auto-fill)
@@ -46,12 +46,12 @@
 txType = parameters.transactionType;
 context.txType = txType;
 if (txType) {
-    currentTx = delegator.findOne("Enumeration", [enumId : txType], false);
+    currentTx = from("Enumeration").where("enumId", txType).queryOne();
     context.currentTx = currentTx;
 }
 
 if (paymentMethodId) {
-    paymentMethod = delegator.findOne("PaymentMethod", [paymentMethodId : paymentMethodId], false);
+    paymentMethod = from("PaymentMethod").where("paymentMethodId", paymentMethodId).queryOne();
     if (paymentMethod) {
         // payment method type
         paymentMethodTypeId = paymentMethod.paymentMethodTypeId;
@@ -82,7 +82,7 @@
 }
 
 if (paymentMethodTypeId) {
-    paymentMethodType = delegator.findOne("PaymentMethodType", [paymentMethodTypeId : paymentMethodTypeId], false);
+    paymentMethodType = from("PaymentMethodType").where("paymentMethodTypeId", paymentMethodTypeId).queryOne();
     context.paymentMethodType = paymentMethodType;
     context.paymentMethodTypeId = paymentMethodTypeId;
 }
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/payment/PrintChecks.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/payment/PrintChecks.groovy
index 63f116f..12078c2 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/payment/PrintChecks.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/payment/PrintChecks.groovy
@@ -45,7 +45,7 @@
 // in the case of a single payment, the paymentId will be supplied
 paymentId = context.paymentId;
 if (paymentId) {
-    payment = delegator.findOne("Payment", [paymentId : paymentId], false);
+    payment = from("Payment").where("paymentId", paymentId).queryOne();
     if (payment) payments.add(payment);
     context.payments = payments;
     return;
@@ -54,12 +54,12 @@
 // in the case of a multi form, parse the multi data and get all of the selected payments
 selected = UtilHttp.parseMultiFormData(parameters);
 selected.each { row ->
-    payment = delegator.findOne("Payment", [paymentId : row.paymentId], false);
+    payment = from("Payment").where("paymentId", row.paymentId).queryOne();
     if (payment) {
         payments.add(payment);
     }
 }
-paymentGroupMembers = EntityUtil.filterByDate(delegator.findList("PaymentGroupMember", EntityCondition.makeCondition("paymentGroupId", EntityOperator.EQUALS, parameters.paymentGroupId), null, null, null, false));
+paymentGroupMembers = from("PaymentGroupMember").where("paymentGroupId", parameters.paymentGroupId).filterByDate().queryList();
 //in the case of a multiple payments, paymentId List is supplied.
 paymentGroupMembers.each { paymentGropupMember->
     payments.add(paymentGropupMember.getRelatedOne("Payment", false));
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/period/EditCustomTimePeriod.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/period/EditCustomTimePeriod.groovy
index 6ce8fb8..a5b3861 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/period/EditCustomTimePeriod.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/period/EditCustomTimePeriod.groovy
@@ -33,7 +33,7 @@
     context.currentCustomTimePeriodId = currentCustomTimePeriodId;
 }
 
-currentCustomTimePeriod = currentCustomTimePeriodId ? delegator.findOne("CustomTimePeriod", [customTimePeriodId : currentCustomTimePeriodId], false) : null;
+currentCustomTimePeriod = currentCustomTimePeriodId ? from("CustomTimePeriod").where("customTimePeriodId", currentCustomTimePeriodId).queryOne() : null;
 if (currentCustomTimePeriod) {
     context.currentCustomTimePeriod = currentCustomTimePeriod;
 }
@@ -47,13 +47,13 @@
 if (findOrganizationPartyId) findMap.organizationPartyId = findOrganizationPartyId;
 if (currentCustomTimePeriodId) findMap.parentPeriodId = currentCustomTimePeriodId;
 
-customTimePeriods = delegator.findByAnd("CustomTimePeriod", findMap, ["periodTypeId", "periodNum", "fromDate"], false);
+customTimePeriods = from("CustomTimePeriod").where(findMap).orderBy(["periodTypeId", "periodNum", "fromDate"]).queryList();
 context.customTimePeriods = customTimePeriods;
 
-allCustomTimePeriods = delegator.findList("CustomTimePeriod", null, null, ["organizationPartyId", "parentPeriodId", "periodTypeId", "periodNum", "fromDate"], null, false);
+allCustomTimePeriods = from("CustomTimePeriod").orderBy(["organizationPartyId", "parentPeriodId", "periodTypeId", "periodNum", "fromDate"]).queryList();
 context.allCustomTimePeriods = allCustomTimePeriods;
 
-periodTypes = delegator.findList("PeriodType", null, null, ["description"], null, true);
+periodTypes = from("PeriodType").orderBy("description").cache(true).queryList();
 context.periodTypes = periodTypes;
 
 newPeriodTypeId = "FISCAL_YEAR";
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/BalanceSheet.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/BalanceSheet.groovy
index dafa616..18d3dec 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/BalanceSheet.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/BalanceSheet.groovy
@@ -45,27 +45,27 @@
 partyIds.add(organizationPartyId);
 
 // Get the group of account classes that will be used to position accounts in the proper section of the financial statement
-GenericValue assetGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "ASSET"), true);
+GenericValue assetGlAccountClass = from("GlAccountClass").where("glAccountClassId", "ASSET").cache(true).queryOne();
 List assetAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(assetGlAccountClass);
-GenericValue contraAssetGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "CONTRA_ASSET"), true);
+GenericValue contraAssetGlAccountClass = from("GlAccountClass").where("glAccountClassId", "CONTRA_ASSET").cache(true).queryOne();
 List contraAssetAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(contraAssetGlAccountClass);
-GenericValue liabilityGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "LIABILITY"), true);
+GenericValue liabilityGlAccountClass = from("GlAccountClass").where("glAccountClassId", "LIABILITY").cache(true).queryOne();
 List liabilityAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(liabilityGlAccountClass);
-GenericValue equityGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "EQUITY"), true);
+GenericValue equityGlAccountClass = from("GlAccountClass").where("glAccountClassId", "EQUITY").cache(true).queryOne();
 List equityAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(equityGlAccountClass);
-GenericValue currentAssetGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "CURRENT_ASSET"), true);
+GenericValue currentAssetGlAccountClass = from("GlAccountClass").where("glAccountClassId", "CURRENT_ASSET").cache(true).queryOne();
 List currentAssetAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(currentAssetGlAccountClass);
-GenericValue longtermAssetGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "LONGTERM_ASSET"), true);
+GenericValue longtermAssetGlAccountClass = from("GlAccountClass").where("glAccountClassId", "LONGTERM_ASSET").cache(true).queryOne();
 List longtermAssetAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(longtermAssetGlAccountClass);
-GenericValue currentLiabilityGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "CURRENT_LIABILITY"), true);
+GenericValue currentLiabilityGlAccountClass = from("GlAccountClass").where("glAccountClassId", "CURRENT_LIABILITY").cache(true).queryOne();
 List currentLiabilityAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(currentLiabilityGlAccountClass);
-GenericValue accumDepreciationGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "ACCUM_DEPRECIATION"), true);
+GenericValue accumDepreciationGlAccountClass = from("GlAccountClass").where("glAccountClassId", "ACCUM_DEPRECIATION").cache(true).queryOne();
 List accumDepreciationAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(accumDepreciationGlAccountClass);
-GenericValue accumAmortizationGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "ACCUM_AMORTIZATION"), true);
+GenericValue accumAmortizationGlAccountClass = from("GlAccountClass").where("glAccountClassId", "ACCUM_AMORTIZATION").cache(true).queryOne();
 List accumAmortizationAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(accumAmortizationGlAccountClass);
 
 // Find the last closed time period to get the fromDate for the transactions in the current period and the ending balances of the last closed period
-Map lastClosedTimePeriodResult = dispatcher.runSync("findLastClosedDate", UtilMisc.toMap("organizationPartyId", organizationPartyId, "findDate", new Date(thruDate.getTime()),"userLogin", userLogin));
+Map lastClosedTimePeriodResult = runService('findLastClosedDate', ["organizationPartyId": organizationPartyId, "findDate": new Date(thruDate.getTime()),"userLogin": userLogin]);
 Timestamp fromDate = (Timestamp)lastClosedTimePeriodResult.lastClosedDate;
 if (!fromDate) {
     return;
@@ -85,7 +85,7 @@
     timePeriodAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, assetAccountClassIds));
     timePeriodAndExprs.add(EntityCondition.makeCondition("endingBalance", EntityOperator.NOT_EQUAL, BigDecimal.ZERO));
     timePeriodAndExprs.add(EntityCondition.makeCondition("customTimePeriodId", EntityOperator.EQUALS, lastClosedTimePeriod.customTimePeriodId));
-    List lastTimePeriodHistories = delegator.findList("GlAccountAndHistory", EntityCondition.makeCondition(timePeriodAndExprs, EntityOperator.AND), null, null, null, false);
+    List lastTimePeriodHistories = from("GlAccountAndHistory").where(timePeriodAndExprs).queryList();
     lastTimePeriodHistories.each { lastTimePeriodHistory ->
         Map accountMap = UtilMisc.toMap("glAccountId", lastTimePeriodHistory.glAccountId, "accountCode", lastTimePeriodHistory.accountCode, "accountName", lastTimePeriodHistory.accountName, "balance", lastTimePeriodHistory.getBigDecimal("endingBalance"), "D", lastTimePeriodHistory.getBigDecimal("postedDebits"), "C", lastTimePeriodHistory.getBigDecimal("postedCredits"));
         assetOpeningBalances.put(lastTimePeriodHistory.glAccountId, accountMap);
@@ -95,7 +95,7 @@
     timePeriodAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, contraAssetAccountClassIds));
     timePeriodAndExprs.add(EntityCondition.makeCondition("endingBalance", EntityOperator.NOT_EQUAL, BigDecimal.ZERO));
     timePeriodAndExprs.add(EntityCondition.makeCondition("customTimePeriodId", EntityOperator.EQUALS, lastClosedTimePeriod.customTimePeriodId));
-    lastTimePeriodHistories = delegator.findList("GlAccountAndHistory", EntityCondition.makeCondition(timePeriodAndExprs, EntityOperator.AND), null, null, null, false);
+    lastTimePeriodHistories = from("GlAccountAndHistory").where(timePeriodAndExprs).queryList();
     lastTimePeriodHistories.each { lastTimePeriodHistory ->
         Map accountMap = UtilMisc.toMap("glAccountId", lastTimePeriodHistory.glAccountId, "accountCode", lastTimePeriodHistory.accountCode, "accountName", lastTimePeriodHistory.accountName, "balance", lastTimePeriodHistory.getBigDecimal("endingBalance"), "D", lastTimePeriodHistory.getBigDecimal("postedDebits"), "C", lastTimePeriodHistory.getBigDecimal("postedCredits"));
         contraAssetOpeningBalances.put(lastTimePeriodHistory.glAccountId, accountMap);
@@ -105,7 +105,7 @@
     timePeriodAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, liabilityAccountClassIds));
     timePeriodAndExprs.add(EntityCondition.makeCondition("endingBalance", EntityOperator.NOT_EQUAL, BigDecimal.ZERO));
     timePeriodAndExprs.add(EntityCondition.makeCondition("customTimePeriodId", EntityOperator.EQUALS, lastClosedTimePeriod.customTimePeriodId));
-    lastTimePeriodHistories = delegator.findList("GlAccountAndHistory", EntityCondition.makeCondition(timePeriodAndExprs, EntityOperator.AND), null, null, null, false);
+    lastTimePeriodHistories = from("GlAccountAndHistory").where(timePeriodAndExprs).queryList();
     lastTimePeriodHistories.each { lastTimePeriodHistory ->
         Map accountMap = UtilMisc.toMap("glAccountId", lastTimePeriodHistory.glAccountId, "accountCode", lastTimePeriodHistory.accountCode, "accountName", lastTimePeriodHistory.accountName, "balance", lastTimePeriodHistory.getBigDecimal("endingBalance"), "D", lastTimePeriodHistory.getBigDecimal("postedDebits"), "C", lastTimePeriodHistory.getBigDecimal("postedCredits"));
         liabilityOpeningBalances.put(lastTimePeriodHistory.glAccountId, accountMap);
@@ -115,7 +115,7 @@
     timePeriodAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, equityAccountClassIds));
     timePeriodAndExprs.add(EntityCondition.makeCondition("endingBalance", EntityOperator.NOT_EQUAL, BigDecimal.ZERO));
     timePeriodAndExprs.add(EntityCondition.makeCondition("customTimePeriodId", EntityOperator.EQUALS, lastClosedTimePeriod.customTimePeriodId));
-    lastTimePeriodHistories = delegator.findList("GlAccountAndHistory", EntityCondition.makeCondition(timePeriodAndExprs, EntityOperator.AND), null, null, null, false);
+    lastTimePeriodHistories = from("GlAccountAndHistory").where(timePeriodAndExprs).queryList();
     lastTimePeriodHistories.each { lastTimePeriodHistory ->
         Map accountMap = UtilMisc.toMap("glAccountId", lastTimePeriodHistory.glAccountId, "accountCode", lastTimePeriodHistory.accountCode, "accountName", lastTimePeriodHistory.accountName, "balance", lastTimePeriodHistory.getBigDecimal("endingBalance"), "D", lastTimePeriodHistory.getBigDecimal("postedDebits"), "C", lastTimePeriodHistory.getBigDecimal("postedCredits"));
         equityOpeningBalances.put(lastTimePeriodHistory.glAccountId, accountMap);
@@ -125,7 +125,7 @@
     timePeriodAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, currentAssetAccountClassIds));
     timePeriodAndExprs.add(EntityCondition.makeCondition("endingBalance", EntityOperator.NOT_EQUAL, BigDecimal.ZERO));
     timePeriodAndExprs.add(EntityCondition.makeCondition("customTimePeriodId", EntityOperator.EQUALS, lastClosedTimePeriod.customTimePeriodId));
-    lastTimePeriodHistories = delegator.findList("GlAccountAndHistory", EntityCondition.makeCondition(timePeriodAndExprs, EntityOperator.AND), null, null, null, false);
+    lastTimePeriodHistories = from("GlAccountAndHistory").where(timePeriodAndExprs).queryList();
     lastTimePeriodHistories.each { lastTimePeriodHistory ->
         Map accountMap = UtilMisc.toMap("glAccountId", lastTimePeriodHistory.glAccountId, "accountCode", lastTimePeriodHistory.accountCode, "accountName", lastTimePeriodHistory.accountName, "balance", lastTimePeriodHistory.getBigDecimal("endingBalance"), "D", lastTimePeriodHistory.getBigDecimal("postedDebits"), "C", lastTimePeriodHistory.getBigDecimal("postedCredits"));
         currentAssetOpeningBalances.put(lastTimePeriodHistory.glAccountId, accountMap);
@@ -135,7 +135,7 @@
     timePeriodAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, longtermAssetAccountClassIds));
     timePeriodAndExprs.add(EntityCondition.makeCondition("endingBalance", EntityOperator.NOT_EQUAL, BigDecimal.ZERO));
     timePeriodAndExprs.add(EntityCondition.makeCondition("customTimePeriodId", EntityOperator.EQUALS, lastClosedTimePeriod.customTimePeriodId));
-    lastTimePeriodHistories = delegator.findList("GlAccountAndHistory", EntityCondition.makeCondition(timePeriodAndExprs, EntityOperator.AND), null, null, null, false);
+    lastTimePeriodHistories = from("GlAccountAndHistory").where(timePeriodAndExprs).queryList();
     lastTimePeriodHistories.each { lastTimePeriodHistory ->
         Map accountMap = UtilMisc.toMap("glAccountId", lastTimePeriodHistory.glAccountId, "accountCode", lastTimePeriodHistory.accountCode, "accountName", lastTimePeriodHistory.accountName, "balance", lastTimePeriodHistory.getBigDecimal("endingBalance"), "D", lastTimePeriodHistory.getBigDecimal("postedDebits"), "C", lastTimePeriodHistory.getBigDecimal("postedCredits"));
         longtermAssetOpeningBalances.put(lastTimePeriodHistory.glAccountId, accountMap);
@@ -145,7 +145,7 @@
     timePeriodAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, currentLiabilityAccountClassIds));
     timePeriodAndExprs.add(EntityCondition.makeCondition("endingBalance", EntityOperator.NOT_EQUAL, BigDecimal.ZERO));
     timePeriodAndExprs.add(EntityCondition.makeCondition("customTimePeriodId", EntityOperator.EQUALS, lastClosedTimePeriod.customTimePeriodId));
-    lastTimePeriodHistories = delegator.findList("GlAccountAndHistory", EntityCondition.makeCondition(timePeriodAndExprs, EntityOperator.AND), null, null, null, false);
+    lastTimePeriodHistories = from("GlAccountAndHistory").where(timePeriodAndExprs).queryList();
     lastTimePeriodHistories.each { lastTimePeriodHistory ->
         Map accountMap = UtilMisc.toMap("glAccountId", lastTimePeriodHistory.glAccountId, "accountCode", lastTimePeriodHistory.accountCode, "accountName", lastTimePeriodHistory.accountName, "balance", lastTimePeriodHistory.getBigDecimal("endingBalance"), "D", lastTimePeriodHistory.getBigDecimal("postedDebits"), "C", lastTimePeriodHistory.getBigDecimal("postedCredits"));
         currentLiabilityOpeningBalances.put(lastTimePeriodHistory.glAccountId, accountMap);
@@ -169,8 +169,7 @@
 balanceTotal = BigDecimal.ZERO;
 List assetAndExprs = FastList.newInstance(mainAndExprs);
 assetAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, assetAccountClassIds));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(assetAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
-
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(assetAndExprs).orderBy("glAccountId").queryList();
 transactionTotalsMap = [:];
 transactionTotalsMap.putAll(assetOpeningBalances);
 transactionTotals.each { transactionTotal ->
@@ -206,7 +205,7 @@
 balanceTotal = BigDecimal.ZERO;
 List currentAssetAndExprs = FastList.newInstance(mainAndExprs);
 currentAssetAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, currentAssetAccountClassIds));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(currentAssetAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(currentAssetAndExprs).orderBy("glAccountId").queryList();
 transactionTotalsMap = [:];
 transactionTotalsMap.putAll(currentAssetOpeningBalances);
 transactionTotals.each { transactionTotal ->
@@ -241,7 +240,7 @@
 balanceTotal = BigDecimal.ZERO;
 List longtermAssetAndExprs = FastList.newInstance(mainAndExprs);
 longtermAssetAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, longtermAssetAccountClassIds));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(longtermAssetAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").orderBy("glAccountId").queryList();
 transactionTotalsMap = [:];
 transactionTotalsMap.putAll(longtermAssetOpeningBalances);
 transactionTotals.each { transactionTotal ->
@@ -276,7 +275,7 @@
 balanceTotal = BigDecimal.ZERO;
 List contraAssetAndExprs = FastList.newInstance(mainAndExprs);
 contraAssetAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, contraAssetAccountClassIds));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(contraAssetAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(contraAssetAndExprs).orderBy("glAccountId").queryList();
 
 transactionTotalsMap = [:];
 transactionTotalsMap.putAll(contraAssetOpeningBalances);
@@ -317,7 +316,7 @@
 balanceTotal = BigDecimal.ZERO;
 List liabilityAndExprs = FastList.newInstance(mainAndExprs);
 liabilityAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, liabilityAccountClassIds));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(liabilityAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(liabilityAndExprs).orderBy("glAccountId").queryList();
 transactionTotalsMap = [:];
 transactionTotalsMap.putAll(liabilityOpeningBalances);
 transactionTotals.each { transactionTotal ->
@@ -353,7 +352,7 @@
 balanceTotal = BigDecimal.ZERO;
 List currentLiabilityAndExprs = FastList.newInstance(mainAndExprs);
 currentLiabilityAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, currentLiabilityAccountClassIds));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(currentLiabilityAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(currentLiabilityAndExprs).orderBy("glAccountId").queryList();
 transactionTotalsMap = [:];
 transactionTotalsMap.putAll(currentLiabilityOpeningBalances);
 transactionTotals.each { transactionTotal ->
@@ -388,7 +387,7 @@
 balanceTotal = BigDecimal.ZERO;
 List equityAndExprs = FastList.newInstance(mainAndExprs);
 equityAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, equityAccountClassIds));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(equityAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(equityAndExprs).orderBy("glAccountId").queryList();
 transactionTotalsMap = [:];
 transactionTotalsMap.putAll(equityOpeningBalances);
 transactionTotals.each { transactionTotal ->
@@ -410,9 +409,9 @@
     transactionTotalsMap.put(transactionTotal.glAccountId, accountMap);
 }
 // Add the "retained earnings" account
-Map netIncomeResult = dispatcher.runSync("prepareIncomeStatement", UtilMisc.toMap("organizationPartyId", organizationPartyId, "glFiscalTypeId", glFiscalTypeId, "fromDate", fromDate, "thruDate", thruDate,"userLogin", userLogin));
+Map netIncomeResult = runService('prepareIncomeStatement', ["organizationPartyId": organizationPartyId, "glFiscalTypeId": glFiscalTypeId, "fromDate": fromDate, "thruDate": thruDate, "userLogin": userLogin]);
 BigDecimal netIncome = (BigDecimal)netIncomeResult.totalNetIncome;
-GenericValue retainedEarningsAccount = delegator.findOne("GlAccountTypeDefault", UtilMisc.toMap("glAccountTypeId", "RETAINED_EARNINGS", "organizationPartyId", organizationPartyId), true);
+GenericValue retainedEarningsAccount = from("GlAccountTypeDefault").where("glAccountTypeId", "RETAINED_EARNINGS", "organizationPartyId", organizationPartyId).cache(true).queryOne();
 if (retainedEarningsAccount) {
     GenericValue retainedEarningsGlAccount = retainedEarningsAccount.getRelatedOne("GlAccount", false);
     transactionTotalsMap.put(retainedEarningsGlAccount.glAccountId, UtilMisc.toMap("glAccountId", retainedEarningsGlAccount.glAccountId,"accountName", retainedEarningsGlAccount.accountName, "accountCode", retainedEarningsGlAccount.accountCode, "balance", netIncome));
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/CashFlowStatement.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/CashFlowStatement.groovy
index ba0c0c9..7f3e171 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/CashFlowStatement.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/CashFlowStatement.groovy
@@ -50,13 +50,13 @@
 partyIds.add(organizationPartyId);
 
 // Get the group of account classes that will be used to position accounts in the proper section of the  Cash Flow statement
-GenericValue glAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "CASH_EQUIVALENT"), true);
+GenericValue glAccountClass = from("GlAccountClass").where("glAccountClassId", "CASH_EQUIVALENT").cache(true).queryOne();
 List glAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(glAccountClass);
 
 List cashFlowBalanceTotalList = [];
 
 // Find the last closed time period to get the fromDate for the transactions in the current period and the ending balances of the last closed period 
-Map lastClosedTimePeriodResult = dispatcher.runSync("findLastClosedDate", ["organizationPartyId":organizationPartyId, "findDate":new Date(parametersFromDate.getTime()),"userLogin":userLogin]);
+Map lastClosedTimePeriodResult = runService('findLastClosedDate', ["organizationPartyId":organizationPartyId, "findDate":new Date(parametersFromDate.getTime()),"userLogin":userLogin]);
 Timestamp periodClosingFromDate = (Timestamp)lastClosedTimePeriodResult.lastClosedDate;
 if (!periodClosingFromDate) {
     return;
@@ -70,7 +70,7 @@
     timePeriodAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, glAccountClassIds));
     timePeriodAndExprs.add(EntityCondition.makeCondition("endingBalance", EntityOperator.NOT_EQUAL, BigDecimal.ZERO));
     timePeriodAndExprs.add(EntityCondition.makeCondition("customTimePeriodId", EntityOperator.EQUALS, lastClosedTimePeriod.customTimePeriodId));
-    List lastTimePeriodHistories = delegator.findList("GlAccountAndHistory", EntityCondition.makeCondition(timePeriodAndExprs, EntityOperator.AND), null, null, null, false);
+    List lastTimePeriodHistories = from("GlAccountAndHistory").where(timePeriodAndExprs).queryList();
     lastTimePeriodHistories.each { lastTimePeriodHistory ->
         Map accountMap = ["glAccountId":lastTimePeriodHistory.glAccountId, "accountCode":lastTimePeriodHistory.accountCode, "accountName":lastTimePeriodHistory.accountName, "balance":lastTimePeriodHistory.getBigDecimal("endingBalance"), "D":lastTimePeriodHistory.getBigDecimal("postedDebits"), "C":lastTimePeriodHistory.getBigDecimal("postedCredits")];
         openingCashBalances.(lastTimePeriodHistory.glAccountId) = accountMap;
@@ -90,7 +90,7 @@
 List openingCashBalanceAndExprs = FastList.newInstance(mainAndExprs);
 openingCashBalanceAndExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, periodClosingFromDate));
 openingCashBalanceAndExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN, parametersFromDate));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(openingCashBalanceAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(openingCashBalanceAndExprs).orderBy("glAccountId").queryList();
 transactionTotalsMap = [:];
 transactionTotalsMap.putAll(openingCashBalances);
 transactionTotals.each { transactionTotal ->
@@ -135,7 +135,7 @@
 List periodCashBalanceAndExprs = FastList.newInstance(mainAndExprs);
 periodCashBalanceAndExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, parametersFromDate));
 periodCashBalanceAndExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN, thruDate));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(periodCashBalanceAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(periodCashBalanceAndExprs).orderBy("glAccountId").queryList();
 if (transactionTotals) {
     Map transactionTotalsMap = [:];
     balanceTotalCredit = BigDecimal.ZERO;
@@ -214,7 +214,7 @@
 if (closingTransactionKeySet) {
     closingTransactionKeySet.removeAll(openingTransactionKeySet);
     closingTransactionKeySet.each { closingTransactionKey ->
-        glAccount = delegator.findOne("GlAccount", UtilMisc.toMap("glAccountId", closingTransactionKey), true);
+        glAccount = from("GlAccount").where("glAccountId", closingTransactionKey).cache(true).queryOne();
         context.openingCashBalanceList.add(["glAccountId":glAccount.glAccountId, "accountName":glAccount.accountName, accountCode:glAccount.accountCode, balance:BigDecimal.ZERO, D:BigDecimal.ZERO, C:BigDecimal.ZERO]);
     }
 }
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/CostCenters.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/CostCenters.groovy
index b0c86bb..c74e567 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/CostCenters.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/CostCenters.groovy
@@ -48,9 +48,9 @@
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, fromDate));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN_EQUAL_TO, thruDate));
 andCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-List postedTransactionTotals = delegator.findList("AcctgTransEntrySums", andCond, UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+List postedTransactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(andCond).orderBy("glAccountId").queryList();
 if (postedTransactionTotals) {
-    glAccountCategories = delegator.findByAnd("GlAccountCategory", [glAccountCategoryTypeId : 'COST_CENTER'], ['glAccountCategoryId'], false);
+    glAccountCategories = from("GlAccountCategory").where("glAccountCategoryTypeId", "COST_CENTER").orderBy("glAccountCategoryId").queryList();
     context.glAccountCategories = glAccountCategories;
     Map postedTransactionTotalsMap = [:]
     postedTransactionTotals.each { postedTransactionTotal ->
@@ -67,7 +67,7 @@
         BigDecimal balance = debitAmount.subtract(creditAmount);
         accountMap.put("balance", balance);
         glAccountCategories.each { glAccountCategory ->
-            glAccountCategoryMember = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("GlAccountCategoryMember", [glAccountCategoryId : glAccountCategory.glAccountCategoryId, glAccountId: postedTransactionTotal.glAccountId], ['glAccountCategoryId'], false)));
+            glAccountCategoryMember = from("GlAccountCategoryMember").where("glAccountCategoryId", glAccountCategory.glAccountCategoryId, "glAccountId", postedTransactionTotal.glAccountId).orderBy("glAccountCategoryId").filterByDate().queryFirst();
             if (glAccountCategoryMember) {
                 BigDecimal glAccountCategorySharePercentage = glAccountCategoryMember.amountPercentage;
                 if (glAccountCategorySharePercentage && glAccountCategorySharePercentage != BigDecimal.ZERO ) {
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/GlAccountTrialBalance.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/GlAccountTrialBalance.groovy
index 22aabd8..1813853 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/GlAccountTrialBalance.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/GlAccountTrialBalance.groovy
@@ -26,16 +26,16 @@
 if (organizationPartyId) {
     onlyIncludePeriodTypeIdList = [];
     onlyIncludePeriodTypeIdList.add("FISCAL_YEAR");
-    customTimePeriodResults = dispatcher.runSync("findCustomTimePeriods", [findDate : UtilDateTime.nowTimestamp(), organizationPartyId : organizationPartyId, onlyIncludePeriodTypeIdList : onlyIncludePeriodTypeIdList, userLogin : userLogin]);
+    customTimePeriodResults = runService('findCustomTimePeriods', [findDate : UtilDateTime.nowTimestamp(), organizationPartyId : organizationPartyId, onlyIncludePeriodTypeIdList : onlyIncludePeriodTypeIdList, userLogin : userLogin]);
     customTimePeriodList = customTimePeriodResults.customTimePeriodList;
     if (UtilValidate.isNotEmpty(customTimePeriodList)) {
         context.timePeriod = customTimePeriodList.first().customTimePeriodId;
     }
     decimals = UtilNumber.getBigDecimalScale("ledger.decimals");
     rounding = UtilNumber.getBigDecimalRoundingMode("ledger.rounding");
-    context.currentOrganization = delegator.findOne("PartyNameView", [partyId : organizationPartyId], false);
+    context.currentOrganization = from("PartyNameView").where("partyId", organizationPartyId).queryOne();
     if (parameters.glAccountId) {
-        glAccount = delegator.findOne("GlAccount", [glAccountId : parameters.glAccountId], false);
+        glAccount = from("GlAccount").where("glAccountId", parameters.glAccountId).queryOne();
         isDebitAccount = UtilAccounting.isDebitAccount(glAccount);
         context.isDebitAccount = isDebitAccount;
         context.glAccount = glAccount;
@@ -45,13 +45,11 @@
     BigDecimal balanceOfTheAcctgForYear = BigDecimal.ZERO;
 
     if (parameters.timePeriod) {
-        currentTimePeriod = delegator.findOne("CustomTimePeriod", [customTimePeriodId : parameters.timePeriod], false);
-        previousTimePeriodResult = dispatcher.runSync("getPreviousTimePeriod", 
-                [customTimePeriodId : parameters.timePeriod, userLogin : userLogin]);
+        currentTimePeriod = from("CustomTimePeriod").where("customTimePeriodId", parameters.timePeriod).queryOne();
+        previousTimePeriodResult = runService('getPreviousTimePeriod', [customTimePeriodId : parameters.timePeriod, userLogin : userLogin]);
         previousTimePeriod = previousTimePeriodResult.previousTimePeriod;
         if (UtilValidate.isNotEmpty(previousTimePeriod)) {
-            glAccountHistory = delegator.findOne("GlAccountHistory", 
-                    [customTimePeriodId : previousTimePeriod.customTimePeriodId, glAccountId : parameters.glAccountId, organizationPartyId : organizationPartyId], false);
+            glAccountHistory = from("GlAccountHistory").where("customTimePeriodId", previousTimePeriod.customTimePeriodId, "glAccountId", parameters.glAccountId, "organizationPartyId", organizationPartyId).queryOne();
             if (glAccountHistory && glAccountHistory.endingBalance != null) {
                 context.openingBalance = glAccountHistory.endingBalance;
                 balanceOfTheAcctgForYear = glAccountHistory.endingBalance;
@@ -76,7 +74,7 @@
             if ("ALL".equals(isPosted)) {
                 isPosted = "";
             }
-            acctgTransEntriesAndTransTotal = dispatcher.runSync("getAcctgTransEntriesAndTransTotal", 
+            acctgTransEntriesAndTransTotal = runService('getAcctgTransEntriesAndTransTotal', 
                     [customTimePeriodStartDate : customTimePeriodStartDate, customTimePeriodEndDate : customTimePeriodEndDate, organizationPartyId : organizationPartyId, glAccountId : parameters.glAccountId, isPosted : isPosted, userLogin : userLogin]);
             totalOfYearToDateDebit = totalOfYearToDateDebit + acctgTransEntriesAndTransTotal.debitTotal;
             acctgTransEntriesAndTransTotal.totalOfYearToDateDebit = totalOfYearToDateDebit.setScale(decimals, rounding);
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/IncomeStatement.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/IncomeStatement.groovy
index 79ed28c..0e0ac0d 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/IncomeStatement.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/IncomeStatement.groovy
@@ -42,19 +42,19 @@
 partyIds.add(organizationPartyId);
 
 // Get the group of account classes that will be used to position accounts in the proper section of the financial statement
-GenericValue revenueGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "REVENUE"), true);
+GenericValue revenueGlAccountClass = from("GlAccountClass").where("glAccountClassId", "REVENUE").cache(true).queryOne();
 List revenueAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(revenueGlAccountClass);
-GenericValue contraRevenueGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "CONTRA_REVENUE"), true);
+GenericValue contraRevenueGlAccountClass = from("GlAccountClass").where("glAccountClassId", "CONTRA_REVENUE").cache(true).queryOne();
 List contraRevenueAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(contraRevenueGlAccountClass);
-GenericValue incomeGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "INCOME"), true);
+GenericValue incomeGlAccountClass = from("GlAccountClass").where("glAccountClassId", "INCOME").cache(true).queryOne();
 List incomeAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(incomeGlAccountClass);
-GenericValue expenseGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "EXPENSE"), true);
+GenericValue expenseGlAccountClass = from("GlAccountClass").where("glAccountClassId", "EXPENSE").cache(true).queryOne();
 List expenseAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(expenseGlAccountClass);
-GenericValue cogsExpenseGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "COGS_EXPENSE"), true);
+GenericValue cogsExpenseGlAccountClass = from("GlAccountClass").where("glAccountClassId", "COGS_EXPENSE").cache(true).queryOne();
 List cogsExpenseAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(cogsExpenseGlAccountClass);
-GenericValue sgaExpenseGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "SGA_EXPENSE"), true);
+GenericValue sgaExpenseGlAccountClass = from("GlAccountClass").where("glAccountClassId", "SGA_EXPENSE").cache(true).queryList();
 List sgaExpenseAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(sgaExpenseGlAccountClass);
-GenericValue depreciationGlAccountClass = delegator.findOne("GlAccountClass", UtilMisc.toMap("glAccountClassId", "DEPRECIATION"), true);
+GenericValue depreciationGlAccountClass = from("GlAccountClass").where("glAccountClassId", "DEPRECIATION").cache(true).queryOne();
 List depreciationAccountClassIds = UtilAccounting.getDescendantGlAccountClassIds(depreciationGlAccountClass);
 
 List mainAndExprs = FastList.newInstance();
@@ -74,7 +74,7 @@
 balanceTotal = BigDecimal.ZERO;
 List revenueAndExprs = FastList.newInstance(mainAndExprs);
 revenueAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, revenueAccountClassIds));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(revenueAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(revenueAndExprs).orderBy("glAccountId").queryList();
 if (transactionTotals) {
     Map transactionTotalsMap = [:];
     balanceTotalCredit = BigDecimal.ZERO;
@@ -117,7 +117,7 @@
 balanceTotal = BigDecimal.ZERO;
 List contraRevenueAndExprs = FastList.newInstance(mainAndExprs);
 contraRevenueAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, contraRevenueAccountClassIds));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(contraRevenueAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(contraRevenueAndExprs).orderBy("glAccountId").queryList();
 if (transactionTotals) {
     Map transactionTotalsMap = [:];
     balanceTotalCredit = BigDecimal.ZERO;
@@ -159,7 +159,7 @@
 balanceTotal = BigDecimal.ZERO;
 List expenseAndExprs = FastList.newInstance(mainAndExprs);
 expenseAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, expenseAccountClassIds));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(expenseAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(expenseAndExprs).queryList();
 if (transactionTotals) {
     Map transactionTotalsMap = [:];
     balanceTotalCredit = BigDecimal.ZERO;
@@ -202,7 +202,7 @@
 balanceTotal = BigDecimal.ZERO;
 List cogsExpenseAndExprs = FastList.newInstance(mainAndExprs);
 cogsExpenseAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, cogsExpenseAccountClassIds));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(cogsExpenseAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(cogsExpenseAndExprs).orderBy("glAccountId").queryList();
 if (transactionTotals) {
     Map transactionTotalsMap = [:];
     balanceTotalCredit = BigDecimal.ZERO;
@@ -244,7 +244,7 @@
 balanceTotal = BigDecimal.ZERO;
 List sgaExpenseAndExprs = FastList.newInstance(mainAndExprs);
 sgaExpenseAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, sgaExpenseAccountClassIds));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(sgaExpenseAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(sgaExpenseAndExprs).orderBy("glAccountId").queryList();
 if (transactionTotals) {
     Map transactionTotalsMap = [:];
     balanceTotalCredit = BigDecimal.ZERO;
@@ -285,7 +285,7 @@
 balanceTotal = BigDecimal.ZERO;
 List depreciationAndExprs = FastList.newInstance(mainAndExprs);
 depreciationAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, depreciationAccountClassIds));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(depreciationAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(depreciationAndExprs).orderBy("glAccountId").queryList();
 if (transactionTotals) {
 Map transactionTotalsMap = [:];
 balanceTotalCredit = BigDecimal.ZERO;
@@ -326,7 +326,7 @@
 balanceTotal = BigDecimal.ZERO;
 List incomeAndExprs = FastList.newInstance(mainAndExprs);
 incomeAndExprs.add(EntityCondition.makeCondition("glAccountClassId", EntityOperator.IN, incomeAccountClassIds));
-transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(incomeAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(incomeAndExprs).orderBy("glAccountId").queryList();
 if (transactionTotals) {
     Map transactionTotalsMap = [:];
     balanceTotalCredit = BigDecimal.ZERO;
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/SalesInvoiceByProductCategorySummary.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/SalesInvoiceByProductCategorySummary.groovy
index 089f2a2..02d8da8 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/SalesInvoiceByProductCategorySummary.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/SalesInvoiceByProductCategorySummary.groovy
@@ -31,8 +31,8 @@
 //TODO:
 
 // get products and categories under the root category
-productMemberList = delegator.findByAnd("ProductCategoryMember", [productCategoryId : rootProductCategoryId], ["sequenceNum"], false);
-categoryRollupList = delegator.findByAnd("ProductCategoryRollup", [parentProductCategoryId : rootProductCategoryId], ["sequenceNum"], false);
+productMemberList = from("ProductCategoryMember").where("productCategoryId", rootProductCategoryId).orderBy("sequenceNum").queryList();
+categoryRollupList = from("ProductCategoryRollup").where("parentProductCategoryId", rootProductCategoryId).orderBy("sequenceNum").queryList();
 
 // for use in the queries
 productIdSet = FastSet.newInstance();
@@ -55,8 +55,6 @@
     productCategoryIdSet.add(categoryRollup.productCategoryId);
 }
 
-productFieldsToSelect = UtilMisc.toSet("productId", "quantityTotal", "amountTotal");
-
 //NOTE: tax, etc also have productId on them, so restrict by type INV_PROD_ITEM, INV_FPROD_ITEM, INV_DPROD_ITEM, others?
 baseProductAndExprs = FastList.newInstance();
 baseProductAndExprs.add(EntityCondition.makeCondition("invoiceTypeId", EntityOperator.EQUALS, "SALES_INVOICE"));
@@ -65,8 +63,6 @@
 if (organizationPartyId) baseProductAndExprs.add(EntityCondition.makeCondition("partyIdFrom", EntityOperator.EQUALS, organizationPartyId));
 if (currencyUomId) baseProductAndExprs.add(EntityCondition.makeCondition("currencyUomId", EntityOperator.EQUALS, currencyUomId));
 
-categoryFieldsToSelect = UtilMisc.toSet("productCategoryId", "quantityTotal", "amountTotal");
-
 baseCategoryAndExprs = FastList.newInstance();
 baseCategoryAndExprs.add(EntityCondition.makeCondition("invoiceTypeId", EntityOperator.EQUALS, "SALES_INVOICE"));
 baseCategoryAndExprs.add(EntityCondition.makeCondition("invoiceItemTypeId", EntityOperator.IN, ["INV_PROD_ITEM", "INV_FPROD_ITEM", "INV_DPROD_ITEM"]));
@@ -104,8 +100,6 @@
     currentDayCal.add(Calendar.DAY_OF_MONTH, 1);
     nextDayBegin = new java.sql.Timestamp(currentDayCal.getTimeInMillis());
 
-    findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
-
     // do the product find
     productAndExprs = FastList.newInstance();
     productAndExprs.addAll(baseProductAndExprs);
@@ -113,7 +107,7 @@
     productAndExprs.add(EntityCondition.makeCondition("invoiceDate", EntityOperator.GREATER_THAN_EQUAL_TO, currentDayBegin));
     productAndExprs.add(EntityCondition.makeCondition("invoiceDate", EntityOperator.LESS_THAN, nextDayBegin));
 
-    productResultListIterator = delegator.find("InvoiceItemProductSummary", EntityCondition.makeCondition(productAndExprs, EntityOperator.AND), null, productFieldsToSelect, null, findOpts);
+    productResultListIterator = select("productId", "quantityTotal", "amountTotal").from("InvoiceItemProductSummary").where(productAndExprs).cursorScrollInsensitive().cache(true).queryIterator();
     productResultMap = FastMap.newInstance();
     while ((productResult = productResultListIterator.next())) {
         productResultMap[productResult.productId] = productResult;
@@ -130,7 +124,7 @@
     categoryAndExprs.add(EntityCondition.makeCondition("invoiceDate", EntityOperator.GREATER_THAN_EQUAL_TO, currentDayBegin));
     categoryAndExprs.add(EntityCondition.makeCondition("invoiceDate", EntityOperator.LESS_THAN, nextDayBegin));
 
-    categoryResultListIterator = delegator.find("InvoiceItemCategorySummary", EntityCondition.makeCondition(categoryAndExprs, EntityOperator.AND), null, categoryFieldsToSelect, null, findOpts);
+    categoryResultListIterator = select("productCategoryId", "quantityTotal", "amountTotal").from(InvoiceItemCategorySummary).where(categoryAndExprs).cursorScrollInsensitive().cache(true).queryIterator();
     categoryResultMap = FastMap.newInstance();
     while ((categoryResult = categoryResultListIterator.next())) {
         categoryResultMap[categoryResult.productCategoryId] = categoryResult;
@@ -147,7 +141,7 @@
     productNullAndExprs.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, null));
     productNullAndExprs.add(EntityCondition.makeCondition("invoiceDate", EntityOperator.GREATER_THAN_EQUAL_TO, currentDayBegin));
     productNullAndExprs.add(EntityCondition.makeCondition("invoiceDate", EntityOperator.LESS_THAN, nextDayBegin));
-    productNullResultListIterator = delegator.find("InvoiceItemProductSummary", EntityCondition.makeCondition(productNullAndExprs, EntityOperator.AND), null, productFieldsToSelect, null, findOpts);
+    productNullResultListIterator = select("productId", "quantityTotal", "amountTotal").from("InvoiceItemProductSummary").where(productNullAndExprs).cursorScrollInsensitive().cache(true).queryIterator();
     // should just be 1 result
     productNullResult = productNullResultListIterator.next();
     productNullResultListIterator.close();
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/TransactionTotals.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/TransactionTotals.groovy
index 03f7d19..170d213 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/TransactionTotals.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/TransactionTotals.groovy
@@ -43,7 +43,7 @@
 }
 
 // Find the last closed time period to get the fromDate for the transactions in the current period and the ending balances of the last closed period
-Map lastClosedTimePeriodResult = dispatcher.runSync("findLastClosedDate", UtilMisc.toMap("organizationPartyId", organizationPartyId, "findDate", new Date(fromDate.getTime()),"userLogin", userLogin));
+Map lastClosedTimePeriodResult = runService('findLastClosedDate', ["organizationPartyId": organizationPartyId, "findDate": new Date(fromDate.getTime()),"userLogin": userLogin]);
 Timestamp lastClosedDate = (Timestamp)lastClosedTimePeriodResult.lastClosedDate;
 GenericValue lastClosedTimePeriod = null; 
 if (lastClosedDate) {
@@ -61,24 +61,19 @@
 andExprs.add(EntityCondition.makeCondition("glFiscalTypeId", EntityOperator.EQUALS, glFiscalTypeId));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, fromDate));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN_EQUAL_TO, thruDate));
-andCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-List postedTransactionTotals = delegator.findList("AcctgTransEntrySums", andCond, UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+List postedTransactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(andExprs).orderBy("glAccountId").queryList();
 if (postedTransactionTotals) {
     Map postedTransactionTotalsMap = [:]
     postedTransactionTotals.each { postedTransactionTotal ->
         Map accountMap = (Map)postedTransactionTotalsMap.get(postedTransactionTotal.glAccountId);
         if (!accountMap) {
-            GenericValue glAccount = delegator.findOne("GlAccount", UtilMisc.toMap("glAccountId", postedTransactionTotal.glAccountId), true);
+            GenericValue glAccount = from("GlAccount").where("glAccountId", postedTransactionTotal.glAccountId).cache(true).queryOne();
             if (glAccount) {
                 boolean isDebitAccount = UtilAccounting.isDebitAccount(glAccount);
                 // Get the opening balances at the end of the last closed time period
                 if (UtilAccounting.isAssetAccount(glAccount) || UtilAccounting.isLiabilityAccount(glAccount) || UtilAccounting.isEquityAccount(glAccount)) {
                     if (lastClosedTimePeriod) {
-                        List timePeriodAndExprs = FastList.newInstance();
-                        timePeriodAndExprs.add(EntityCondition.makeCondition("organizationPartyId", EntityOperator.EQUALS, organizationPartyId));
-                        timePeriodAndExprs.add(EntityCondition.makeCondition("glAccountId", EntityOperator.EQUALS, postedTransactionTotal.glAccountId));
-                        timePeriodAndExprs.add(EntityCondition.makeCondition("customTimePeriodId", EntityOperator.EQUALS, lastClosedTimePeriod.customTimePeriodId));
-                        lastTimePeriodHistory = EntityUtil.getFirst(delegator.findList("GlAccountAndHistory", EntityCondition.makeCondition(timePeriodAndExprs, EntityOperator.AND), null, null, null, false));
+                        lastTimePeriodHistory = from("GlAccountAndHistory").where("organizationPartyId", organizationPartyId, "glAccountId", postedTransactionTotal.glAccountId, "customTimePeriodId", lastClosedTimePeriod.customTimePeriodId).queryFirst();
                         if (lastTimePeriodHistory) {
                             accountMap = UtilMisc.toMap("glAccountId", lastTimePeriodHistory.glAccountId, "accountCode", lastTimePeriodHistory.accountCode, "accountName", lastTimePeriodHistory.accountName, "balance", lastTimePeriodHistory.getBigDecimal("endingBalance"), "openingD", lastTimePeriodHistory.getBigDecimal("postedDebits"), "openingC", lastTimePeriodHistory.getBigDecimal("postedCredits"), "D", BigDecimal.ZERO, "C", BigDecimal.ZERO);
                         }
@@ -102,7 +97,7 @@
             mainAndExprs.add(EntityCondition.makeCondition("acctgTransTypeId", EntityOperator.NOT_EQUAL, "PERIOD_CLOSING"));
             mainAndExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, lastClosedDate));
             mainAndExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN, fromDate));
-            transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(mainAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+            transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(mainAndExprs).orderBy("glAccountId").queryList();
             transactionTotals.each { transactionTotal ->
                 UtilMisc.addToBigDecimalInMap(accountMap, "opening" + transactionTotal.debitCreditFlag, transactionTotal.amount);
             }
@@ -120,8 +115,7 @@
 andExprs.add(EntityCondition.makeCondition("debitCreditFlag", EntityOperator.EQUALS, "D"));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, fromDate));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN_EQUAL_TO, thruDate));
-andCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-List postedDebitTransactionTotals = delegator.findList("AcctgTransEntrySums", andCond, UtilMisc.toSet("amount"), null, null, false);
+List postedDebitTransactionTotals = select("amount").from("AcctgTransEntrySums").where(andExprs).queryList();
 if (postedDebitTransactionTotals) {
     postedDebitTransactionTotal = postedDebitTransactionTotals.first();
     if (postedDebitTransactionTotal && postedDebitTransactionTotal.amount) {
@@ -136,8 +130,7 @@
 andExprs.add(EntityCondition.makeCondition("debitCreditFlag", EntityOperator.EQUALS, "C"));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, fromDate));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN_EQUAL_TO, thruDate));
-andCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-List postedCreditTransactionTotals = delegator.findList("AcctgTransEntrySums", andCond, UtilMisc.toSet("amount"), null, null, false);
+List postedCreditTransactionTotals = select("amount").from("AcctgTransEntrySums").where(andExprs).queryList();
 if (postedCreditTransactionTotals) {
     postedCreditTransactionTotal = postedCreditTransactionTotals.first();
     if (postedCreditTransactionTotal && postedCreditTransactionTotal.amount) {
@@ -159,23 +152,19 @@
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, fromDate));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN_EQUAL_TO, thruDate));
 andCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-List unpostedTransactionTotals = delegator.findList("AcctgTransEntrySums", andCond, UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+List unpostedTransactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(andExprs).orderBy("glAccountId").queryList();
 if (unpostedTransactionTotals) {
     Map unpostedTransactionTotalsMap = [:]
     unpostedTransactionTotals.each { unpostedTransactionTotal ->
         Map accountMap = (Map)unpostedTransactionTotalsMap.get(unpostedTransactionTotal.glAccountId);
         if (!accountMap) {
-            GenericValue glAccount = delegator.findOne("GlAccount", UtilMisc.toMap("glAccountId", unpostedTransactionTotal.glAccountId), true);
+            GenericValue glAccount = from("GlAccount").where("glAccountId", unpostedTransactionTotal.glAccountId).cache(true).queryOne();
             if (glAccount) {
                 boolean isDebitAccount = UtilAccounting.isDebitAccount(glAccount);
                 // Get the opening balances at the end of the last closed time period
                 if (UtilAccounting.isAssetAccount(glAccount) || UtilAccounting.isLiabilityAccount(glAccount) || UtilAccounting.isEquityAccount(glAccount)) {
                     if (lastClosedTimePeriod) {
-                        List timePeriodAndExprs = FastList.newInstance();
-                        timePeriodAndExprs.add(EntityCondition.makeCondition("organizationPartyId", EntityOperator.EQUALS, organizationPartyId));
-                        timePeriodAndExprs.add(EntityCondition.makeCondition("glAccountId", EntityOperator.EQUALS, unpostedTransactionTotal.glAccountId));
-                        timePeriodAndExprs.add(EntityCondition.makeCondition("customTimePeriodId", EntityOperator.EQUALS, lastClosedTimePeriod.customTimePeriodId));
-                        lastTimePeriodHistory = EntityUtil.getFirst(delegator.findList("GlAccountAndHistory", EntityCondition.makeCondition(timePeriodAndExprs, EntityOperator.AND), null, null, null, false));
+                        lastTimePeriodHistory = from("GlAccountAndHistory").where("organizationPartyId", organizationPartyId, "glAccountId", unpostedTransactionTotal.glAccountId, "customTimePeriodId", lastClosedTimePeriod.customTimePeriodId).queryFirst();
                         if (lastTimePeriodHistory) {
                             accountMap = UtilMisc.toMap("glAccountId", lastTimePeriodHistory.glAccountId, "accountCode", lastTimePeriodHistory.accountCode, "accountName", lastTimePeriodHistory.accountName, "balance", lastTimePeriodHistory.getBigDecimal("endingBalance"), "openingD", lastTimePeriodHistory.getBigDecimal("postedDebits"), "openingC", lastTimePeriodHistory.getBigDecimal("postedCredits"), "D", BigDecimal.ZERO, "C", BigDecimal.ZERO);
                         }
@@ -199,7 +188,7 @@
             mainAndExprs.add(EntityCondition.makeCondition("acctgTransTypeId", EntityOperator.NOT_EQUAL, "PERIOD_CLOSING"));
             mainAndExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, lastClosedDate));
             mainAndExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN, fromDate));
-            transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(mainAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+            transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(mainAndExprs).orderBy("glAccountId").queryList();
             transactionTotals.each { transactionTotal ->
                 UtilMisc.addToBigDecimalInMap(accountMap, "opening" + transactionTotal.debitCreditFlag, transactionTotal.amount);
             }
@@ -217,8 +206,7 @@
 andExprs.add(EntityCondition.makeCondition("debitCreditFlag", EntityOperator.EQUALS, "D"));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, fromDate));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN_EQUAL_TO, thruDate));
-andCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-List unpostedDebitTransactionTotals = delegator.findList("AcctgTransEntrySums", andCond, UtilMisc.toSet("amount"), null, null, false);
+List unpostedDebitTransactionTotals = select("amount").from("AcctgTransEntrySums").where(andExprs).queryList();
 if (unpostedDebitTransactionTotals) {
     unpostedDebitTransactionTotal = unpostedDebitTransactionTotals.first();
     if (unpostedDebitTransactionTotal && unpostedDebitTransactionTotal.amount) {
@@ -234,7 +222,7 @@
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, fromDate));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN_EQUAL_TO, thruDate));
 andCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-List unpostedCreditTransactionTotals = delegator.findList("AcctgTransEntrySums", andCond, UtilMisc.toSet("amount"), null, null, false);
+List unpostedCreditTransactionTotals = select("amount").from("AcctgTransEntrySums").where(andExprs).queryList();
 if (unpostedCreditTransactionTotals) {
     unpostedCreditTransactionTotal = unpostedCreditTransactionTotals.first();
     if (unpostedCreditTransactionTotal && unpostedCreditTransactionTotal.amount) {
@@ -255,13 +243,13 @@
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, fromDate));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN_EQUAL_TO, thruDate));
 andCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-List allTransactionTotals = delegator.findList("AcctgTransEntrySums", andCond, UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+List allTransactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(andExprs).orderBy("glAccountId").queryList();
 if (allTransactionTotals) {
     Map allTransactionTotalsMap = [:]
     allTransactionTotals.each { allTransactionTotal ->
         Map accountMap = (Map)allTransactionTotalsMap.get(allTransactionTotal.glAccountId);
         if (!accountMap) {
-            GenericValue glAccount = delegator.findOne("GlAccount", UtilMisc.toMap("glAccountId", allTransactionTotal.glAccountId), true);
+            GenericValue glAccount = from("GlAccount").where("glAccountId", allTransactionTotal.glAccountId).cache(true).queryOne();
             if (glAccount) {
                 boolean isDebitAccount = UtilAccounting.isDebitAccount(glAccount);
                 // Get the opening balances at the end of the last closed time period
@@ -271,7 +259,7 @@
                         timePeriodAndExprs.add(EntityCondition.makeCondition("organizationPartyId", EntityOperator.EQUALS, organizationPartyId));
                         timePeriodAndExprs.add(EntityCondition.makeCondition("glAccountId", EntityOperator.EQUALS, allTransactionTotal.glAccountId));
                         timePeriodAndExprs.add(EntityCondition.makeCondition("customTimePeriodId", EntityOperator.EQUALS, lastClosedTimePeriod.customTimePeriodId));
-                        lastTimePeriodHistory = EntityUtil.getFirst(delegator.findList("GlAccountAndHistory", EntityCondition.makeCondition(timePeriodAndExprs, EntityOperator.AND), null, null, null, false));
+                        lastTimePeriodHistory = from("GlAccountAndHistory").where(timePeriodAndExprs).queryFirst();
                         if (lastTimePeriodHistory) {
                             accountMap = UtilMisc.toMap("glAccountId", lastTimePeriodHistory.glAccountId, "accountCode", lastTimePeriodHistory.accountCode, "accountName", lastTimePeriodHistory.accountName, "balance", lastTimePeriodHistory.getBigDecimal("endingBalance"), "openingD", lastTimePeriodHistory.getBigDecimal("postedDebits"), "openingC", lastTimePeriodHistory.getBigDecimal("postedCredits"), "D", BigDecimal.ZERO, "C", BigDecimal.ZERO);
                         }
@@ -295,7 +283,7 @@
             mainAndExprs.add(EntityCondition.makeCondition("acctgTransTypeId", EntityOperator.NOT_EQUAL, "PERIOD_CLOSING"));
             mainAndExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, lastClosedDate));
             mainAndExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN, fromDate));
-            transactionTotals = delegator.findList("AcctgTransEntrySums", EntityCondition.makeCondition(mainAndExprs, EntityOperator.AND), UtilMisc.toSet("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount"), UtilMisc.toList("glAccountId"), null, false);
+            transactionTotals = select("glAccountId", "accountName", "accountCode", "debitCreditFlag", "amount").from("AcctgTransEntrySums").where(mainAndExprs).orderBy("glAccountId").queryList();
             transactionTotals.each { transactionTotal ->
                 UtilMisc.addToBigDecimalInMap(accountMap, "opening" + transactionTotal.debitCreditFlag, transactionTotal.amount);
             }
@@ -312,8 +300,7 @@
 andExprs.add(EntityCondition.makeCondition("debitCreditFlag", EntityOperator.EQUALS, "D"));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, fromDate));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN_EQUAL_TO, thruDate));
-andCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-List allDebitTransactionTotals = delegator.findList("AcctgTransEntrySums", andCond, UtilMisc.toSet("amount"), null, null, false);
+List allDebitTransactionTotals = select("amount").from("AcctgTransEntrySums").where(andExprs).queryList();
 if (allDebitTransactionTotals) {
     allDebitTransactionTotal = allDebitTransactionTotals.first();
     if (allDebitTransactionTotal && allDebitTransactionTotal.amount) {
@@ -328,7 +315,7 @@
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.GREATER_THAN_EQUAL_TO, fromDate));
 andExprs.add(EntityCondition.makeCondition("transactionDate", EntityOperator.LESS_THAN_EQUAL_TO, thruDate));
 andCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-List allCreditTransactionTotals = delegator.findList("AcctgTransEntrySums", andCond, UtilMisc.toSet("amount"), null, null, false);
+List allCreditTransactionTotals = select("amount").from("AcctgTransEntrySums").where(andExprs).queryList();
 if (allCreditTransactionTotals) {
     allCreditTransactionTotal = allCreditTransactionTotals.first();
     if (allCreditTransactionTotal && allCreditTransactionTotal.amount) {
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/TrialBalance.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/TrialBalance.groovy
index 9a4d7af..12acd09 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/reports/TrialBalance.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/reports/TrialBalance.groovy
@@ -29,19 +29,19 @@
 context.partyNameList = partyNameList;
 
 if (parameters.customTimePeriodId) {
-    customTimePeriod = delegator.findOne('CustomTimePeriod', [customTimePeriodId:parameters.customTimePeriodId], true)
+    customTimePeriod = from("CustomTimePeriod").where("customTimePeriodId", parameters.customTimePeriodId).cache(true).queryOne();
     exprList = [];
     exprList.add(EntityCondition.makeCondition('organizationPartyId', EntityOperator.IN, partyIds))
     exprList.add(EntityCondition.makeCondition('fromDate', EntityOperator.LESS_THAN, customTimePeriod.getDate('thruDate').toTimestamp()))
     exprList.add(EntityCondition.makeCondition(EntityCondition.makeCondition('thruDate', EntityOperator.GREATER_THAN_EQUAL_TO, customTimePeriod.getDate('fromDate').toTimestamp()), EntityOperator.OR, EntityCondition.makeCondition('thruDate', EntityOperator.EQUALS, null)))
-    List organizationGlAccounts = delegator.findList('GlAccountOrganizationAndClass', EntityCondition.makeCondition(exprList, EntityOperator.AND), null, ['accountCode'], null, false)
+    List organizationGlAccounts = from("GlAccountOrganizationAndClass").where(exprList).orderBy("accountCode").queryList();
 
     accountBalances = []
     postedDebitsTotal = 0
     postedCreditsTotal = 0
     organizationGlAccounts.each { organizationGlAccount ->
         accountBalance = [:]
-        accountBalance = dispatcher.runSync('computeGlAccountBalanceForTimePeriod', [organizationPartyId: organizationGlAccount.organizationPartyId, customTimePeriodId: customTimePeriod.customTimePeriodId, glAccountId: organizationGlAccount.glAccountId, userLogin: userLogin]);
+        accountBalance = runService('computeGlAccountBalanceForTimePeriod', [organizationPartyId: organizationGlAccount.organizationPartyId, customTimePeriodId: customTimePeriod.customTimePeriodId, glAccountId: organizationGlAccount.glAccountId]);
         if (accountBalance.postedDebits != 0 || accountBalance.postedCredits != 0) {
             accountBalance.glAccountId = organizationGlAccount.glAccountId
             accountBalance.accountCode = organizationGlAccount.accountCode
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/transaction/AuthorizeTransaction.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/transaction/AuthorizeTransaction.groovy
index 6b6a016..06cbcc7 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/transaction/AuthorizeTransaction.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/transaction/AuthorizeTransaction.groovy
@@ -26,7 +26,7 @@
 if ((!orderId) || (!orderPaymentPreferenceId)) return;
 
 if (orderId) {
-   orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+   orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
    context.orderHeader = orderHeader;
 }
 
@@ -37,7 +37,7 @@
 }
 
 if (orderPaymentPreferenceId) {
-   orderPaymentPreference = delegator.findOne("OrderPaymentPreference", [orderPaymentPreferenceId : orderPaymentPreferenceId], false);
+   orderPaymentPreference = from("OrderPaymentPreference").where("orderPaymentPreferenceId", orderPaymentPreferenceId).queryOne();
    context.orderPaymentPreference = orderPaymentPreference;
 }
 
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/transaction/CaptureTransaction.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/transaction/CaptureTransaction.groovy
index 103ef0a..697df5d 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/transaction/CaptureTransaction.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/transaction/CaptureTransaction.groovy
@@ -29,12 +29,12 @@
 if ((!orderId) || (!orderPaymentPreferenceId)) return;
 
 if (orderId) {
-   orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+   orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
    context.orderHeader = orderHeader;
 }
 
 if (orderPaymentPreferenceId) {
-   orderPaymentPreference = delegator.findOne("OrderPaymentPreference", [orderPaymentPreferenceId : orderPaymentPreferenceId], false);
+   orderPaymentPreference = from("OrderPaymentPreference").where("orderPaymentPreferenceId", orderPaymentPreferenceId).queryOne();
    context.orderPaymentPreference = orderPaymentPreference;
 }
 
diff --git a/applications/accounting/webapp/accounting/WEB-INF/actions/transaction/ViewGatewayResponse.groovy b/applications/accounting/webapp/accounting/WEB-INF/actions/transaction/ViewGatewayResponse.groovy
index ffc9ab3..3c2218d 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/actions/transaction/ViewGatewayResponse.groovy
+++ b/applications/accounting/webapp/accounting/WEB-INF/actions/transaction/ViewGatewayResponse.groovy
@@ -42,7 +42,7 @@
   context.orderPaymentPreferenceId = orderPaymentPreference.orderPaymentPreferenceId;
 } else {
     // second purpose: grab the latest gateway response of the orderpaymentpreferenceId
-    orderPaymentPreference = delegator.findOne("OrderPaymentPreference", [orderPaymentPreferenceId : orderPaymentPreferenceId], false);
+    orderPaymentPreference = from("OrderPaymentPreference").where("orderPaymentPreferenceId", orderPaymentPreferenceId).queryOne();
     gatewayResponses = orderPaymentPreference.getRelated("PaymentGatewayResponse", null, ["transactionDate DESC"], false);
     EntityUtil.filterByCondition(gatewayResponses, EntityCondition.makeCondition("transCodeEnumId", EntityOperator.EQUALS, "PGT_AUTHORIZE"));
     
diff --git a/applications/accounting/webapp/ap/WEB-INF/actions/invoices/CommissionReport.groovy b/applications/accounting/webapp/ap/WEB-INF/actions/invoices/CommissionReport.groovy
index 44a64cb..a19a25f 100644
--- a/applications/accounting/webapp/ap/WEB-INF/actions/invoices/CommissionReport.groovy
+++ b/applications/accounting/webapp/ap/WEB-INF/actions/invoices/CommissionReport.groovy
@@ -41,7 +41,7 @@
         invoiceItemAndAssocProductCond.add(EntityCondition.makeCondition("thruDate", EntityOperator.LESS_THAN_EQUAL_TO, Timestamp.valueOf(thruDate)));
     }
     invoiceItemAndAssocProductList = [];
-    invoiceItemAndAssocProductList = delegator.findList("InvoiceItemAndAssocProduct", EntityCondition.makeCondition(invoiceItemAndAssocProductCond, EntityOperator.AND), null, null, null, false);
+    invoiceItemAndAssocProductList = from("InvoiceItemAndAssocProduct").where(invoiceItemAndAssocProductCond).queryList();
 
     //filtering invoiceItemAndAssocProductList for each productId with updating quantity, commission amount and number of order which generated sales invoices.
     totalQuantity = BigDecimal.ZERO;
diff --git a/applications/accounting/webapp/ap/WEB-INF/actions/invoices/CommissionRun.groovy b/applications/accounting/webapp/ap/WEB-INF/actions/invoices/CommissionRun.groovy
index 4402bc6..0a5ed05 100644
--- a/applications/accounting/webapp/ap/WEB-INF/actions/invoices/CommissionRun.groovy
+++ b/applications/accounting/webapp/ap/WEB-INF/actions/invoices/CommissionRun.groovy
@@ -35,11 +35,11 @@
     if (context.salesRepPartyList) {
         invoiceCond.add(EntityCondition.makeCondition("invoiceRolePartyId", EntityOperator.IN, context.salesRepPartyList));
     }
-    invoiceList = delegator.findList("InvoiceAndRole", EntityCondition.makeCondition(invoiceCond, EntityOperator.AND), null, null, null, false);
+    invoiceList = from("InvoiceAndRole").where(invoiceCond).queryList();
 
     List invoices = [];
     if (invoiceList) {
-        resultMap = dispatcher.runSync("getInvoicesFilterByAssocType", [invoiceItemAssocTypeId : "COMMISSION_INVOICE", invoiceList : invoiceList, userLogin : userLogin]);
+        resultMap = runService('getInvoicesFilterByAssocType', [invoiceItemAssocTypeId : "COMMISSION_INVOICE", invoiceList : invoiceList, userLogin : userLogin]);
         invoices = resultMap.filteredInvoiceList; 
         context.invoices = invoices;
     }
diff --git a/applications/accounting/webapp/ar/WEB-INF/actions/BatchPayments.groovy b/applications/accounting/webapp/ar/WEB-INF/actions/BatchPayments.groovy
index 92f21eb..d692e4f 100644
--- a/applications/accounting/webapp/ar/WEB-INF/actions/BatchPayments.groovy
+++ b/applications/accounting/webapp/ar/WEB-INF/actions/BatchPayments.groovy
@@ -43,15 +43,15 @@
         paymentCond.add(EntityCondition.makeCondition("partyIdFrom", EntityOperator.EQUALS, partyIdFrom));
     }
     if (finAccountId) {
-        finAccountTransList = delegator.findList("FinAccountTrans", EntityCondition.makeCondition([finAccountId : finAccountId]), null, null, null, false);
+        finAccountTransList = from("FinAccountTrans").where("finAccountId", finAccountId).queryList();
         if (finAccountTransList) {
             finAccountTransIds = EntityUtil.getFieldListFromEntityList(finAccountTransList, "finAccountTransId", true);
             paymentCond.add(EntityCondition.makeCondition("finAccountTransId", EntityOperator.IN, finAccountTransIds));
-            payments = delegator.findList("PaymentAndTypePartyNameView", EntityCondition.makeCondition(paymentCond, EntityOperator.AND), null, null, null, false);
+            payments = from("PaymentAndTypePartyNameView").where(paymentCond).queryList();
         }
     } else {
         paymentCond.add(EntityCondition.makeCondition("finAccountTransId", EntityOperator.EQUALS, null));
-        payments = delegator.findList("PaymentAndTypePartyNameView", EntityCondition.makeCondition(paymentCond, EntityOperator.AND), null, null, null, false);
+        payments = from("PaymentAndTypePartyNameView").where(paymentCond).queryList();
     }
     paymentListWithCreditCard = [];
     paymentListWithoutCreditCard = [];
@@ -59,10 +59,10 @@
         payments.each { payment ->
             isReceipt = UtilAccounting.isReceipt(payment);
             if (isReceipt) {
-                paymentGroupMembers = EntityUtil.filterByDate(delegator.findList("PaymentGroupMember", EntityCondition.makeCondition([paymentId : payment.paymentId]), null, null, null, false));
+                paymentGroupMembers = from("PaymentGroupMember").where("paymentId", payment.paymentId).filterByDate().queryList();
                 if (!paymentGroupMembers) {
                     if (cardType && payment.paymentMethodId) {
-                        creditCard = delegator.findOne("CreditCard", [paymentMethodId : payment.paymentMethodId], false);
+                        creditCard = from("CreditCard").where("paymentMethodId", payment.paymentMethodId).queryOne();
                         if (creditCard.cardType == cardType) {
                             paymentListWithCreditCard.add(payment);
                         }
diff --git a/applications/content/config/ContentErrorUiLabels.xml b/applications/content/config/ContentErrorUiLabels.xml
index feafda6..6d0da97 100644
--- a/applications/content/config/ContentErrorUiLabels.xml
+++ b/applications/content/config/ContentErrorUiLabels.xml
@@ -306,4 +306,9 @@
         <value xml:lang="zh">没有上传文件</value>
         <value xml:lang="zh_TW">沒有上傳檔案</value>
     </property>
+    <property key="uploadContentAndImage.noRootDirProvided">
+        <value xml:lang="en">No root dir provided, please fill path in the data resource objectInfo field</value>
+        <value xml:lang="fr">Aucun répertoire racine fourni. Veuillez indiquer le chemin dans le champ objectInfo de la ressource de donnée</value>
+    </property>
+
 </resource>
diff --git a/applications/content/config/ContentUiLabels.xml b/applications/content/config/ContentUiLabels.xml
index ebd71cd..5abc301 100644
--- a/applications/content/config/ContentUiLabels.xml
+++ b/applications/content/config/ContentUiLabels.xml
@@ -1031,6 +1031,10 @@
         <value xml:lang="zh">内容设置</value>
         <value xml:lang="zh_TW">內容設定</value>
     </property>
+    <property key="ContentContentShow">
+        <value xml:lang="en">Show Content (if visible else simply Id)</value>
+        <value xml:lang="fr">Montre le contenu (si visible sinon uniquement la référence</value>
+    </property>
     <property key="ContentContentToOrFromErrorRetriving">
         <value xml:lang="en">Error in retrieving content To or From.</value>
         <value xml:lang="fr">Erreur dans la récupération du document de destination ou d'origine.</value>
@@ -1237,6 +1241,10 @@
         <value xml:lang="vi">HTML</value>
         <value xml:lang="zh_TW">HTML</value>
     </property>
+    <property key="ContentDataResourceId">
+        <value xml:lang="en">Data Resource Id</value>
+        <value xml:lang="fr">Ressource de données</value>
+    </property>
     <property key="ContentDataResourceImage">
         <value xml:lang="ar">صورة</value>
         <value xml:lang="da">Billede</value>
@@ -7514,8 +7522,8 @@
         <value xml:lang="ar">إشحن علويا الصورة</value>
         <value xml:lang="da">Upload billede</value>
         <value xml:lang="de">Bild hochladen</value>
-        <value xml:lang="en">Upload Image</value>
-        <value xml:lang="fr">Télécharger une image vers le serveur</value>
+        <value xml:lang="en">Upload File</value>
+        <value xml:lang="fr">Télécharger un fichier vers le serveur</value>
         <value xml:lang="it">Carica Immagine</value>
         <value xml:lang="ja">画像をアップロード</value>
         <value xml:lang="pt">Enviar imagem</value>
diff --git a/applications/content/entitydef/entitymodel.xml b/applications/content/entitydef/entitymodel.xml
index 9a91627..67d4285 100644
--- a/applications/content/entitydef/entitymodel.xml
+++ b/applications/content/entitydef/entitymodel.xml
@@ -1689,9 +1689,6 @@
       <field name="secondsTotal" type="floating-point"></field>
       <field name="searchDate" type="date-time"></field>
       <prim-key field="contentSearchResultId"/>
-      <relation type="one" fk-name="CNT_SCHRES_VST" rel-entity-name="Visit">
-        <key-map field-name="visitId"/>
-      </relation>
     </entity>
     
     <entity entity-name="WebAnalyticsConfig"
diff --git a/applications/content/script/org/ofbiz/content/data/DataServices.xml b/applications/content/script/org/ofbiz/content/data/DataServices.xml
index bdef08c..73f8797 100644
--- a/applications/content/script/org/ofbiz/content/data/DataServices.xml
+++ b/applications/content/script/org/ofbiz/content/data/DataServices.xml
@@ -564,13 +564,16 @@
         <property-to-field resource="content.properties" property="content.upload.always.local.file" field="forceLocal"/>
         <if>
             <condition>
-            <!-- if (forceLocal && !("LOCAL_FILE".equals(parameters.dataResourceTypeId) || "OFBIZ_FILE".equals(parameters.dataResourceTypeId)) -->
                 <and>
                     <if-compare field="forceLocal" value="true" operator="equals"/>
                     <not>
                         <or>
                             <if-compare field="parameters.dataResourceTypeId" operator="equals" value="LOCAL_FILE"/>
                             <if-compare field="parameters.dataResourceTypeId" operator="equals" value="OFBIZ_FILE"/>
+                            <if-compare field="parameters.dataResourceTypeId" operator="equals" value="CONTEXT_FILE"/>
+                            <if-compare field="parameters.dataResourceTypeId" operator="equals" value="LOCAL_FILE_BIN"/>
+                            <if-compare field="parameters.dataResourceTypeId" operator="equals" value="OFBIZ_FILE_BIN"/>
+                            <if-compare field="parameters.dataResourceTypeId" operator="equals" value="CONTEXT_FILE_BIN"/>
                         </or>
                     </not>
                 </and>
@@ -623,15 +626,44 @@
             </if>
         </if-empty>
 
-        <if-compare field="parameters.dataResourceTypeId" value="LOCAL_FILE" operator="equals">
-            <call-simple-method method-name="saveLocalFileDataResource"/>
-            <return/>
-        </if-compare>
+        <if>
+            <condition>
+                <or>
+                    <if-compare field="parameters.dataResourceTypeId" value="LOCAL_FILE" operator="equals"/>
+                    <if-compare field="parameters.dataResourceTypeId" value="LOCAL_FILE_BIN" operator="equals"/>
+                </or>
+            </condition>
+            <then>
+                <call-simple-method method-name="saveLocalFileDataResource"/>
+                <return/>
+            </then>
+        </if>
 
-        <if-compare field="parameters.dataResourceTypeId" value="OFBIZ_FILE" operator="equals">
-            <call-simple-method method-name="saveOfbizFileDataResource"/>
-            <return/>
-        </if-compare>
+        <if>
+            <condition>
+                <or>
+                    <if-compare field="parameters.dataResourceTypeId" value="OFBIZ_FILE" operator="equals"/>
+                    <if-compare field="parameters.dataResourceTypeId" value="OFBIZ_FILE_BIN" operator="equals"/>
+                </or>
+            </condition>
+            <then>
+                <call-simple-method method-name="saveOfbizFileDataResource"/>
+                <return/>
+            </then>
+        </if>
+
+        <if>
+            <condition>
+                <or>
+                    <if-compare field="parameters.dataResourceTypeId" value="CONTEXT_FILE" operator="equals"/>
+                    <if-compare field="parameters.dataResourceTypeId" value="CONTEXT_FILE_BIN" operator="equals"/>
+                </or>
+            </condition>
+            <then>
+                <call-simple-method method-name="saveContextFileDataResource"/>
+                <return/>
+            </then>
+        </if>
 
         <if-compare field="parameters.dataResourceTypeId" value="IMAGE_OBJECT" operator="equals">
             <entity-one entity-name="ImageDataResource" value-field="dataResObj">
@@ -740,7 +772,7 @@
         <if-not-empty field="extension">
             <set value="${uploadPath}/${dataResource.dataResourceId}.${extension.fileExtensionId}" field="dataResource.objectInfo"/>
         </if-not-empty>
-        <set value="LOCAL_FILE" field="dataResource.dataResourceTypeId"/>
+        <set from-field="parameters.dataResourceTypeId" field="dataResource.dataResourceTypeId"/>
         <store-value value-field="dataResource"/>
 
         <set-service-fields service-name="createAnonFile" map="dataResource" to-map="fileCtx"/>
@@ -811,7 +843,7 @@
         <if-not-empty field="extension">
             <set value="${uploadPath}/${dataResource.dataResourceId}.${extension.fileExtensionId}" field="dataResource.objectInfo"/>
         </if-not-empty>
-        <set value="OFBIZ_FILE" field="dataResource.dataResourceTypeId"/>
+        <set from-field="parameters.dataResourceTypeId" field="dataResource.dataResourceTypeId"/>
         <store-value value-field="dataResource"/>
 
         <set-service-fields service-name="createAnonFile" map="dataResource" to-map="fileCtx"/>
@@ -1062,4 +1094,78 @@
         <field-to-result result-name="dataResourceId" field="dataResource.dataResourceId"/>
         <field-to-result result-name="mimeTypeId" field="dataResource.mimeTypeId"/>
     </simple-method>
+
+    <!-- save CONTEXT_FILE data -->
+    <simple-method method-name="saveContextFileDataResource" short-description="Attach an uploaded file to a data resource as CONTEXT_FILE">
+        <entity-one entity-name="DataResource" value-field="dataResource"/>
+        <if-empty field="dataResource">
+            <add-error>
+                <fail-property resource="ContentUiLabels" property="ContentDataResourceNotFound"/>
+            </add-error>
+            <else>
+                <if-not-empty field="dataResource.objectInfo">
+                    <set field="isUpdate" value="Y"/>
+                </if-not-empty>
+            </else>
+        </if-empty>
+        <if>
+            <condition>
+                <if-empty field="parameters._uploadedFile_fileName"/>
+            </condition>
+            <then>
+                <if>
+                    <condition>
+                        <or>
+                            <if-empty field="isUpdate"/>
+                            <if-compare field="isUpdate" value="Y" operator="not-equals"/>
+                        </or>
+                    </condition>
+                    <then>
+                        <add-error>
+                            <fail-property resource="ContentUiLabels" property="ContentNoUploadedContentFound"/>
+                        </add-error>
+                    </then>
+                    <else>
+                        <!-- if not upload is found on an update; its okay, don't do anything just return -->
+                        <field-to-result result-name="dataResourceId" field="dataResource.dataResourceId"/>
+                        <field-to-result result-name="mimeTypeId" field="dataResource.mimeTypeId"/>
+                        <return/>
+                    </else>
+                </if>
+
+            </then>
+        </if>
+        <check-errors/>
+
+        <set field="uploadPath" from-field="parameters.rootDir"/>
+        <log level="info" message="[attachLocalFileToDataResource] - Found Subdir : ${uploadPath}"/>
+        <if-empty field="uploadPath">
+            <add-error>
+                <fail-property resource="ContentErrorUiLabels" property="uploadContentAndImage.noRootDirProvided"/>
+            </add-error>
+            <check-errors/>
+        </if-empty>
+        <log level="info" message="[attachLocalFileToDataResource] - Found Subdir : ${uploadPath}"/>
+
+        <set from-field="parameters._uploadedFile_contentType" field="extenLookup.mimeTypeId"/>
+        <find-by-and entity-name="FileExtension" map="extenLookup" list="extensions"/>
+        <first-from-list entry="extension" list="extensions"/>
+
+        <set from-field="parameters._uploadedFile_fileName" field="dataResource.dataResourceName"/>
+        <set from-field="parameters._uploadedFile_contentType" field="dataResource.mimeTypeId"/>
+        <set value="${uploadPath}/${dataResource.dataResourceId}" field="dataResource.objectInfo"/>
+        <if-not-empty field="extension">
+            <set value="${uploadPath}/${dataResource.dataResourceId}.${extension.fileExtensionId}" field="dataResource.objectInfo"/>
+        </if-not-empty>
+        <set from-field="parameters.dataResourceTypeId" field="dataResource.dataResourceTypeId"/>
+        <store-value value-field="dataResource"/>
+
+        <set-service-fields service-name="createAnonFile" map="dataResource" to-map="fileCtx"/>
+        <set from-field="parameters.uploadedFile" field="fileCtx.binData"/>
+        <set from-field="dataResource" field="fileCtx.dataResource"/>
+        <call-service service-name="createAnonFile" in-map-name="fileCtx" include-user-login="true"/>
+
+        <field-to-result result-name="dataResourceId" field="dataResource.dataResourceId"/>
+        <field-to-result result-name="mimeTypeId" field="dataResource.mimeTypeId"/>
+    </simple-method>
 </simple-methods>
diff --git a/applications/content/servicedef/services_content.xml b/applications/content/servicedef/services_content.xml
index 00c0bdf..52c623d 100644
--- a/applications/content/servicedef/services_content.xml
+++ b/applications/content/servicedef/services_content.xml
@@ -88,6 +88,7 @@
         <attribute name="dataResourceTypeId" type="String" mode="IN" optional="true"/>
         <!-- mimetype is set from the uploaded file (contentType) when empty -->
         <attribute name="mimeTypeId" type="String" mode="INOUT" optional="true"/>
+        <attribute mode="IN" name="rootDir" optional="true" type="String"/>
     </service>
 
     <service name="createContentFromUploadedFile" engine="group" transaction-timeout="300">
diff --git a/applications/content/src/org/ofbiz/content/ContentManagementServices.java b/applications/content/src/org/ofbiz/content/ContentManagementServices.java
index 0bd5dcc..75c1b53 100644
--- a/applications/content/src/org/ofbiz/content/ContentManagementServices.java
+++ b/applications/content/src/org/ofbiz/content/ContentManagementServices.java
@@ -146,7 +146,6 @@
         Map<String, Object> context = UtilMisc.makeMapWritable(rcontext);
         Locale locale = (Locale) context.get("locale");
 
-        Debug.logInfo("=========== type:" + (String)context.get("dataresourceTypeId") , module);
         // Knowing why a request fails permission check is one of the more difficult
         // aspects of content management. Setting "displayFailCond" to true will
         // put an html table in result.errorMessage that will show what tests were performed
@@ -638,7 +637,7 @@
           newDrContext.put("mimeTypeId", mimeTypeId);
       }
 
-      if (!dataResourceExists) {
+      if (!dataResourceExists) { // Create
           Map<String, Object> thisResult = dispatcher.runSync("createDataResource", newDrContext);
           String errorMsg = ServiceUtil.getErrorMessage(thisResult);
           if (UtilValidate.isNotEmpty(errorMsg)) {
@@ -651,29 +650,7 @@
           dataResource = (GenericValue)thisResult.get("dataResource");
           Map<String, Object> fileContext = FastMap.newInstance();
           fileContext.put("userLogin", userLogin);
-          if (dataResourceTypeId.indexOf("_FILE") >=0) {
-              boolean hasData = false;
-              if (textData != null) {
-                  fileContext.put("textData", textData);
-                  hasData = true;
-              }
-              if (imageDataBytes != null) {
-                  fileContext.put("binData", imageDataBytes);
-                  hasData = true;
-              }
-              if (hasData) {
-                  fileContext.put("rootDir", context.get("rootDir"));
-                  fileContext.put("dataResourceTypeId", dataResourceTypeId);
-                  if (UtilValidate.isNotEmpty(dataResource) && UtilValidate.isNotEmpty(dataResource.get("objectInfo"))) {
-                      fileContext.put("objectInfo", dataResource.get("objectInfo"));
-                  }
-                  thisResult = dispatcher.runSync("createFile", fileContext);
-                  errorMsg = ServiceUtil.getErrorMessage(thisResult);
-                  if (UtilValidate.isNotEmpty(errorMsg)) {
-                      return ServiceUtil.returnError(errorMsg);
-                  }
-              }
-          } else if (dataResourceTypeId.equals("IMAGE_OBJECT")) {
+          if (dataResourceTypeId.equals("IMAGE_OBJECT")) {
               if (imageDataBytes != null) {
                   fileContext.put("dataResourceId", dataResourceId);
                   fileContext.put("imageData", imageDataBytes);
@@ -697,46 +674,19 @@
                   }
               }
           }
-      } else {
+      } else { // Update
           Map<String, Object> thisResult = dispatcher.runSync("updateDataResource", newDrContext);
           String errorMsg = ServiceUtil.getErrorMessage(thisResult);
           if (UtilValidate.isNotEmpty(errorMsg)) {
               return ServiceUtil.returnError(errorMsg);
           }
-          //Map thisResult = DataServices.updateDataResourceMethod(dctx, context);
-          if (Debug.infoOn()) {
-              Debug.logInfo("====in persist... thisResult.permissionStatus(0):" + thisResult.get("permissionStatus"), null);
-          }
-          //thisResult = DataServices.updateElectronicTextMethod(dctx, context);
           Map<String, Object> fileContext = FastMap.newInstance();
           fileContext.put("userLogin", userLogin);
           String forceElectronicText = (String)context.get("forceElectronicText");
-          Debug.logInfo("====dataResourceType" + dataResourceTypeId , module);
-          if (dataResourceTypeId.indexOf("_FILE") >=0) {
-              boolean hasData = false;
-              if (textData != null) {
-                  fileContext.put("textData", textData);
-                  hasData = true;
-              }
-              if (imageDataBytes != null) {
-                  fileContext.put("binData", imageDataBytes);
-                  hasData = true;
-              }
-              if (hasData || "true".equalsIgnoreCase(forceElectronicText)) {
-                  fileContext.put("rootDir", context.get("rootDir"));
-                  fileContext.put("dataResourceTypeId", dataResourceTypeId);
-                  fileContext.put("objectInfo", dataResource.get("objectInfo"));
-                  thisResult = dispatcher.runSync("updateFile", fileContext);
-                  errorMsg = ServiceUtil.getErrorMessage(thisResult);
-                  if (UtilValidate.isNotEmpty(errorMsg)) {
-                      return ServiceUtil.returnError(errorMsg);
-                  }
-              }
-          } else if (dataResourceTypeId.equals("IMAGE_OBJECT")) {
+          if (dataResourceTypeId.equals("IMAGE_OBJECT")) {
               if (imageDataBytes != null || "true".equalsIgnoreCase(forceElectronicText)) {
                   fileContext.put("dataResourceId", dataResourceId);
                   fileContext.put("imageData", imageDataBytes);
-                  Debug.logInfo("====trying to update image", module);
                   thisResult = dispatcher.runSync("updateImage", fileContext);
                   errorMsg = ServiceUtil.getErrorMessage(thisResult);
                   if (UtilValidate.isNotEmpty(errorMsg)) {
@@ -757,6 +707,17 @@
               }
           }
       }
+      if (dataResourceTypeId.indexOf("_FILE") >=0) {
+          Map<String, Object> uploadImage = FastMap.newInstance();
+          uploadImage.put("userLogin", userLogin);
+          uploadImage.put("dataResourceId", dataResourceId);
+          uploadImage.put("dataResourceTypeId", dataResourceTypeId);
+          uploadImage.put("rootDir", context.get("objectInfo"));
+          uploadImage.put("uploadedFile", imageDataBytes);
+          uploadImage.put("_uploadedFile_fileName", (String) context.get("_imageData_fileName"));
+          uploadImage.put("_uploadedFile_contentType", (String) context.get("_imageData_contentType"));
+          dispatcher.runSync("attachUploadToDataResource", uploadImage);
+      }
       result.put("dataResourceId", dataResourceId);
       result.put("drDataResourceId", dataResourceId);
       context.put("dataResourceId", dataResourceId);
diff --git a/applications/content/src/org/ofbiz/content/content/ContentUrlFilter.java b/applications/content/src/org/ofbiz/content/content/ContentUrlFilter.java
index 7f42d1d..4f2c779 100644
--- a/applications/content/src/org/ofbiz/content/content/ContentUrlFilter.java
+++ b/applications/content/src/org/ofbiz/content/content/ContentUrlFilter.java
@@ -31,7 +31,7 @@
 import javax.servlet.http.HttpServletResponse;
 
 import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
 import org.ofbiz.base.util.UtilHttp;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.common.UrlServletHelper;
@@ -39,7 +39,6 @@
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.webapp.control.ContextFilter;
-import org.owasp.esapi.errors.EncodingException;
 
 public class ContentUrlFilter extends ContextFilter {
     public final static String module = ContentUrlFilter.class.getName();
@@ -118,14 +117,10 @@
                     .queryFirst();
             if (contentAssocDataResource != null) {
                 url = contentAssocDataResource.getString("drObjectInfo");
-                try {
-                    url = StringUtil.defaultWebEncoder.decodeFromURL(url);
-                    String mountPoint = request.getContextPath();
-                    if (!(mountPoint.equals("/")) && !(mountPoint.equals(""))) {
-                        url = mountPoint + url;
-                    }
-                } catch (EncodingException e) {
-                    Debug.logError(e, module);
+                url = UtilCodec.getDecoder("url").decode(url);
+                String mountPoint = request.getContextPath();
+                if (!(mountPoint.equals("/")) && !(mountPoint.equals(""))) {
+                    url = mountPoint + url;
                 }
             }
         } catch (Exception e) {
diff --git a/applications/content/src/org/ofbiz/content/data/DataResourceWorker.java b/applications/content/src/org/ofbiz/content/data/DataResourceWorker.java
index 17f4ad4..d4f7f4b 100644
--- a/applications/content/src/org/ofbiz/content/data/DataResourceWorker.java
+++ b/applications/content/src/org/ofbiz/content/data/DataResourceWorker.java
@@ -56,6 +56,7 @@
 import org.ofbiz.base.util.FileUtil;
 import org.ofbiz.base.util.GeneralException;
 import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.StringUtil.StringWrapper;
 import org.ofbiz.base.util.UtilGenerics;
 import org.ofbiz.base.util.UtilHttp;
 import org.ofbiz.base.util.UtilIO;
@@ -63,7 +64,6 @@
 import org.ofbiz.base.util.UtilProperties;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.StringUtil.StringWrapper;
 import org.ofbiz.base.util.collections.MapStack;
 import org.ofbiz.base.util.template.FreeMarkerWorker;
 import org.ofbiz.base.util.template.XslTransform;
@@ -942,14 +942,14 @@
     public static void renderFile(String dataResourceTypeId, String objectInfo, String rootDir, Appendable out) throws GeneralException, IOException {
         // TODO: this method assumes the file is a text file, if it is an image we should respond differently, see the comment above for IMAGE_OBJECT type data resource
 
-        if (dataResourceTypeId.equals("LOCAL_FILE")) {
+        if (dataResourceTypeId.equals("LOCAL_FILE") && UtilValidate.isNotEmpty(objectInfo)) {
             File file = FileUtil.getFile(objectInfo);
             if (!file.isAbsolute()) {
                 throw new GeneralException("File (" + objectInfo + ") is not absolute");
             }
             FileReader in = new FileReader(file);
             UtilIO.copy(in, true, out);
-        } else if (dataResourceTypeId.equals("OFBIZ_FILE")) {
+        } else if (dataResourceTypeId.equals("OFBIZ_FILE") && UtilValidate.isNotEmpty(objectInfo)) {
             String prefix = System.getProperty("ofbiz.home");
             String sep = "";
             if (objectInfo.indexOf("/") != 0 && prefix.lastIndexOf("/") != (prefix.length() - 1)) {
@@ -958,7 +958,7 @@
             File file = FileUtil.getFile(prefix + sep + objectInfo);
             FileReader in = new FileReader(file);
             UtilIO.copy(in, true, out);
-        } else if (dataResourceTypeId.equals("CONTEXT_FILE")) {
+        } else if (dataResourceTypeId.equals("CONTEXT_FILE") && UtilValidate.isNotEmpty(objectInfo)) {
             String prefix = rootDir;
             String sep = "";
             if (objectInfo.indexOf("/") != 0 && prefix.lastIndexOf("/") != (prefix.length() - 1)) {
diff --git a/applications/content/src/org/ofbiz/content/view/SimpleContentViewHandler.java b/applications/content/src/org/ofbiz/content/view/SimpleContentViewHandler.java
index 1d0cf66..0b2fb69 100644
--- a/applications/content/src/org/ofbiz/content/view/SimpleContentViewHandler.java
+++ b/applications/content/src/org/ofbiz/content/view/SimpleContentViewHandler.java
@@ -25,10 +25,12 @@
 import java.text.ParseException;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
 
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.GeneralException;
@@ -42,6 +44,10 @@
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.util.EntityQuery;
+import org.ofbiz.entity.util.EntityUtilProperties;
+import org.ofbiz.service.GenericServiceException;
+import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.service.ServiceUtil;
 import org.ofbiz.webapp.view.AbstractViewHandler;
 import org.ofbiz.webapp.view.ViewHandlerException;
 import org.ofbiz.webapp.website.WebSiteWorker;
@@ -66,6 +72,9 @@
      */
     public void render(String name, String page, String info, String contentType, String encoding, HttpServletRequest request, HttpServletResponse response) throws ViewHandlerException {
 
+        LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
+        HttpSession session = request.getSession();
+        GenericValue userLogin = (GenericValue) session.getAttribute("userLogin");
         String contentId = request.getParameter("contentId");
         String rootContentId = request.getParameter("rootContentId");
         String mapKey = request.getParameter("mapKey");
@@ -136,6 +145,43 @@
                 if (!UtilValidate.isEmpty(dataResource.getString("dataResourceName"))) {
                     fileName = dataResource.getString("dataResourceName").replace(" ", "_"); // spaces in filenames can be a problem
                 }
+
+                // see if data resource is public or not
+                String isPublic = dataResource.getString("isPublic");
+                if (UtilValidate.isEmpty(isPublic)) {
+                    isPublic = "N";
+                }
+                // get the permission service required for streaming data; default is always the genericContentPermission
+                String permissionService = EntityUtilProperties.getPropertyValue("content.properties", "stream.permission.service", "genericContentPermission", delegator);
+
+                // not public check security
+                if (!"Y".equalsIgnoreCase(isPublic)) {
+                    // do security check
+                    Map<String, ? extends Object> permSvcCtx = UtilMisc.toMap("userLogin", userLogin, "locale", locale, "mainAction", "VIEW", "contentId", contentId);
+                    Map<String, Object> permSvcResp;
+                    try {
+                        permSvcResp = dispatcher.runSync(permissionService, permSvcCtx);
+                    } catch (GenericServiceException e) {
+                        Debug.logError(e, module);
+                        request.setAttribute("_ERROR_MESSAGE_", e.getMessage());
+                        throw new ViewHandlerException(e.getMessage());
+                    }
+                    if (ServiceUtil.isError(permSvcResp)) {
+                        String errorMsg = ServiceUtil.getErrorMessage(permSvcResp);
+                        Debug.logError(errorMsg, module);
+                        request.setAttribute("_ERROR_MESSAGE_", errorMsg);
+                        throw new ViewHandlerException(errorMsg);
+                    }
+
+                    // no service errors; now check the actual response
+                    Boolean hasPermission = (Boolean) permSvcResp.get("hasPermission");
+                    if (!hasPermission.booleanValue()) {
+                        String errorMsg = (String) permSvcResp.get("failMessage");
+                        Debug.logError(errorMsg, module);
+                        request.setAttribute("_ERROR_MESSAGE_", errorMsg);
+                        throw new ViewHandlerException(errorMsg);
+                    }
+                }
                 UtilHttp.streamContentToBrowser(response, bais, byteBuffer.limit(), contentType2, fileName);
             }
         } catch (GenericEntityException e) {
diff --git a/applications/content/webapp/content/WEB-INF/actions/cms/CmsEditAddPrep.groovy b/applications/content/webapp/content/WEB-INF/actions/cms/CmsEditAddPrep.groovy
index 65d0c8b..77ac4f4 100644
--- a/applications/content/webapp/content/WEB-INF/actions/cms/CmsEditAddPrep.groovy
+++ b/applications/content/webapp/content/WEB-INF/actions/cms/CmsEditAddPrep.groovy
@@ -35,7 +35,7 @@
 
 contentAssoc = null;
 if (contentAssocPK.isPrimaryKey()) {
-    contentAssoc = delegator.findOne("ContentAssoc", contentAssocPK, false);
+    contentAssoc = from("ContentAssoc").where(contentAssocPK).queryOne();
 }
 
 if (contentAssoc) {
@@ -50,7 +50,7 @@
 textData = "";
 content = null;
 if (contentId) {
-    content = delegator.findOne("Content", [contentId : contentId], true);
+    content = from("Content").where("contentId", contentId).cache(true).queryOne();
     if (content) {
         contentAssocDataResourceViewFrom.setAllFields(content, false, null, null);
     }
@@ -68,7 +68,7 @@
     }
 }
 if (dataResourceId) {
-    dataResource = delegator.findOne("DataResource", [dataResourceId : dataResourceId], true);
+    dataResource = from("DataResource").where("dataResourceId", dataResourceId).cache(true).queryOne();
     SimpleMapProcessor.runSimpleMapProcessor("component://content/script/org/ofbiz/content/ContentManagementMapProcessors.xml", "dataResourceOut", dataResource, contentAssocDataResourceViewFrom, new ArrayList(), Locale.getDefault());
     templateRoot = [:];
     FreeMarkerViewHandler.prepOfbizRoot(templateRoot, request, response);
diff --git a/applications/content/webapp/content/WEB-INF/actions/cms/FeaturePrep.groovy b/applications/content/webapp/content/WEB-INF/actions/cms/FeaturePrep.groovy
index 8a56bfd..8ed3a73 100644
--- a/applications/content/webapp/content/WEB-INF/actions/cms/FeaturePrep.groovy
+++ b/applications/content/webapp/content/WEB-INF/actions/cms/FeaturePrep.groovy
@@ -24,13 +24,13 @@
 contentId = context.contentId;
 dataResourceId = context.dataResourceId;
 
-productFeatureList = delegator.findList("ProductFeature", null, null, null, null, true);
+productFeatureList = from("ProductFeature").cache(true).queryList();
 featureList = [] as ArrayList;
 if (dataResourceId) {
     productFeatureList.each { productFeature ->
         productFeatureId = productFeature.productFeatureId;
         description = productFeature.description;
-        productFeatureDataResource = delegator.findOne("ProductFeatureDataResource", [productFeatureId : productFeatureId, dataResourceId : dataResourceId], true);
+        productFeatureDataResource = from("ProductFeatureDataResource").where("productFeatureId", productFeatureId, "dataResourceId", dataResourceId).cache(true).queryOne();
         if (productFeatureDataResource) {
             feature = [];
             feature.productFeatureId = productFeatureId;
diff --git a/applications/content/webapp/content/WEB-INF/actions/cms/MostRecentPrep.groovy b/applications/content/webapp/content/WEB-INF/actions/cms/MostRecentPrep.groovy
index 8da6bd0..9ff64b3 100644
--- a/applications/content/webapp/content/WEB-INF/actions/cms/MostRecentPrep.groovy
+++ b/applications/content/webapp/content/WEB-INF/actions/cms/MostRecentPrep.groovy
@@ -38,7 +38,7 @@
     contentIdToExpr = EntityCondition.makeCondition("caContentId", EntityOperator.EQUALS, forumId);
     exprList.add(contentIdToExpr);
     expr = EntityCondition.makeCondition(exprList, EntityOperator.AND);
-    entityList = delegator.findList("ContentAssocViewFrom", expr, null, ['-caFromDate'], null, false);
+    entityList = from("ContentAssocViewFrom").where(exprList).orderBy("-caFromDate").queryList();
 
     Debug.logInfo("in mostrecentprep(1), entityList.size():" + entityList.size(),"");
     Debug.logInfo("in mostrecentprep(1), entityList:" + entityList,"");
diff --git a/applications/content/webapp/content/WEB-INF/actions/cms/UserPermPrep.groovy b/applications/content/webapp/content/WEB-INF/actions/cms/UserPermPrep.groovy
index a724672..ebc6166 100644
--- a/applications/content/webapp/content/WEB-INF/actions/cms/UserPermPrep.groovy
+++ b/applications/content/webapp/content/WEB-INF/actions/cms/UserPermPrep.groovy
@@ -23,15 +23,14 @@
 
 paramMap = UtilHttp.getParameterMap(request);
 forumId = ContentManagementWorker.getFromSomewhere("permRoleSiteId", paramMap, request, context);
-blogRoles = delegator.findList("RoleType", EntityCondition.makeCondition([parentTypeId : 'BLOG']), null, null, null, true);
+blogRoles = from("RoleType").where("parentTypeId", "BLOG").cache(true).queryList();
 
 if (forumId) {
     siteRoleMap = [:];
     for (int i=0; i < blogRoles.size(); i++) {
         roleType = blogRoles.get(i);
         roleTypeId = roleType.roleTypeId;
-        contentRoleList = delegator.findList("ContentRole", EntityCondition.makeCondition([contentId : forumId, roleTypeId : roleTypeId]), null, null, null, false);
-        filteredRoleList = EntityUtil.filterByDate(contentRoleList);
+        filteredRoleList = from("ContentRole").where("contentId", forumId, "roleTypeId", roleTypeId).filterByDate().queryList();
         cappedBlogRoleName = ModelUtil.dbNameToVarName(roleTypeId);
 
         filteredRoleList.each { contentRole ->
diff --git a/applications/content/webapp/content/WEB-INF/actions/content/ContentSearchOptions.groovy b/applications/content/webapp/content/WEB-INF/actions/content/ContentSearchOptions.groovy
index 838a800..429d804 100644
--- a/applications/content/webapp/content/WEB-INF/actions/content/ContentSearchOptions.groovy
+++ b/applications/content/webapp/content/WEB-INF/actions/content/ContentSearchOptions.groovy
@@ -53,8 +53,8 @@
 
 searchConstraintStrings = ContentSearchSession.searchGetConstraintStrings(false, session, delegator);
 searchSortOrderString = ContentSearchSession.searchGetSortOrderString(false, request);
-contentAssocTypes=delegator.findList("ContentAssocType", null, null, null, null, false);
-roleTypes=delegator.findList("RoleType", null, null, null, null, false);
+contentAssocTypes = from("ContentAssocType").queryList();
+roleTypes = from("RoleType").queryList();
 
 context.put("searchOperator", searchOperator);
 context.put("searchConstraintStrings", searchConstraintStrings);
diff --git a/applications/content/webapp/content/WEB-INF/actions/content/GetContentLookupList.groovy b/applications/content/webapp/content/WEB-INF/actions/content/GetContentLookupList.groovy
index f5049da..0a6e35b 100644
--- a/applications/content/webapp/content/WEB-INF/actions/content/GetContentLookupList.groovy
+++ b/applications/content/webapp/content/WEB-INF/actions/content/GetContentLookupList.groovy
@@ -80,7 +80,6 @@
 context.lowIndex = lowIndex;
 int arraySize = 0;
 List resultPartialList = null;
-    conditions = [EntityCondition.makeCondition("contentIdStart", EntityOperator.EQUALS,(String)parameters.get("contentId"))];
 
 if ((highIndex - lowIndex + 1) > 0) {
     // get the results as an entity list iterator
@@ -88,9 +87,7 @@
     if(resultPartialList==null){
     try {
         beganTransaction = TransactionUtil.begin();
-        allConditions = EntityCondition.makeCondition( conditions, EntityOperator.AND );
-        findOptions = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
-        EntityListIterator listIt = delegator.find("ContentAssocViewTo", allConditions, null, null, ["contentId ASC"], findOptions);
+        EntityListIterator listIt = from("ContentAssocViewTo").where("contentIdStart", (String)parameters.get("contentId")).orderBy("contentId ASC").cursorScrollInsensitive().cache(true).queryIterator();
         resultPartialList = listIt.getPartialList(lowIndex, highIndex - lowIndex + 1);
         
         arraySize = listIt.getResultsSizeAfterPartialList();
diff --git a/applications/content/webapp/content/WEB-INF/actions/contentsetup/UserPermPrep.groovy b/applications/content/webapp/content/WEB-INF/actions/contentsetup/UserPermPrep.groovy
index 809ce5f..749d758 100644
--- a/applications/content/webapp/content/WEB-INF/actions/contentsetup/UserPermPrep.groovy
+++ b/applications/content/webapp/content/WEB-INF/actions/contentsetup/UserPermPrep.groovy
@@ -27,15 +27,14 @@
 
 paramMap = UtilHttp.getParameterMap(request);
 forumId = ContentManagementWorker.getFromSomewhere("webSitePublishPoint", paramMap, request, context);
-blogRoles = delegator.findList("RoleType", EntityCondition.makeCondition([parentTypeId : 'BLOG']), null, null, null, true);
+blogRoles = from("RoleType").where("parentTypeId", "BLOG").cache(true).queryList();
 
 if (forumId) {
     siteRoleMap = [:];
     for (int i=0; i < blogRoles.size(); i++) {
         roleType = blogRoles.get(i);
         roleTypeId = roleType.roleTypeId;
-        contentRoleList = delegator.findList("ContentRole", EntityCondition.makeCondition([contentId : forumId, roleTypeId : roleTypeId]), null, null, null, false);
-        filteredRoleList = EntityUtil.filterByDate(contentRoleList);
+        filteredRoleList = from("ContentRole").where("contentId", forumId, "roleTypeId", roleTypeId).filterByDate().queryList();
         cappedBlogRoleName = ModelUtil.dbNameToVarName(roleTypeId);
 
         filteredRoleList.each { contentRole ->
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 b7eec26..e5d1ad2 100644
--- a/applications/content/webapp/content/WEB-INF/actions/survey/EditSurveyQuestions.groovy
+++ b/applications/content/webapp/content/WEB-INF/actions/survey/EditSurveyQuestions.groovy
@@ -25,11 +25,11 @@
 surveyQuestionId = parameters.surveyQuestionId;
 context.surveyQuestionId = surveyQuestionId;
 
-surveyQuestion = delegator.findOne("SurveyQuestion", [surveyQuestionId : surveyQuestionId], false);
+surveyQuestion = from("SurveyQuestion").where("surveyQuestionId", surveyQuestionId).queryOne();
 
-surveyQuestionAndApplList = delegator.findList("SurveyQuestionAndAppl", EntityCondition.makeCondition([surveyId : surveyId]), null, ['sequenceNum'], null, false);
-surveyPageList = delegator.findList("SurveyPage", EntityCondition.makeCondition([surveyId : surveyId]), null, ['sequenceNum'], null, false);
-surveyMultiRespList = delegator.findList("SurveyMultiResp", EntityCondition.makeCondition([surveyId : surveyId]), null, ['multiRespTitle'], null, false);
+surveyQuestionAndApplList = from("SurveyQuestionAndAppl").where("surveyId", surveyId).orderBy("sequenceNum").queryList();
+surveyPageList = from("SurveyPage").where("surveyId", surveyId).orderBy("sequenceNum").queryList();
+surveyMultiRespList = from("SurveyMultiResp").where("surveyId", surveyId).orderBy("multiRespTitle").queryList();
 
 HtmlFormWrapper createSurveyQuestionWrapper = new HtmlFormWrapper("component://content/widget/survey/SurveyForms.xml", "CreateSurveyQuestion", request, response);
 createSurveyQuestionWrapper.putInContext("surveyId", surveyId);
@@ -40,7 +40,7 @@
 
 if (surveyQuestion && surveyQuestion.surveyQuestionTypeId && "OPTION".equals(surveyQuestion.surveyQuestionTypeId)) {
     // get the options
-    questionOptions = delegator.findList("SurveyQuestionOption", EntityCondition.makeCondition([surveyQuestionId : surveyQuestionId]), null, ['sequenceNum'], null, false);
+    questionOptions = from("SurveyQuestionOption").where("surveyQuestionId", surveyQuestionId).orderBy("sequenceNum").queryList();
     context.questionOptions = questionOptions;
 
     HtmlFormWrapper createSurveyOptionWrapper = new HtmlFormWrapper("component://content/widget/survey/SurveyForms.xml", "CreateSurveyQuestionOption", request, response);
@@ -49,7 +49,7 @@
     optionSeqId = parameters.surveyOptionSeqId;
     surveyQuestionOption = null;
     if (optionSeqId) {
-        surveyQuestionOption = delegator.findOne("SurveyQuestionOption", [surveyQuestionId : surveyQuestionId, surveyOptionSeqId : optionSeqId], false);
+        surveyQuestionOption = from("SurveyQuestionOption").where("surveyQuestionId", surveyQuestionId, "surveyOptionSeqId", optionSeqId).queryOne();
     }
     context.surveyQuestionOption = surveyQuestionOption;
 
@@ -63,12 +63,12 @@
 surveyQuestionCategory = null;
 categoryQuestions = null;
 if (surveyQuestionCategoryId) {
-    surveyQuestionCategory = delegator.findOne("SurveyQuestionCategory", [surveyQuestionCategoryId : surveyQuestionCategoryId], false);
+    surveyQuestionCategory = from("SurveyQuestionCategory").where("surveyQuestionCategoryId", surveyQuestionCategoryId).queryOne();
     if (surveyQuestionCategory) {
         categoryQuestions = surveyQuestionCategory.getRelated("SurveyQuestion", null, null, false);
     }
 }
-questionCategories = delegator.findList("SurveyQuestionCategory", null, null, ['description'], null, false);
+questionCategories = from("SurveyQuestionCategory").orderBy("description").queryList();
 context.surveyQuestion = surveyQuestion;
 
 context.surveyQuestionAndApplList = surveyQuestionAndApplList;
diff --git a/applications/content/webapp/content/WEB-INF/actions/survey/EditSurveyResponse.groovy b/applications/content/webapp/content/WEB-INF/actions/survey/EditSurveyResponse.groovy
index 7c92e16..b3d586b 100644
--- a/applications/content/webapp/content/WEB-INF/actions/survey/EditSurveyResponse.groovy
+++ b/applications/content/webapp/content/WEB-INF/actions/survey/EditSurveyResponse.groovy
@@ -24,7 +24,8 @@
 partyId = null;
 
 if (!surveyId && surveyResponseId) {
-   surveyResponse = delegator.findOne("SurveyResponse", [surveyResponseId : surveyResponseId], false);
+   surveyResponse = from("SurveyResponse").where("surveyResponseId", surveyResponseId).queryOne();
+   
    surveyId = surveyResponse.surveyId;
    context.surveyId = surveyId;
 }
diff --git a/applications/content/webapp/content/WEB-INF/actions/survey/ViewSurveyResponses.groovy b/applications/content/webapp/content/WEB-INF/actions/survey/ViewSurveyResponses.groovy
index a412133..e740c14 100644
--- a/applications/content/webapp/content/WEB-INF/actions/survey/ViewSurveyResponses.groovy
+++ b/applications/content/webapp/content/WEB-INF/actions/survey/ViewSurveyResponses.groovy
@@ -22,11 +22,11 @@
 if (!survey) {
     surveyResponseId = parameters.surveyResponseId;
     if (surveyResponseId) {
-        surveyResponse = delegator.findOne("SurveyResponse", [surveyResponseId : surveyResponseId], false);
+        surveyResponse = from("SurveyResponse").where("surveyResponseId", surveyResponseId).queryOne();
         if (surveyResponse) {
             surveyId = surveyResponse.surveyId;
             if (surveyId) {
-                survey = delegator.findOne("Survey", [surveyId : surveyId], false);
+                survey = from("Survey").where("surveyId", surveyId).queryOne();
                 context.survey = survey;
                 context.surveyId = surveyId;
             }
diff --git a/applications/content/webapp/content/WEB-INF/actions/website/WebSiteCMSMetaInfo.groovy b/applications/content/webapp/content/WEB-INF/actions/website/WebSiteCMSMetaInfo.groovy
index bc1df86..879e3d7 100644
--- a/applications/content/webapp/content/WEB-INF/actions/website/WebSiteCMSMetaInfo.groovy
+++ b/applications/content/webapp/content/WEB-INF/actions/website/WebSiteCMSMetaInfo.groovy
@@ -23,36 +23,28 @@
 
 if (content) {
     // lookup assoc content
-    titles = delegator.findList("ContentAssoc", EntityCondition.makeCondition([contentId : contentId, mapKey : 'title']), null, ['-fromDate'], null, false);
-    titles = EntityUtil.filterByDate(titles);
-    title = EntityUtil.getFirst(titles);
+    title = from("ContentAssoc").where("contentId", contentId, "mapKey", "title").orderBy("-fromDate").filterByDate().queryFirst();
     if (title) {
         tc = title.getRelatedOne("ToContent", false);
         tcdr = tc.getRelatedOne("DataResource", false);
         context.title = tcdr;
     }
 
-    titleProps = delegator.findList("ContentAssoc", EntityCondition.makeCondition([contentId : contentId, mapKey : 'titleProperty']), null, ['-fromDate'], null, false);
-    titleProps = EntityUtil.filterByDate(titleProps);
-    titleProp = EntityUtil.getFirst(titleProps);
+    titleProp = from("ContentAssoc").where("contentId", contentId, "mapKey", "titleProperty").orderBy("-fromDate").filterByDate().queryFirst();
     if (titleProp) {
         tpc = titleProp.getRelatedOne("ToContent", false);
         tpcdr = tpc.getRelatedOne("DataResource", false);
         context.titleProperty = tpcdr;
     }
 
-    metaDescs = delegator.findList("ContentAssoc", EntityCondition.makeCondition([contentId : contentId, mapKey : 'metaDescription']), null, ['-fromDate'], null, false);
-    metaDescs = EntityUtil.filterByDate(metaDescs);
-    metaDesc = EntityUtil.getFirst(metaDescs);
+    metaDesc = from("ContentAssoc").where("contentId", contentId, "mapKey", "metaDescription").orderBy("-fromDate").filterByDate().queryFirst();
     if (metaDesc) {
         mdc = metaDesc.getRelatedOne("ToContent", false);
         mdcdr = mdc.getRelatedOne("DataResource", false);
         context.metaDescription = mdcdr;
     }
 
-    metaKeys = delegator.findList("ContentAssoc", EntityCondition.makeCondition([contentId : contentId, mapKey : 'metaKeywords']), null, ['-fromDate'], null, false);
-    metaKeys = EntityUtil.filterByDate(metaKeys);
-    metaKey = EntityUtil.getFirst(metaKeys);
+    metaKey = from("ContentAssoc").where("contentId", contentId, "mapKey", "metaKeywords").orderBy("-fromDate").filterByDate().queryFirst();
     if (metaKey) {
         mkc = metaKey.getRelatedOne("ToContent", false);
         mkcdr = mkc.getRelatedOne("DataResource", false);
diff --git a/applications/content/webapp/content/WEB-INF/actions/website/WebSitePublishPoint.groovy b/applications/content/webapp/content/WEB-INF/actions/website/WebSitePublishPoint.groovy
index 450d118..4e11b9c 100644
--- a/applications/content/webapp/content/WEB-INF/actions/website/WebSitePublishPoint.groovy
+++ b/applications/content/webapp/content/WEB-INF/actions/website/WebSitePublishPoint.groovy
@@ -20,10 +20,7 @@
 import org.ofbiz.entity.condition.*
 import org.ofbiz.entity.util.*
 
-pplookupMap = [webSiteId : webSiteId, webSiteContentTypeId : 'PUBLISH_POINT'];
-webSiteContents = delegator.findList("WebSiteContent", EntityCondition.makeCondition(pplookupMap), null, ['-fromDate'], null, false);
-webSiteContents = EntityUtil.filterByDate(webSiteContents);
-webSiteContent = EntityUtil.getFirst(webSiteContents);
+webSiteContent = from("WebSiteContent").where("webSiteId", webSiteId, "webSiteContentTypeId", "PUBLISH_POINT").orderBy("-fromDate").filterByDate().queryFirst();
 if (webSiteContent) {
     content = webSiteContent.getRelatedOne("Content", false);
     contentRoot = content.contentId;
@@ -31,13 +28,11 @@
     context.contentRoot = contentRoot;
 
     // get all sub content for the publish point
-    subsites = delegator.findList("ContentAssoc", EntityCondition.makeCondition([contentId : contentRoot]), null, null, null, false);
+    subsites = from("ContentAssoc").where("contentId", contentRoot).queryList();
     context.subsites = subsites;
 }
 
-mnlookupMap = [webSiteId : webSiteId, webSiteContentTypeId : 'MENU_ROOT'];
-webSiteMenus = delegator.findList("WebSiteContent", EntityCondition.makeCondition(mnlookupMap), null, ['-fromDate'], null, false);
-webSiteMenu = EntityUtil.getFirst(webSiteMenus);
+webSiteMenu = from("WebSiteContent").where("webSiteId", webSiteId, "webSiteContentTypeId", "MENU_ROOT").orderBy("-fromDate").queryFirst();
 if (webSiteMenu) {
     menu = webSiteMenu.getRelatedOne("Content", false);
     menuRoot = menu.contentId;
@@ -45,13 +40,11 @@
     context.menuRoot = menuRoot;
 
     // get all sub content for the menu root
-    menus = delegator.findList("ContentAssoc", EntityCondition.makeCondition([contentId : menuRoot]), null, null, null, false);
+    menus = from("ContentAssoc").where("contentId", menuRoot).queryList();
     context.menus = menus;
 }
 
-erlookupMap = [webSiteId : webSiteId, webSiteContentTypeId : 'ERROR_ROOT'];
-webSiteErrors = delegator.findList("WebSiteContent", EntityCondition.makeCondition(erlookupMap), null, ['-fromDate'], null, false);
-webSiteError = EntityUtil.getFirst(webSiteErrors);
+webSiteError = from("WebSiteContent").where("webSiteId", webSiteId, "webSiteContentTypeId", "ERROR_ROOT").orderBy("-fromDate").queryFirst();
 if (webSiteError) {
     error = webSiteError.getRelatedOne("Content", false);
     errorRoot = error.contentId;
@@ -59,6 +52,6 @@
     context.errorRoot = errorRoot;
 
     // get all sub content for the error root
-    errors = delegator.findList("ContentAssoc", EntityCondition.makeCondition([contentId : errorRoot]), null, null, null, false);
+    errors = from("ContentAssoc").where("contentId", errorRoot).queryList();
     context.errors = errors;
 }
diff --git a/applications/content/webapp/content/fonts.fo.ftl b/applications/content/webapp/content/fonts.fo.ftl
index feb1733..de23a94 100644
--- a/applications/content/webapp/content/fonts.fo.ftl
+++ b/applications/content/webapp/content/fonts.fo.ftl
@@ -1302,17 +1302,281 @@
 </fo:table-body>
 </fo:table>
   </fo:block>
+  
+  
+  <fo:block font-family="Helvetica"  font-size="14pt">
+NotoSans
+  </fo:block>
+  <fo:block space-after.optimum="10pt" font-family="NotoSans" font-size="10pt">
+<fo:table>
+<fo:table-column column-width="65pt"/>
+<fo:table-column column-width="30pt"/>
+<fo:table-column column-width="65pt"/>
+<fo:table-column column-width="30pt"/>
+<fo:table-column column-width="65pt"/>
+<fo:table-column column-width="30pt"/>
+<fo:table-column column-width="65pt"/>
+<fo:table-body>
+<fo:table-row>
+<fo:table-cell>
+  <fo:block>
+&amp;#x21; : &#x21;
+&amp;#x22; : &#x22;
+&amp;#x23; : &#x23;
+&amp;#x24; : &#x24;
+&amp;#x25; : &#x25;
+&amp;#x26; : &#x26;
+&amp;#x27; : &#x27;
+&amp;#x28; : &#x28;
+&amp;#x29; : &#x29;
+&amp;#x2A; : &#x2A;
+&amp;#x2B; : &#x2B;
+&amp;#x2C; : &#x2C;
+&amp;#x2D; : &#x2D;
+&amp;#x2E; : &#x2E;
+&amp;#x2F; : &#x2F;
+&amp;#x30; : &#x30;
+&amp;#x31; : &#x31;
+&amp;#x32; : &#x32;
+&amp;#x33; : &#x33;
+&amp;#x34; : &#x34;
+&amp;#x35; : &#x35;
+&amp;#x36; : &#x36;
+&amp;#x37; : &#x37;
+&amp;#x38; : &#x38;
+&amp;#x39; : &#x39;
+&amp;#x3A; : &#x3A;
+&amp;#x3B; : &#x3B;
+&amp;#x3C; : &#x3C;
+&amp;#x3D; : &#x3D;
+&amp;#x3E; : &#x3E;
+&amp;#x3F; : &#x3F;
+&amp;#x40; : &#x40;
+&amp;#x41; : &#x41;
+&amp;#x42; : &#x42;
+&amp;#x43; : &#x43;
+&amp;#x44; : &#x44;
+&amp;#x45; : &#x45;
+&amp;#x46; : &#x46;
+&amp;#x47; : &#x47;
+&amp;#x48; : &#x48;
+&amp;#x49; : &#x49;
+&amp;#x4A; : &#x4A;
+&amp;#x4B; : &#x4B;
+&amp;#x4C; : &#x4C;
+&amp;#x4D; : &#x4D;
+&amp;#x4E; : &#x4E;
+&amp;#x4F; : &#x4F;
+&amp;#x50; : &#x50;
+&amp;#x51; : &#x51;
+&amp;#x52; : &#x52;
+&amp;#x53; : &#x53;
+&amp;#x54; : &#x54;
+&amp;#x55; : &#x55;
+  </fo:block>
+</fo:table-cell>
+<fo:table-cell>
+  <fo:block>
+  </fo:block>
+</fo:table-cell>
+<fo:table-cell>
+  <fo:block>
+&amp;#x56; : &#x56;
+&amp;#x57; : &#x57;
+&amp;#x58; : &#x58;
+&amp;#x59; : &#x59;
+&amp;#x5A; : &#x5A;
+&amp;#x5B; : &#x5B;
+&amp;#x5C; : &#x5C;
+&amp;#x5D; : &#x5D;
+&amp;#x5E; : &#x5E;
+&amp;#x5F; : &#x5F;
+&amp;#x60; : &#x60;
+&amp;#x61; : &#x61;
+&amp;#x62; : &#x62;
+&amp;#x63; : &#x63;
+&amp;#x64; : &#x64;
+&amp;#x65; : &#x65;
+&amp;#x66; : &#x66;
+&amp;#x67; : &#x67;
+&amp;#x68; : &#x68;
+&amp;#x69; : &#x69;
+&amp;#x6A; : &#x6A;
+&amp;#x6B; : &#x6B;
+&amp;#x6C; : &#x6C;
+&amp;#x6D; : &#x6D;
+&amp;#x6E; : &#x6E;
+&amp;#x6F; : &#x6F;
+&amp;#x70; : &#x70;
+&amp;#x71; : &#x71;
+&amp;#x72; : &#x72;
+&amp;#x73; : &#x73;
+&amp;#x74; : &#x74;
+&amp;#x75; : &#x75;
+&amp;#x76; : &#x76;
+&amp;#x77; : &#x77;
+&amp;#x78; : &#x78;
+&amp;#x79; : &#x79;
+&amp;#x7A; : &#x7A;
+&amp;#x7B; : &#x7B;
+&amp;#x7C; : &#x7C;
+&amp;#x7D; : &#x7D;
+&amp;#x7E; : &#x7E;
+&amp;#xA1; : &#xA1;
+&amp;#xA2; : &#xA2;
+&amp;#xA3; : &#xA3;
+&amp;#xA4; : &#xA4;
+&amp;#xA5; : &#xA5;
+&amp;#xA6; : &#xA6;
+&amp;#xA7; : &#xA7;
+&amp;#xA8; : &#xA8;
+&amp;#xA9; : &#xA9;
+&amp;#xAA; : &#xAA;
+&amp;#xAB; : &#xAB;
+&amp;#xAC; : &#xAC;
+  </fo:block>
+</fo:table-cell>
+<fo:table-cell>
+  <fo:block>
+  </fo:block>
+</fo:table-cell>
+<fo:table-cell>
+  <fo:block>
+&amp;#xAE; : &#xAE;
+&amp;#xAF; : &#xAF;
+&amp;#xB0; : &#xB0;
+&amp;#xB1; : &#xB1;
+&amp;#xB2; : &#xB2;
+&amp;#xB3; : &#xB3;
+&amp;#xB4; : &#xB4;
+&amp;#xB5; : &#xB5;
+&amp;#xB6; : &#xB6;
+&amp;#xB7; : &#xB7;
+&amp;#xB8; : &#xB8;
+&amp;#xB9; : &#xB9;
+&amp;#xBA; : &#xBA;
+&amp;#xBB; : &#xBB;
+&amp;#xBC; : &#xBC;
+&amp;#xBD; : &#xBD;
+&amp;#xBE; : &#xBE;
+&amp;#xBF; : &#xBF;
+&amp;#xC0; : &#xC0;
+&amp;#xC1; : &#xC1;
+&amp;#xC2; : &#xC2;
+&amp;#xC3; : &#xC3;
+&amp;#xC4; : &#xC4;
+&amp;#xC5; : &#xC5;
+&amp;#xC6; : &#xC6;
+&amp;#xC7; : &#xC7;
+&amp;#xC8; : &#xC8;
+&amp;#xC9; : &#xC9;
+&amp;#xCA; : &#xCA;
+&amp;#xCB; : &#xCB;
+&amp;#xCC; : &#xCC;
+&amp;#xCD; : &#xCD;
+&amp;#xCE; : &#xCE;
+&amp;#xCF; : &#xCF;
+&amp;#xD0; : &#xD0;
+&amp;#xD1; : &#xD1;
+&amp;#xD2; : &#xD2;
+&amp;#xD3; : &#xD3;
+&amp;#xD4; : &#xD4;
+&amp;#xD5; : &#xD5;
+&amp;#xD6; : &#xD6;
+&amp;#xD7; : &#xD7;
+&amp;#xD8; : &#xD8;
+&amp;#xD9; : &#xD9;
+&amp;#xDA; : &#xDA;
+&amp;#xDB; : &#xDB;
+&amp;#xDC; : &#xDC;
+&amp;#xDD; : &#xDD;
+&amp;#xDE; : &#xDE;
+&amp;#xDF; : &#xDF;
+&amp;#xE0; : &#xE0;
+&amp;#xE1; : &#xE1;
+&amp;#xE2; : &#xE2;
+  </fo:block>
+</fo:table-cell>
+<fo:table-cell>
+  <fo:block>
+  </fo:block>
+</fo:table-cell>
+<fo:table-cell>
+  <fo:block>
+&amp;#xE3; : &#xE3;
+&amp;#xE4; : &#xE4;
+&amp;#xE5; : &#xE5;
+&amp;#xE6; : &#xE6;
+&amp;#xE7; : &#xE7;
+&amp;#xE8; : &#xE8;
+&amp;#xE9; : &#xE9;
+&amp;#xEA; : &#xEA;
+&amp;#xEB; : &#xEB;
+&amp;#xEC; : &#xEC;
+&amp;#xED; : &#xED;
+&amp;#xEE; : &#xEE;
+&amp;#xEF; : &#xEF;
+&amp;#xF0; : &#xF0;
+&amp;#xF1; : &#xF1;
+&amp;#xF2; : &#xF2;
+&amp;#xF3; : &#xF3;
+&amp;#xF4; : &#xF4;
+&amp;#xF5; : &#xF5;
+&amp;#xF6; : &#xF6;
+&amp;#xF7; : &#xF7;
+&amp;#xF8; : &#xF8;
+&amp;#xF9; : &#xF9;
+&amp;#xFA; : &#xFA;
+&amp;#xFB; : &#xFB;
+&amp;#xFC; : &#xFC;
+&amp;#xFD; : &#xFD;
+&amp;#xFE; : &#xFE;
+&amp;#xFF; : &#xFF;
+&amp;#x0152; : &#x0152;
+&amp;#x0153; : &#x0153;
+&amp;#x0160; : &#x0160;
+&amp;#x0161; : &#x0161;
+&amp;#x0178; : &#x0178;
+&amp;#x017D; : &#x017D;
+&amp;#x017E; : &#x017E;
+&amp;#x0192; : &#x0192;
+&amp;#x02DC; : &#x02DC;
+&amp;#x2013; : &#x2013;
+&amp;#x2014; : &#x2014;
+&amp;#x2018; : &#x2018;
+&amp;#x2019; : &#x2019;
+&amp;#x201A; : &#x201A;
+&amp;#x201C; : &#x201C;
+&amp;#x201D; : &#x201D;
+&amp;#x201E; : &#x201E;
+&amp;#x2020; : &#x2020;
+&amp;#x2021; : &#x2021;
+&amp;#x2022; : &#x2022;
+&amp;#x2026; : &#x2026;
+&amp;#x2030; : &#x2030;
+&amp;#x2039; : &#x2039;
+&amp;#x203A; : &#x203A;
+&amp;#x2122; : &#x2122;
+  </fo:block>
+</fo:table-cell>
+</fo:table-row>
+</fo:table-body>
+</fo:table>
+  </fo:block>
 
+  
+
+  <fo:block font-family="Helvetica" font-size="12pt">
+Some special characters:
+  </fo:block>
   <fo:block font-family="Helvetica"  font-size="12pt">
- Some special characters:
+Euro symbol in Helvetica 12 ( dec 8364, hex 20AC): &#x20AC;
   </fo:block>
-  <fo:block space-after.optimum="10pt" font-family="Helvetica">
-Euro ( dec 8364, hex 20AC): &#x20AC;
+  <fo:block font-family="NotoSans"  font-size="12pt">
+Ruppe symbol in NotoSans 12 (dec 8377, hex 20B9): &#x20B9;
   </fo:block>
-
-
-  <fo:block space-after.optimum="10pt" font-family="Helvetica">
-
+  <fo:block font-family="NotoSans"  font-size="12pt">
+I &#x2665; NotoSans!
   </fo:block>
 
 </fo:flow>
diff --git a/applications/content/widget/LookupForms.xml b/applications/content/widget/LookupForms.xml
index 6b35c30..ae4088c 100644
--- a/applications/content/widget/LookupForms.xml
+++ b/applications/content/widget/LookupForms.xml
@@ -38,7 +38,7 @@
 
     <form name="lookupDataResourceContent" default-entity-name="DataResourceContentView" target="LookupSubContent" title="" type="single"
         header-row-style="header-row" default-table-style="basic-table">
-        <field name="dataResourceId">
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}">
             <text-find/>
         </field>
         <field name="coContentId">
diff --git a/applications/content/widget/cms/CMSForms.xml b/applications/content/widget/cms/CMSForms.xml
index 69d2321..7950b5c 100644
--- a/applications/content/widget/cms/CMSForms.xml
+++ b/applications/content/widget/cms/CMSForms.xml
@@ -27,7 +27,7 @@
         <field name="caContentAssocTypeId"><text-find/></field>
         <field name="caFromDate" title="${uiLabelMap.CommonFromDate}"><date-find/></field>
         <field name="contentId"><text-find/></field>
-        <field name="dataResourceId"><text-find/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><text-find/></field>
         <field name="contentName"><text-find/></field>
         <field name="submitButton" title="${uiLabelMap.CommonFind}" widget-style="smallSubmit"><submit button-type="button"/></field>
     </form>
@@ -68,7 +68,7 @@
         <field name="caMapKey"><display/></field>
         <field name="caFromDate" title="${uiLabelMap.CommonFromDate}"><display/></field>
         <field name="contentId"><display/></field>
-        <field name="dataResourceId"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><display/></field>
         <field name="contentName"><display/></field>
     </form>
 
@@ -77,7 +77,7 @@
         <field name="imageData" >
             <file />
         </field>
-        <field name="dataResourceId" >
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" >
             <drop-down allow-empty="false" no-current-selected-key="TEMPLATE_TEXT_ONLY">
                 <option key="TEMPLATE_TEXT_ONLY" description="${uiLabelMap.ContentTemplateTextOnly}"/>
                 <option key="TEMPLATE_IMAGE_CENTERED" description="${uiLabelMap.ContentTemplateImageCentered}"/>
@@ -498,7 +498,7 @@
         <field name="dataResourceTitle" title-style="h1" map-name="dummy">
             <display description=""/>
         </field>
-        <field name="dataResourceId">
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}">
             <lookup target-form-name="LookupDataResource">
             <sub-hyperlink use-when="&quot;${currentValue.dataResourceId}&quot;.length()>0" link-style="buttontext" target-type="intra-app" target="gotoDataResource" description="${uiLabelMap.ContentGoToDataResource}">
                 <parameter param-name="dataResourceId" from-field="currentValue.dataResourceId"/>
diff --git a/applications/content/widget/compdoc/CompDocTemplateTree.xml b/applications/content/widget/compdoc/CompDocTemplateTree.xml
index 9057c3a..87c76ca 100644
--- a/applications/content/widget/compdoc/CompDocTemplateTree.xml
+++ b/applications/content/widget/compdoc/CompDocTemplateTree.xml
@@ -19,7 +19,7 @@
 -->
 <trees xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/widget-tree.xsd">
-    <tree name="CompDocTemplateTree" root-node-name="node-root"
+    <tree name="CompDocTemplateTree" entity-name="Content" root-node-name="node-root"
         default-render-style="simple" default-wrap-style="treeWrapper">
         <node name="node-root" wrap-style="treeWrapper">
             <entity-one entity-name="Content" use-cache="false">
@@ -87,7 +87,7 @@
         </node>
     </tree>
 
-    <tree name="CompDocInstanceTree" root-node-name="node-root"
+    <tree name="CompDocInstanceTree" entity-name="Content" root-node-name="node-root"
         default-render-style="simple" default-wrap-style="treeWrapper">
         <node name="node-root">
             <entity-one entity-name="Content" use-cache="false">
diff --git a/applications/content/widget/content/ContentForms.xml b/applications/content/widget/content/ContentForms.xml
index 6f9cada..7375ad9 100644
--- a/applications/content/widget/content/ContentForms.xml
+++ b/applications/content/widget/content/ContentForms.xml
@@ -42,7 +42,7 @@
                 </entity-options>
             </drop-down>
         </field>
-        <field name="dataResourceId" position="1">
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" position="1">
             <lookup target-form-name="LookupDataResource"/>
         </field>
         <field name="ownerContentId" position="2">
@@ -95,8 +95,8 @@
         <field name="localeString" sort-field="true"><display-entity entity-name="CountryCode" key-field-name="countryCode" description="${countryName}[${countryCode}]"></display-entity></field>
         <field name="contentTypeId" sort-field="true"><display-entity entity-name="ContentType"></display-entity></field>
         <field name="mimeTypeId" sort-field="true"><display-entity entity-name="MimeType"></display-entity></field>
-        <field name="dataResourceId" use-when="dataResourceId==null" sort-field="true"><display/></field>
-        <field name="dataResourceId" use-when="dataResourceId!=null" sort-field="true">
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" use-when="dataResourceId==null" sort-field="true"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" use-when="dataResourceId!=null" sort-field="true">
             <display-entity entity-name="DataResource" description="${dataResourceName}">
                 <sub-hyperlink target="EditDataResource" link-style="buttontext" description="[${dataResourceId}]">
                     <parameter param-name="dataResourceId"/>
@@ -151,14 +151,14 @@
                 </entity-options>
             </drop-down>
         </field>
-        <field name="dataResourceId" use-when="dataResourceId != null">
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" use-when="dataResourceId != null">
             <lookup target-form-name="LookupDataResource">
                 <sub-hyperlink link-style="buttontext" target="EditDataResource" description="${uiLabelMap.ContentGoToDataResource}">
                     <parameter param-name="dataResourceId" from-field="currentValue.dataResourceId"/>
                 </sub-hyperlink>
             </lookup>
         </field>
-        <field name="dataResourceId" use-when="dataResourceId == null ">
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" use-when="dataResourceId == null ">
             <lookup target-form-name="LookupDataResource">
                 <sub-hyperlink link-style="buttontext" target="AddDataResourceFromContent" description="${uiLabelMap.FormFieldTitle_newDataResourceId}">
                     <parameter param-name="contentId" from-field="currentValue.contentId"/>
diff --git a/applications/content/widget/content/DataResourceForms.xml b/applications/content/widget/content/DataResourceForms.xml
index c25f30e..06f29a0 100644
--- a/applications/content/widget/content/DataResourceForms.xml
+++ b/applications/content/widget/content/DataResourceForms.xml
@@ -24,7 +24,7 @@
     <form name="FindDataResource" target="findDataResource" type="single"
         header-row-style="header-row" default-table-style="basic-table">
         <field name="noConditionFind"><hidden value="Y"/><!-- if this isn't there then with all fields empty no query will be done --></field>
-        <field name="dataResourceId"><text-find ignore-case="true"/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><text-find ignore-case="true"/></field>
         <field name="dataResourceName"><text-find ignore-case="true"/></field>
         <field name="dataResourceTypeId">
             <drop-down allow-empty="true">
@@ -140,7 +140,7 @@
                 <field-map field-name="viewSize" from-field="viewSize"/>
             </service>
         </actions>
-        <field name="dataResourceId">
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}">
             <hyperlink also-hidden="false" target-type="plain" description="${dataResourceId}" target="javascript:set_value('${dataResourceId}')"/>
         </field>
         <field name="dataResourceName"><display/></field>
@@ -238,7 +238,7 @@
     <form name="DataResourceMaster" target="createDataResource" title="" type="single" default-map-name="currentValue"
         header-row-style="header-row" default-table-style="basic-table">
         <auto-fields-entity entity-name="DataResource" default-field-type="edit"/>
-        <field name="dataResourceId"></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"></field>
         <field name="dataResourceTypeId">
             <drop-down allow-empty="true">
                 <entity-options description="${description}" entity-name="DataResourceType" key-field-name="dataResourceTypeId"/>
@@ -287,14 +287,14 @@
 -->
     <form name="AddDataResource" target="createDataResource" title="" type="single" extends="DataResourceMaster"
         header-row-style="header-row" default-table-style="basic-table">
-        <field name="dataResourceId"><text/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><text/></field>
         <field name="submitButton" title="${uiLabelMap.CommonCreate}" widget-style="smallSubmit"><submit button-type="button"/></field>
         <field name="objectInfo" title="${uiLabelMap.ContentUrl}"/>
         <field name="mode"><hidden value="CREATE"/></field>
     </form>
     <form name="AddDataResourceText" target="createDataResourceAndText" title="" type="single" extends="DataResourceMaster"
         header-row-style="header-row" default-table-style="basic-table">
-        <field name="dataResourceId"><text/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><text/></field>
         <field name="dataResourceTypeId"><hidden value="ELECTRONIC_TEXT"/></field>
         <field name="dataResourceTypeIdDisplay" title="${uiLabelMap.CommonType}" field-name="dataResourceTypeId">
             <display description="ELECTRONIC_TEXT" also-hidden="false"/>
@@ -304,7 +304,7 @@
     </form>
     <form name="AddDataResourceUrl" target="createDataResourceUrl" title="" type="single" extends="DataResourceMaster"
         header-row-style="header-row" default-table-style="basic-table">
-        <field name="dataResourceId"><text/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><text/></field>
         <field name="objectInfo" title="${uiLabelMap.ContentUrl}"><text/></field>
         <field name="dataResourceTypeId"><hidden value="URL_RESOURCE"/></field>
         <field name="dataResourceTypeIdDisplay" title="${uiLabelMap.CommonType}" field-name="dataResourceTypeId">
@@ -348,17 +348,17 @@
     </form>
     <form name="ImageUpload" target="uploadImage" title="" type="upload"  default-map-name="currentValue"
         header-row-style="header-row" default-table-style="basic-table">
-        <field name="dataResourceId"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><display/></field>
         <field name="dataResourceTypeId" ><hidden/></field>
-        <field name="objectInfo"><display /></field>
-        <field name="imageData" entity-name="ImageDataResource"><file/></field>
+        <field name="objectInfo" title="${uiLabelMap.ContentUploadedFile}"><display /></field>
+        <field name="imageData" entity-name="ImageDataResource" title="${uiLabelMap.ContentFile}"><file/></field>
         <field name="submitButton" title="${uiLabelMap.CommonUpload}" widget-style="smallSubmit"><submit button-type="button"/></field>
     </form>
     <!-- DataResourceAttribute forms -->
     <form name="AddDataResourceAttribute" target="addDataResourceAttribute" title="" type="single"
         header-row-style="header-row" default-table-style="basic-table">
         <auto-fields-service service-name="createDataResourceAttribute"/>
-        <field name="dataResourceId" title=" " map-name="currentValue"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" map-name="currentValue"><display/></field>
         <field name="submitButton" title="${uiLabelMap.CommonAdd}" widget-style="smallSubmit"><submit button-type="button"/></field>
     </form>
     <form name="ListDataResourceAttribute" list-name="dataResourceAttribute" target="updateDataResourceAttribute" title="" type="list"
@@ -386,7 +386,7 @@
     <form name="AddDataResourceRole" target="addDataResourceRole" title="" type="single"
         header-row-style="header-row" default-table-style="basic-table">
         <auto-fields-entity entity-name="DataResourceRole"/>
-        <field name="dataResourceId" title=" " map-name="currentValue"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" map-name="currentValue"><display/></field>
         <field name="partyId" title=" "><lookup target-form-name="LookupPerson"/></field>
         <field name="roleTypeId">
             <drop-down allow-empty="true">
@@ -422,7 +422,7 @@
     <form name="AddDataResourceProductFeature" target="createDataResourceProductFeature" title="" type="single"
         header-row-style="header-row" default-table-style="basic-table">
         <auto-fields-service service-name="createProductFeatureDataResource"/>
-        <field name="dataResourceId" map-name="currentValue"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" map-name="currentValue"><display/></field>
         <field name="productFeatureId" widget-style="buttontext"><lookup target-form-name="LookupProductFeature"/></field>
         <field name="submitButton" title="${uiLabelMap.CommonAdd}" widget-style="smallSubmit"><submit button-type="button"/></field>
     </form>
@@ -487,7 +487,7 @@
             <entity-one entity-name="ElectronicText" value-field="electronicText"/>
         </actions>
         <alt-target use-when="electronicText==null" target="addElectronicText"/>
-        <field name="dataResourceId" title=" " widget-style="buttontext"><display also-hidden="true"/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" widget-style="buttontext"><display also-hidden="true"/></field>
         <field name="textData" widget-style="buttontext"><textarea cols="120" rows="24"/></field>
         <field name="submitButton"  use-when="electronicText!=null" title="${uiLabelMap.CommonUpdate}" widget-style="smallSubmit"><submit button-type="button"/></field>
         <field name="submitButton" use-when="electronicText==null" title="${uiLabelMap.CommonAdd}" widget-style="smallSubmit"><submit button-type="button"/></field>
@@ -497,7 +497,7 @@
     <form name="AddHtmlText" target="addHtmlText" title="" type="single"
         header-row-style="header-row" default-table-style="basic-table">
         <auto-fields-entity entity-name="ElectronicText"/>
-        <field name="dataResourceId" title=" " widget-style="buttontext" map-name="currentValue"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" widget-style="buttontext" map-name="currentValue"><display/></field>
         <field name="textData" id-name="textData"><textarea rows="24" cols="120"/></field>
         <field name="submitButton" title="${uiLabelMap.CommonAdd}" widget-style="smallSubmit"><submit button-type="button"/></field>
     </form>
@@ -508,7 +508,7 @@
         </actions>
         <alt-target use-when="electronicText==null" target="addHtmlText"/>
         <auto-fields-entity entity-name="ElectronicText"/>
-        <field name="dataResourceId" title=" " widget-style="buttontext"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" widget-style="buttontext"><display/></field>
         <field name="textData" id-name="textData" encode-output="true"><textarea cols="120" rows="20" visual-editor-enable="true" /></field>
         <field name="submitButton" title="${uiLabelMap.CommonUpdate}" widget-style="smallSubmit"><submit button-type="button"/></field>
     </form>
diff --git a/applications/content/widget/content/DataResourceScreens.xml b/applications/content/widget/content/DataResourceScreens.xml
index 499c9d0..61f09ce 100644
--- a/applications/content/widget/content/DataResourceScreens.xml
+++ b/applications/content/widget/content/DataResourceScreens.xml
@@ -214,8 +214,15 @@
                 <decorator-screen name="commonDataResourceDecorator" location="${parameters.mainDecoratorLocation}">
                     <decorator-section name="body">
                         <include-form name="ImageUpload" location="component://content/widget/content/DataResourceForms.xml"/>
-                        <content dataresource-id="${currentValue.dataResourceId}" border="false"/>
-                    </decorator-section>
+                        <!-- Commented out the following snippet because the behaviour is too random (does not depend on browser)-->
+<!--                        <content dataresource-id="${currentValue.dataResourceId}" border="false"/>
+                        <horizontal-separator></horizontal-separator>
+                        <label>${uiLabelMap.ContentContentShow}:</label>
+                        <container>
+                            <content dataresource-id="${currentValue.dataResourceId}" border="false"/>
+                            <horizontal-separator></horizontal-separator>
+                        </container>
+-->                    </decorator-section>
                 </decorator-screen>
             </widgets>
         </section>
diff --git a/applications/content/widget/forum/ForumTrees.xml b/applications/content/widget/forum/ForumTrees.xml
index 4603e30..020b286 100644
--- a/applications/content/widget/forum/ForumTrees.xml
+++ b/applications/content/widget/forum/ForumTrees.xml
@@ -23,7 +23,7 @@
 
 <!--    <tree name="MessageTree" root-node-name="node-root"
         default-render-style="expand-collapse" expand-collapse-request="findForumThreads?forumId=${parameters.forumId}"> -->
-    <tree name="MessageTree" root-node-name="node-root" default-render-style="simple">
+    <tree name="MessageTree" entity-name="Content" root-node-name="node-root" default-render-style="simple">
         <node name="node-root">
             <entity-one entity-name="Content" use-cache="false" value-field="rsp">
                 <field-map field-name="contentId" from-field="parameters.forumId"/>
diff --git a/applications/content/widget/website/WebSiteForms.xml b/applications/content/widget/website/WebSiteForms.xml
index b53dfb8..e22bb54 100644
--- a/applications/content/widget/website/WebSiteForms.xml
+++ b/applications/content/widget/website/WebSiteForms.xml
@@ -153,7 +153,7 @@
             <sort-field name="deleteLink"/>
         </sort-order>
     </form>
-    <form name="CreateWebSiteContent" type="single" target="CreateWebSiteContent" title="" default-map-name="webSite"
+    <form name="CreateWebSiteContent" type="single" target="CreateWebSiteContent" title=""
         header-row-style="header-row" default-table-style="basic-table">
         <auto-fields-service service-name="createWebSiteContent"/>
         <field name="webSiteId" map-name="webSite"><display also-hidden="true"/></field>
@@ -291,4 +291,4 @@
             </hyperlink>
         </field>
     </form>
-</forms>
\ No newline at end of file
+</forms>
diff --git a/applications/humanres/webapp/humanres/WEB-INF/actions/category/CategoryTree.groovy b/applications/humanres/webapp/humanres/WEB-INF/actions/category/CategoryTree.groovy
index 266a80a..f893074 100644
--- a/applications/humanres/webapp/humanres/WEB-INF/actions/category/CategoryTree.groovy
+++ b/applications/humanres/webapp/humanres/WEB-INF/actions/category/CategoryTree.groovy
@@ -23,6 +23,7 @@
  */
 import org.ofbiz.entity.util.EntityUtil;
 import org.ofbiz.base.util.*;
+import org.ofbiz.party.party.PartyHelper;
 import org.ofbiz.product.catalog.*;
 import org.ofbiz.product.category.*;
 import javolution.util.FastMap;
@@ -41,20 +42,19 @@
 subtopLists =  FastList.newInstance();
 
 //internalOrg list
-partyRelationships = EntityUtil.filterByDate(delegator.findByAnd("PartyRelationship", [partyIdFrom : partyId, partyRelationshipTypeId : "GROUP_ROLLUP"], null, false));
+partyRelationships = from("PartyRelationship").where("partyIdFrom", partyId, "partyRelationshipTypeId", "GROUP_ROLLUP").filterByDate().queryList();
 if (partyRelationships) {
     //root
-    partyRoot = delegator.findOne("PartyGroup", [partyId : partyId], false);
+    partyRoot = from("PartyGroup").where("partyId", partyId).queryOne();
     partyRootMap = FastMap.newInstance();
     partyRootMap.put("partyId", partyId);
     partyRootMap.put("groupName", partyRoot.getString("groupName"));
 
     //child
     for(partyRelationship in partyRelationships) {
-        partyGroup = delegator.findOne("PartyGroup", [partyId : partyRelationship.getString("partyIdTo")], false);
-        partyGroupMap = FastMap.newInstance();
-        partyGroupMap.put("partyId", partyGroup.getString("partyId"));
-        partyGroupMap.put("groupName", partyGroup.getString("groupName"));
+        partyGroupMap = [:];
+        partyGroupMap.put("partyId", partyRelationship.getString("partyIdTo"));
+        partyGroupMap.put("groupName", PartyHelper.getPartyName(delegator, partyRelationship.getString("partyIdTo"), false));
         completedTreeContext.add(partyGroupMap);
 
         subtopLists.addAll(partyRelationship.getString("partyIdTo"));
diff --git a/applications/humanres/widget/PersonTrainingScreens.xml b/applications/humanres/widget/PersonTrainingScreens.xml
index 14d5397..ec71bc2 100644
--- a/applications/humanres/widget/PersonTrainingScreens.xml
+++ b/applications/humanres/widget/PersonTrainingScreens.xml
@@ -139,7 +139,7 @@
                                     <if-compare field="workEffort.currentStatusId" operator="not-equals" value="CAL_CANCELLED"/>
                                 </and>
                                 <if-empty field="workEffort"/>
-                                <if-has-permission permission="WORKEFFORTMGR" action="ADMIN"/>
+                                <if-has-permission permission="WORKEFFORTMGR" action="_ADMIN"/>
                             </or>
                             <if-compare field="parameters.form" operator="equals" value="edit"/>
                         </and>
diff --git a/applications/manufacturing/config/ManufacturingUiLabels.xml b/applications/manufacturing/config/ManufacturingUiLabels.xml
index c555570..9da0b82 100644
--- a/applications/manufacturing/config/ManufacturingUiLabels.xml
+++ b/applications/manufacturing/config/ManufacturingUiLabels.xml
@@ -1630,7 +1630,7 @@
         <value xml:lang="de">Abhängige Produktionsaufträge</value>
         <value xml:lang="en">Succeeding Production Run(s)</value>
         <value xml:lang="es">Esfuerzos de trabajo dependientes</value>
-        <value xml:lang="fr">Exécution de production dépendantes</value>
+        <value xml:lang="fr">Exécution d'ordre de fabrication/s suivant/s</value>
         <value xml:lang="it">Ordini di produzione successivi</value>
         <value xml:lang="ja">依存する生産実行</value>
         <value xml:lang="nl">Opvolgende productierun(s)</value>
@@ -2675,7 +2675,7 @@
         <value xml:lang="de">Erforderliche Produktionsaufträge</value>
         <value xml:lang="en">Preceding Production Run(s)</value>
         <value xml:lang="es">Órdenes de producción obligatorias</value>
-        <value xml:lang="fr">Cadences de production obligatoires</value>
+        <value xml:lang="fr">Exécution d'ordre de fabrication/s précédent/s</value>
         <value xml:lang="it">Cicli Produzione Precedenti</value>
         <value xml:lang="ja">生産強制実行</value>
         <value xml:lang="nl">Voorafgaande productierun(s)</value>
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/bom/BomSimulation.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/bom/BomSimulation.groovy
index 0973671..27491ea 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/bom/BomSimulation.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/bom/BomSimulation.groovy
@@ -44,7 +44,7 @@
         try {
             outMap = [:];
             if (currencyUomId) {
-                outMap = dispatcher.runSync("getProductCost", [productId : node.getProduct().productId,
+                outMap = runService('getProductCost', [productId : node.getProduct().productId,
                                                                              currencyUomId : currencyUomId,
                                                                              costComponentTypePrefix : "EST_STD",
                                                                              userLogin : userLogin]);
@@ -53,7 +53,7 @@
                 grandTotalCost = grandTotalCost + totalCost ?: 0;
             }
             if (facilityId) {
-                outMap = dispatcher.runSync("getInventoryAvailableByFacility", [productId : node.getProduct().productId,
+                outMap = runService('getInventoryAvailableByFacility', [productId : node.getProduct().productId,
                                                                                               facilityId : facilityId,
                                                                                               userLogin : userLogin]);
                 qoh = outMap.quantityOnHandTotal;
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/bom/EditProductBom.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/bom/EditProductBom.groovy
index 3c4a481..d2ec5a2 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/bom/EditProductBom.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/bom/EditProductBom.groovy
@@ -44,7 +44,7 @@
 if (fromDateStr) fromDate = Timestamp.valueOf(fromDateStr) ?: (Timestamp)request.getAttribute("ProductAssocCreateFromDate");;
 context.fromDate = fromDate;
 
-productAssoc = delegator.findOne("ProductAssoc", [productId : productId, productIdTo : productIdTo, productAssocTypeId : productAssocTypeId, fromDate : fromDate], false);
+productAssoc = from("ProductAssoc").where("productId", productId, "productIdTo", productIdTo, "productAssocTypeId", productAssocTypeId, "fromDate", fromDate).queryOne();
 if (updateMode) {
     productAssoc = [:];
     context.remove("productIdTo");
@@ -58,10 +58,10 @@
 
 context.useValues = useValues;
 
-Collection assocTypes = delegator.findByAnd("ProductAssocType", [parentTypeId : "PRODUCT_COMPONENT"], ["productAssocTypeId", "description"], false);
+Collection assocTypes = from("ProductAssocType").where("parentTypeId", "PRODUCT_COMPONENT").orderBy("productAssocTypeId", "description").queryList();
 context.assocTypes = assocTypes;
 
-Collection formulae = delegator.findByAnd("CustomMethod", [customMethodTypeId : "BOM_FORMULA"], ["customMethodId", "description"], false);
+Collection formulae = from("CustomMethod").where("customMethodTypeId", "BOM_FORMULA").orderBy("customMethodId", "description").queryList();
 context.formulae = formulae;
 
 if (product) {
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/bom/FindProductBom.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/bom/FindProductBom.groovy
index 12ce26b..79fbd80 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/bom/FindProductBom.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/bom/FindProductBom.groovy
@@ -20,9 +20,6 @@
 import org.ofbiz.entity.util.*;
 import org.ofbiz.entity.condition.*;
 
-fieldToSelect = ["productId", "internalName", "productAssocTypeId"] as Set;
-orderBy = ["productId", "productAssocTypeId"];
-
 condList = [];
 if (parameters.productId) {
     cond = EntityCondition.makeCondition("productId", EntityOperator.EQUALS, parameters.productId);
@@ -41,8 +38,12 @@
                                           ], EntityOperator.OR);
     condList.add(cond);
 }
-cond =  EntityCondition.makeCondition(condList, EntityOperator.AND);
-findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
-bomListIterator = delegator.find("ProductAndAssoc", cond, null, fieldToSelect, orderBy, findOpts);
+bomListIterator = select("productId", "internalName", "productAssocTypeId")
+                    .from("ProductAndAssoc")
+                    .where(condList)
+                    .orderBy("productId", "productAssocTypeId")
+                    .cursorScrollInsensitive()
+                    .cache(true)
+                    .queryIterator();
 
 context.ListProductBom = bomListIterator;
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 c1deccd..49e6897 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunActualComponents.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunActualComponents.groovy
@@ -22,9 +22,9 @@
 productionRunId = parameters.productionRunId ?: parameters.workEffortId;
 
 taskInfos = [];
-tasks = delegator.findByAnd("WorkEffort", [workEffortParentId : productionRunId, workEffortTypeId : "PROD_ORDER_TASK"], ["workEffortId"], false);
+tasks = from("WorkEffort").where("workEffortParentId", productionRunId, "workEffortTypeId", "PROD_ORDER_TASK").orderBy("workEffortId").queryList();
 tasks.each { task ->
-    records = delegator.findByAnd("InventoryItemDetail", [workEffortId : task.workEffortId], null, false);
+    records = from("InventoryItemDetail").where("workEffortId", task.workEffortId).queryList();
     HtmlFormWrapper taskForm = new HtmlFormWrapper("component://manufacturing/widget/manufacturing/ProductionRunForms.xml", "ProductionRunTaskActualComponents", request, response);
     taskForm.putInContext("records", records);
     taskInfos.add([task : task, taskForm : taskForm]);
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 fb1cf06..8bc5a50 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunComponents.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunComponents.groovy
@@ -22,9 +22,9 @@
 productionRunId = parameters.productionRunId ?: parameters.workEffortId;
 
 taskInfos = [];
-tasks = delegator.findByAnd("WorkEffort", [workEffortParentId : productionRunId, workEffortTypeId : "PROD_ORDER_TASK"], ["workEffortId"], false);
+tasks = from("WorkEffort").where("workEffortParentId", productionRunId, "workEffortTypeId", "PROD_ORDER_TASK").orderBy("workEffortId").queryList();
 tasks.each { task ->
-    records = delegator.findByAnd("WorkEffortGoodStandard", [workEffortId : task.workEffortId], null, false);
+    records = from("WorkEffortGoodStandard").where("workEffortId", task.workEffortId).queryList();
     HtmlFormWrapper taskForm = new HtmlFormWrapper("component://manufacturing/widget/manufacturing/ProductionRunForms.xml", "ProductionRunTaskComponents", request, response);
     taskForm.putInContext("records", records);
     taskInfos.add([task : task, taskForm : taskForm]);
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunContent.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunContent.groovy
index ef2b397..4ffa501 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunContent.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunContent.groovy
@@ -19,16 +19,17 @@
 
 import org.ofbiz.content.content.ContentWorker;
 import org.ofbiz.entity.util.EntityUtil;
+import org.ofbiz.entity.GenericValue;
 
 productionRunId = parameters.productionRunId ?: parameters.workEffortId;
 context.productionRunId = productionRunId;
 
-delivGoodStandard = EntityUtil.getFirst(delegator.findByAnd("WorkEffortGoodStandard", [workEffortId : productionRunId, workEffortGoodStdTypeId : "PRUN_PROD_DELIV", statusId : "WEGS_CREATED"], ["-fromDate"], false));
+delivGoodStandard = from("WorkEffortGoodStandard").where("workEffortId", productionRunId, "workEffortGoodStdTypeId", "PRUN_PROD_DELIV", "statusId", "WEGS_CREATED").orderBy("-fromDate").queryFirst();
 if (delivGoodStandard) {
     context.delivProductId = delivGoodStandard.productId;
 }
 if (context.delivProductId && (parameters.partyId || parameters.contentLocale)) {
-    delivProductContents = EntityUtil.filterByDate(delegator.findByAnd("ProductContentAndInfo", [productId : context.delivProductId], ["-fromDate"], false));
+    delivProductContents = from("ProductContentAndInfo").where("productId", context.delivProductId).orderBy("-fromDate").filterByDate().queryList();
     context.delivProductContents = delivProductContents;
 
     Locale contentLocale = null;
@@ -38,7 +39,7 @@
     delivProductContentsForLocaleAndUser = [];
     delivProductContents.each { delivProductContent ->
         GenericValue content = ContentWorker.findContentForRendering(delegator, delivProductContent.contentId, contentLocale, parameters.partyId, parameters.roleTypeId, true);
-        delivProductContentsForLocaleAndUser.add(EntityUtil.getFirst(delegator.findByAnd("ContentDataResourceView", [contentId : content.contentId], null, false)));
+        delivProductContentsForLocaleAndUser.add(from("ContentDataResourceView").where("contentId", content.contentId).queryFirst());
     }
     context.delivProductContentsForLocaleAndUser = delivProductContentsForLocaleAndUser;
 }
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 9b0680d..74d0108 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunCosts.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunCosts.groovy
@@ -22,16 +22,16 @@
 
 productionRunId = parameters.productionRunId ?: parameters.workEffortId;
 taskCosts = [];
-tasks = delegator.findByAnd("WorkEffort", [workEffortParentId : productionRunId, workEffortTypeId : "PROD_ORDER_TASK"], ["workEffortId"], false);
+tasks = from("WorkEffort").where("workEffortParentId", productionRunId, "workEffortTypeId", "PROD_ORDER_TASK").orderBy("workEffortId").queryList();
 tasks.each { task ->
-    costs = EntityUtil.filterByDate(delegator.findByAnd("CostComponent", [workEffortId : task.workEffortId], null, false));
+    costs = from("CostComponent").where("workEffortId", task.workEffortId).filterByDate().queryList();
     HtmlFormWrapper taskCostsForm = new HtmlFormWrapper("component://manufacturing/widget/manufacturing/ProductionRunForms.xml", "ProductionRunTaskCosts", request, response);
     taskCostsForm.putInContext("taskCosts", costs);
     taskCosts.add([task : task ,costsForm : taskCostsForm]);
 }
 // get the costs directly associated to the production run (e.g. overhead costs)
-productionRun = delegator.findOne("WorkEffort", [workEffortId: productionRunId], true);
-costs = EntityUtil.filterByDate(delegator.findByAnd("CostComponent", [workEffortId : productionRunId], null, false));
+productionRun = from("WorkEffort").where("workEffortId", productionRunId).cache(true).queryOne();
+costs = from("CostComponent").where("workEffortId", productionRunId).filterByDate().queryList();
 HtmlFormWrapper taskCostsForm = new HtmlFormWrapper("component://manufacturing/widget/manufacturing/ProductionRunForms.xml", "ProductionRunTaskCosts", request, response);
 taskCostsForm.putInContext("taskCosts", costs);
 taskCosts.add([task : productionRun ,costsForm : taskCostsForm]);
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 2153aae..8367e94 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunDeclaration.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunDeclaration.groovy
@@ -36,7 +36,7 @@
         context.productionRun = productionRun.getGenericValue();
 
         // Find all the order items to which this production run is linked.
-        orderItems = delegator.findByAnd("WorkOrderItemFulfillment", [workEffortId : productionRunId], null, false);
+        orderItems = from("WorkOrderItemFulfillment").where("workEffortId", productionRunId).queryList();
         if (orderItems) {
             context.orderItems = orderItems;
         }
@@ -44,7 +44,7 @@
         quantityToProduce = productionRun.getGenericValue().get("quantityToProduce") ?: 0.0;
 
         // Find the inventory items produced
-        inventoryItems = delegator.findByAnd("WorkEffortInventoryProduced", [workEffortId : productionRunId], null, false);
+        inventoryItems = from("WorkEffortInventoryProduced").where("workEffortId", productionRunId).queryList();
         context.inventoryItems = inventoryItems;
         if (inventoryItems) {
             lastWorkEffortInventoryProduced = (GenericValue)inventoryItems.get(inventoryItems.size() - 1);
@@ -95,7 +95,7 @@
         // routingTask update sub-screen
         routingTaskId = parameters.routingTaskId;
         if (routingTaskId && (actionForm.equals("UpdateRoutingTask") || actionForm.equals("EditRoutingTask"))) {
-            routingTask = delegator.findOne("WorkEffort", [workEffortId : routingTaskId], false);
+            routingTask = from("WorkEffort").where("workEffortId", routingTaskId).queryOne();
             Map routingTaskData = routingTask.getAllFields();
             routingTaskData.estimatedSetupMillis = routingTask.getDouble("estimatedSetupMillis");
             routingTaskData.estimatedMilliSeconds = routingTask.getDouble("estimatedMilliSeconds");
@@ -105,7 +105,7 @@
             // Get the list of deliverable products, i.e. the WorkEffortGoodStandard entries
             // with workEffortGoodStdTypeId = "PRUNT_PROD_DELIV":
             // first of all we get the template task (the routing task)
-            templateTaskAssoc = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("WorkEffortAssoc", [workEffortIdTo : routingTask.workEffortId, workEffortAssocTypeId : "WORK_EFF_TEMPLATE"], null, false)));
+            templateTaskAssoc = from("WorkEffortAssoc").where("workEffortIdTo", routingTask.workEffortId, "workEffortAssocTypeId", "WORK_EFF_TEMPLATE").filterByDate().queryFirst();
             templateTask = [:];
             if (templateTaskAssoc) {
                 templateTask = templateTaskAssoc.getRelatedOne("FromWorkEffort", false);
@@ -116,7 +116,7 @@
             }
             context.delivProducts = delivProducts;
             // Get the list of delivered products, i.e. inventory items
-            prunInventoryProduced = delegator.findByAnd("WorkEffortAndInventoryProduced", [workEffortId : routingTaskId], null, false);
+            prunInventoryProduced = from("WorkEffortAndInventoryProduced").where("workEffortId", routingTaskId).queryList();
             context.prunInventoryProduced = prunInventoryProduced;
         }
 
@@ -130,9 +130,8 @@
             if ("PRUN_RUNNING".equals(task.currentStatusId)) {
                 // Use WorkEffortGoodStandard to figure out if there are products which are needed for this task (PRUNT_PRODNEEDED) and which have not been issued (ie, WEGS_CREATED).
                 // If so this task should have products issued
-                components = delegator.findByAnd("WorkEffortGoodStandard", [workEffortId : task.workEffortId, workEffortGoodStdTypeId : "PRUNT_PROD_NEEDED"], null, false);
-                List notIssued = EntityUtil.filterByAnd(components, [statusId : "WEGS_CREATED"]);
-                if (components && notIssued) {
+                components = from("WorkEffortGoodStandard").where("workEffortId", task.workEffortId, "workEffortGoodStdTypeId", "PRUNT_PROD_NEEDED", "statusId", "WEGS_CREATED").queryList();
+                if (components) {
                     issueTaskId = task.workEffortId;
                 }
                 if (!issueTaskId) {
@@ -170,7 +169,7 @@
                 componentData.internalName = componentName;
                 componentData.workEffortName = workEffortName;
                 componentData.facilityId = productionRunTask.facilityId;
-                issuances = delegator.findByAnd("WorkEffortAndInventoryAssign", [workEffortId : component.workEffortId, productId : product.productId], null, false);
+                issuances = from("WorkEffortAndInventoryAssign").where("workEffortId", component.workEffortId, "productId", product.productId).queryList();
                 totalIssued = 0.0;
                 issuances.each { issuance ->
                     issued = issuance.quantity;
@@ -178,10 +177,10 @@
                         totalIssued += issued;
                     }
                 }
-                returns = delegator.findByAnd("WorkEffortAndInventoryProduced", [workEffortId : component.workEffortId , productId : product.productId], null, false);
+                returns = from("WorkEffortAndInventoryProduced").where("workEffortId", component.workEffortId , "productId", product.productId).queryList();
                 totalReturned = 0.0;
                 returns.each { returned ->
-                    returnDetail = EntityUtil.getFirst(delegator.findByAnd("InventoryItemDetail", [inventoryItemId : returned.inventoryItemId], ["inventoryItemDetailSeqId"], false));
+                    returnDetail = from("InventoryItemDetail").where("inventoryItemId", returned.inventoryItemId).orderBy("inventoryItemDetailSeqId").queryFirst();
                     if (returnDetail) {
                         qtyReturned = returnDetail.quantityOnHandDiff;
                         if (qtyReturned) {
@@ -206,7 +205,7 @@
             }
         }
         // Content
-        productionRunContents = EntityUtil.filterByDate(delegator.findByAnd("WorkEffortContentAndInfo", [workEffortId : productionRunId], ["-fromDate"], false));
+        productionRunContents = from("WorkEffortContentAndInfo").where("workEffortId", productionRunId).orderBy("-fromDate").filterByDate().queryList();
         context.productionRunContents = productionRunContents;
         context.productionRunComponentsData = productionRunComponentsData;
         context.productionRunComponentsDataReadyForIssuance = productionRunComponentsDataReadyForIssuance;
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 3475000..c1d6714 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunFixedAssets.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunFixedAssets.groovy
@@ -22,7 +22,7 @@
 productionRunId = parameters.productionRunId ?: parameters.workEffortId;
 
 taskInfos = [];
-tasks = delegator.findByAnd("WorkEffort", [workEffortParentId : productionRunId, workEffortTypeId : "PROD_ORDER_TASK"], ["workEffortId"], false);
+tasks = from("WorkEffort").where("workEffortParentId", productionRunId, "workEffortTypeId", "PROD_ORDER_TASK").orderBy("workEffortId").queryList();
 tasks.each { task ->
     records = task.getRelated("WorkEffortFixedAssetAssign", null, null, false);
     HtmlFormWrapper taskForm = new HtmlFormWrapper("component://manufacturing/widget/manufacturing/ProductionRunForms.xml", "ProductionRunTaskFixedAssets", request, response);
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ViewProductionRun.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ViewProductionRun.groovy
index 5e2fc83..48eca07 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ViewProductionRun.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ViewProductionRun.groovy
@@ -44,7 +44,7 @@
         context.productionRunData = productionRunData;
 
         // Find all the order items to which this production run is linked.
-        orderItems = delegator.findByAnd("WorkOrderItemFulfillment", [workEffortId : productionRunId], null, false);
+        orderItems = from("WorkOrderItemFulfillment").where("workEffortId", productionRunId).queryList();
         if (orderItems) {
             context.orderItems = orderItems;
         }
@@ -55,7 +55,7 @@
         context.productionRunComponents = productionRun.getProductionRunComponents();;
 
         // Find all the notes linked to this production run.
-        productionRunNoteData = delegator.findByAnd("WorkEffortNoteAndData", [workEffortId : productionRunId], null, false);
+        productionRunNoteData = from("WorkEffortNoteAndData").where("workEffortId", productionRunId).queryList();
         if (productionRunNoteData) {
             context.productionRunNoteData = productionRunNoteData;
         }
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/WorkWithShipmentPlans.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/WorkWithShipmentPlans.groovy
index b22c17b..376c5dd 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/WorkWithShipmentPlans.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/WorkWithShipmentPlans.groovy
@@ -25,7 +25,7 @@
 shipmentPlans = [];
 rows = [];
 if (shipment && shipment.shipmentId) {
-    shipmentPlans = delegator.findByAnd("OrderShipment", [shipmentId : shipment.shipmentId], null, false);
+    shipmentPlans = from("OrderShipment").where("shipmentId", shipment.shipmentId).queryList();
 }
 if (shipmentPlans) {
     workInProgress = "false";
@@ -67,7 +67,7 @@
         // Total quantity planned not issued
         plannedQuantity = 0.0;
         qtyPlannedInShipment = [:];
-        plans = delegator.findByAnd("OrderShipment", [orderId : orderItem.orderId ,orderItemSeqId : orderItem.orderItemSeqId], null, false);
+        plans = from("OrderShipment").where("orderId", orderItem.orderId ,"orderItemSeqId", orderItem.orderItemSeqId).queryList();
         plans.each { plan ->
             if (plan.quantity) {
                 netPlanQty = plan.quantity;
@@ -120,7 +120,7 @@
         }
         oneRow.weight = weight;
         if (product.weightUomId) {
-            weightUom = delegator.findOne("Uom", [uomId : product.weightUomId], true);
+            weightUom = from("Uom").where("uomId", product.weightUomId).cache(true).queryOne();
             oneRow.weightUom = weightUom.abbreviation;
         }
         volume = 0.0;
@@ -138,16 +138,16 @@
             product.widthUomId &&
             product.depthUomId) {
 
-            heightUom = delegator.findOne("Uom", [uomId : product.heightUomId], true);
-            widthUom = delegator.findOne("Uom", [uomId : product.widthUomId], true);
-            depthUom = delegator.findOne("Uom", [uomId : product.depthUomId], true);
+            heightUom = from("Uom").where("uomId", product.heightUomId).cache(true).queryOne();
+            widthUom = from("Uom").where("uomId", product.widthUomId).cache(true).queryOne();
+            depthUom = from("Uom").where("uomId", product.depthUomId).cache(true).queryOne();
             oneRow.volumeUom = heightUom.abbreviation + "x" +
                                     widthUom.abbreviation + "x" +
                                     depthUom.abbreviation;
         }
         rows.add(oneRow);
         // Select the production runs, if available
-        productionRuns = delegator.findByAnd("WorkOrderItemFulfillment", [orderId : shipmentPlan.orderId, orderItemSeqId : shipmentPlan.orderItemSeqId, shipGroupSeqId : shipmentPlan.shipGroupSeqId],["workEffortId"], null, false); // TODO: add shipmentId
+        productionRuns = from("WorkOrderItemFulfillment").where("orderId", shipmentPlan.orderId, "orderItemSeqId", shipmentPlan.orderItemSeqId, "shipGroupSeqId", shipmentPlan.shipGroupSeqId).orderBy("workEffortId").queryList();
         if (productionRuns) {
             workInProgress = "true";
             productionRunsId = "";
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/mrp/FindInventoryEventPlan.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/mrp/FindInventoryEventPlan.groovy
index 5789471..bce9ea6 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/mrp/FindInventoryEventPlan.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/mrp/FindInventoryEventPlan.groovy
@@ -60,7 +60,7 @@
 
     if ( mainCond) {
     // do the lookup
-        inventoryList = delegator.findList("MrpEvent", mainCond, null, ["productId", "eventDate"], null, false);
+        inventoryList = from("MrpEvent").where(mainCond).orderBy("productId", "eventDate").queryList();
     }
 
     context.inventoryList = inventoryList;
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsComponentsByFeature.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsComponentsByFeature.groovy
index 9594b5a..3fdb42f 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsComponentsByFeature.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsComponentsByFeature.groovy
@@ -24,15 +24,15 @@
 import org.ofbiz.product.category.CategoryWorker;
 
 if (productCategoryIdPar) {
-    category = delegator.findOne("ProductCategory", [productCategoryId : productCategoryIdPar], false);
+    category = from("ProductCategory").where("productCategoryId", productCategoryIdPar).queryOne();
     context.category = category;
 }
 if (productFeatureTypeIdPar) {
-    featureType = delegator.findOne("ProductFeatureType", [productFeatureTypeId : productFeatureTypeIdPar], false);
+    featureType = from("ProductFeatureType").where("productFeatureTypeId", productFeatureTypeIdPar).queryOne();
     context.featureType = featureType;
 }
 
-allProductionRuns = delegator.findByAnd("WorkEffortAndGoods", [workEffortName : planName],["productId"], false);
+allProductionRuns = from("WorkEffortAndGoods").where("workEffortName", planName).orderBy("productId").queryList();
 productionRuns = [];
 features = [:]; // each entry is a productFeatureId|{productFeature,products}
 products = [:]; // each entry is a productId|{product,quantity}
@@ -43,15 +43,14 @@
 if (allProductionRuns) {
     allProductionRuns.each { productionRun ->
         // select the production run's task of a given name (i.e. type) if any (based on the report's parameter)
-        productionRunTasks = delegator.findByAnd("WorkEffort", [workEffortParentId : productionRun.workEffortId, workEffortName : taskNamePar], null, false);
-        productionRunTask = EntityUtil.getFirst(productionRunTasks);
+        productionRunTask = from("WorkEffort").where("workEffortParentId", productionRun.workEffortId, "workEffortName", taskNamePar).queryFirst();
         if (!productionRunTask) {
             // the production run doesn't include the given task, skip it
             return;
         }
 
         // select the task's components, if any
-        allProductionRunComponents = delegator.findByAnd("WorkEffortGoodStandard", [workEffortId : productionRunTask.workEffortId,workEffortGoodStdTypeId : "PRUNT_PROD_NEEDED"], null, false);
+        allProductionRunComponents = from("WorkEffortGoodStandard").where("workEffortId", productionRunTask.workEffortId, "workEffortGoodStdTypeId", "PRUNT_PROD_NEEDED").queryList();
         allProductionRunComponents.each { productionRunComponent ->
             // verify if the product is a member of the given category (based on the report's parameter)
             if (productCategoryIdPar) {
@@ -60,19 +59,16 @@
                     return;
                 }
             }
-            productionRunProduct = delegator.findOne("Product", [productId : productionRunComponent.productId], false);
+            productionRunProduct = from("Product").where("productId", productionRunComponent.productId).queryOne();
 
             location = null;
             if (productionRunProduct) {
-                locations = delegator.findByAnd("ProductFacilityLocation", [facilityId : productionRun.facilityId, productId : productionRunProduct.productId], null, false);
-                location = EntityUtil.getFirst(locations);
+                location = from("ProductFacilityLocation").where("facilityId", productionRun.facilityId, "productId", productionRunProduct.productId).queryFirst();
             }
 
             // group by standard feature of type productFeatureTypeIdPar
             if (productFeatureTypeIdPar) {
-                standardFeatures = delegator.findByAnd("ProductFeatureAndAppl", [productFeatureTypeId : productFeatureTypeIdPar, productId : productionRunComponent.productId, productFeatureApplTypeId : "STANDARD_FEATURE"], null, false);
-                standardFeatures = EntityUtil.filterByDate(standardFeatures);
-                standardFeature = EntityUtil.getFirst(standardFeatures);
+                standardFeature = from("ProductFeatureAndAppl").where("productFeatureTypeId", productFeatureTypeIdPar, "productId", productionRunComponent.productId, "productFeatureApplTypeId", "STANDARD_FEATURE").filterByDate().queryFirst();
                 standardFeatureId = null;
                 if (standardFeature) {
                     standardFeatureId = standardFeature.productFeatureId;
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsInfoAndOrder.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsInfoAndOrder.groovy
index 09cf1c9..b304fde 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsInfoAndOrder.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsInfoAndOrder.groovy
@@ -25,11 +25,11 @@
 import org.ofbiz.order.order.OrderReadHelper;
 
 if (productCategoryIdPar) {
-    category = delegator.findOne("ProductCategory", [productCategoryId : productCategoryIdPar], false);
+    category = from("ProductCategory").where("productCategoryId", productCategoryIdPar).queryOne();
     context.category = category;
 }
 
-allProductionRuns = delegator.findByAnd("WorkEffortAndGoods", [workEffortName : planName, statusId : "WEGS_CREATED", workEffortGoodStdTypeId : "PRUN_PROD_DELIV"], ["productId"], false);
+allProductionRuns = from("WorkEffortAndGoods").where("workEffortName", planName, "statusId", "WEGS_CREATED", "workEffortGoodStdTypeId", "PRUN_PROD_DELIV").orderBy("productId").queryList();
 productionRuns = [];
 
 if (allProductionRuns) {
@@ -41,16 +41,14 @@
                 return;
             }
         }
-        productionRunProduct = delegator.findOne("Product", [productId : productionRun.productId], false);
+        productionRunProduct = from("Product").where("productId", productionRun.productId).queryOne();
         String rootProductionRunId = ProductionRunHelper.getRootProductionRun(delegator, productionRun.workEffortId);
 
-        productionRunOrders = delegator.findByAnd("WorkOrderItemFulfillment", [workEffortId : rootProductionRunId], null, false);
-        productionRunOrder = EntityUtil.getFirst(productionRunOrders);
+        productionRunOrder = from("WorkOrderItemFulfillment").where("workEffortId", rootProductionRunId).queryFirst();
         OrderReadHelper orh = new OrderReadHelper(delegator, productionRunOrder.orderId);
 
         // select the production run's task of a given name (i.e. type) if any (based on the report's parameter)
-        productionRunTasks = delegator.findByAnd("WorkEffort", [workEffortParentId : productionRun.workEffortId, workEffortName : taskNamePar], null, false);
-        productionRunTask = EntityUtil.getFirst(productionRunTasks);
+        productionRunTask = from("WorkEffort").where("workEffortParentId", productionRun.workEffortId, "workEffortName", taskNamePar).queryFirst();
         if (!productionRunTask) {
             // the production run doesn't include the given task, skip it
             return;
@@ -62,12 +60,13 @@
                                           productionRunOrder : productionRunOrder,
                                           customer : orh.getPlacingParty(),
                                           address : orh.getShippingAddress()];
-        allProductionComponents = delegator.findByAnd("WorkEffortAndGoods", [workEffortId : productionRunTask.workEffortId, statusId : "WEGS_CREATED", workEffortGoodStdTypeId : "PRUNT_PROD_NEEDED"], ["productId"], false);
+        allProductionComponents = from("WorkEffortAndGoods").where("workEffortId", productionRunTask.workEffortId, "statusId", "WEGS_CREATED", "workEffortGoodStdTypeId", "PRUNT_PROD_NEEDED").orderBy("productId").queryList();
+        
         componentList = [];
 
         if (allProductionComponents) {
             allProductionComponents.each { productionComponent ->
-                productionRunProductComp = delegator.findOne("Product", [productId : productionComponent.productId], false);
+                productionRunProductComp = from("Product").where("productId", productionComponent.productId).queryOne();
                 productionRunProductMap = [component : productionComponent,componentProduct : productionRunProductComp];
                 componentList.add(productionRunProductMap);
             }
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsProductsAndOrder.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsProductsAndOrder.groovy
index c2b8ce4..fb77205 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsProductsAndOrder.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsProductsAndOrder.groovy
@@ -25,11 +25,11 @@
 import org.ofbiz.order.order.OrderReadHelper;
 
 if (productCategoryIdPar) {
-    category = delegator.findOne("ProductCategory", [productCategoryId : productCategoryIdPar], false);
+    category = from("ProductCategory").where("productCategoryId", productCategoryIdPar).queryOne();
     context.category = category;
 }
 
-allProductionRuns = delegator.findByAnd("WorkEffortAndGoods", UtilMisc.toMap("workEffortName", planName, "statusId", "WEGS_CREATED", "workEffortGoodStdTypeId", "PRUN_PROD_DELIV"), UtilMisc.toList("productId"), false);
+allProductionRuns = from("WorkEffortAndGoods").where("workEffortName", planName, "statusId", "WEGS_CREATED", "workEffortGoodStdTypeId", "PRUN_PROD_DELIV").orderBy("productId").queryList();
 productionRuns = [];
 
 if (allProductionRuns) {
@@ -41,14 +41,12 @@
                 return;
             }
         }
-        productionRunProduct = delegator.findOne("Product", [productId : productionRun.productId], false);
+        productionRunProduct = from("Product").where("productId", productionRun.productId).queryOne();
         String rootProductionRunId = ProductionRunHelper.getRootProductionRun(delegator, productionRun.workEffortId);
 
-        productionRunOrders = delegator.findByAnd("WorkOrderItemFulfillment", [workEffortId : rootProductionRunId], null, false);
-        productionRunOrder = EntityUtil.getFirst(productionRunOrders);
+        productionRunOrder = from("WorkOrderItemFulfillment").where("workEffortId", rootProductionRunId).queryFirst();
         OrderReadHelper orh = new OrderReadHelper(delegator, productionRunOrder.orderId);
-        locations = delegator.findByAnd("ProductFacilityLocation", [productId : productionRun.productId, facilityId : productionRun.facilityId], null, false);
-        location = EntityUtil.getFirst(locations);
+        location = from("ProductFacilityLocation").where("productId", productionRun.productId, "facilityId", productionRun.facilityId).queryFirst();
 
         productionRunMap = [productionRun : productionRun,
                                           product : productionRunProduct,
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsProductsByFeature.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsProductsByFeature.groovy
index a72517e..d324fad 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsProductsByFeature.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsProductsByFeature.groovy
@@ -23,15 +23,15 @@
 import org.ofbiz.entity.util.EntityUtil;
 
 if (productCategoryIdPar) {
-    category = delegator.findOne("ProductCategory", [productCategoryId : productCategoryIdPar], false);
+    category = from("ProductCategory").where("productCategoryId", productCategoryIdPar).queryOne();
     context.category = category;
 }
 if (productFeatureTypeIdPar) {
-    featureType = delegator.findOne("ProductFeatureType", [productFeatureTypeId : productFeatureTypeIdPar], false);
+    featureType = from("ProductFeatureType").where("productFeatureTypeId", productFeatureTypeIdPar).queryOne();
     context.featureType = featureType;
 }
 
-allProductionRuns = delegator.findByAnd("WorkEffortAndGoods", [workEffortName : planName], ["productId"], false);
+allProductionRuns = from("WorkEffortAndGoods").where("workEffortName", planName).orderBy("productId").queryList();
 productionRuns = [:];
 features = [];
 if (!productFeatureTypeIdPar) {
@@ -47,13 +47,11 @@
                 return;
             }
         }
-        productionRunProduct = delegator.findOne("Product", [productId : productionRun.productId], false);
+        productionRunProduct = from("Product").where("productId", productionRun.productId).queryOne();
 
         // group by standard feature of type productFeatureTypeIdPar
         if (productFeatureTypeIdPar) {
-            standardFeatures = delegator.findByAnd("ProductFeatureAndAppl", [productFeatureTypeId : productFeatureTypeIdPar, productId : productionRun.productId, productFeatureApplTypeId : "STANDARD_FEATURE"], null, false);
-            standardFeatures = EntityUtil.filterByDate(standardFeatures);
-            standardFeature = EntityUtil.getFirst(standardFeatures);
+            standardFeature = from("ProductFeatureAndAppl").where("productFeatureTypeId", productFeatureTypeIdPar, "productId", productionRun.productId, "productFeatureApplTypeId", "STANDARD_FEATURE").filterByDate().queryFirst();
             standardFeatureId = null;
             if (standardFeature) {
                 standardFeatureId = standardFeature.productFeatureId;
@@ -66,8 +64,7 @@
         }
 
         // select the production run's task of a given name (i.e. type) if any (based on the report's parameter)
-        productionRunTasks = delegator.findByAnd("WorkEffort", [workEffortParentId : productionRun.workEffortId, workEffortName : taskNamePar], null, false);
-        productionRunTask = EntityUtil.getFirst(productionRunTasks);
+        productionRunTask = from("WorkEffort").where("workEffortParentId", productionRun.workEffortId, "workEffortName", taskNamePar).queryFirst();
         if (!productionRunTask) {
             // the production run doesn't include the given task, skip it
             return;
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsProductsStacks.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsProductsStacks.groovy
index 65ec9be..92e6f9d 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsProductsStacks.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PRunsProductsStacks.groovy
@@ -23,15 +23,15 @@
 import org.ofbiz.entity.util.EntityUtil;
 
 if (productCategoryIdPar) {
-    category = delegator.findOne("ProductCategory", [productCategoryId : productCategoryIdPar], false);
+    category = from("ProductCategory").where("productCategoryId", productCategoryIdPar).queryOne();
     context.category = category;
 }
 if (productFeatureTypeIdPar) {
-    featureType = delegator.findOne("ProductFeatureType", [productFeatureTypeId : productFeatureTypeIdPar], false);
+    featureType = from("ProductFeatureType").where("productFeatureTypeId", productFeatureTypeIdPar).queryOne();
     context.featureType = featureType;
 }
 
-allProductionRuns = delegator.findByAnd("WorkEffortAndGoods", [workEffortName : planName], ["productId"], false);
+allProductionRuns = from("WorkEffortAndGoods").where("workEffortName", planName).orderBy("productId").queryList();
 productionRuns = [];
 features = [:];
 products = [:];
@@ -45,16 +45,14 @@
                 return;
             }
         }
-        productionRunProduct = delegator.findOne("Product", [productId : productionRun.productId], false);
+        productionRunProduct = from("Product").where("productId", productionRun.productId).queryOne();
         location = [:];
         if (productionRunProduct) {
-            locations = delegator.findByAnd("ProductFacilityLocation", [facilityId : productionRun.facilityId, productId : productionRun.productId], null, false);
-            location = EntityUtil.getFirst(locations);
+            location = form("ProductFacilityLocation").where(facilityId : productionRun.facilityId, productId : productionRun.productId).queryFirst();
         }
         if (taskNamePar) {
             // select the production run's task of a given name (i.e. type) if any (based on the report's parameter)
-            productionRunTasks = delegator.findByAnd("WorkEffort", [workEffortParentId : productionRun.workEffortId , workEffortName : taskNamePar], null, false);
-            productionRunTask = EntityUtil.getFirst(productionRunTasks);
+            productionRunTask = from("WorkEffort").where("workEffortParentId", productionRun.workEffortId , "workEffortName", taskNamePar).queryFirst();
             if (!productionRunTask) {
                 // the production run doesn't include the given task, skip it
                 return;
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PackageContentsAndOrder.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PackageContentsAndOrder.groovy
index fa6ff45..96772d0 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PackageContentsAndOrder.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/PackageContentsAndOrder.groovy
@@ -25,21 +25,20 @@
 import org.ofbiz.order.order.OrderContentWrapper;
 
 if (productCategoryIdPar) {
-    category = delegator.findOne("ProductCategory", [productCategoryId : productCategoryIdPar], false);
+    category = from("ProductCategory").where("productCategoryId", productCategoryIdPar).queryOne();
     context.category = category;
 }
 if (productFeatureTypeIdPar) {
-    featureType = delegator.findOne("ProductFeatureType", [productFeatureTypeId : productFeatureTypeIdPar], false);
+    featureType = from("ProductFeatureType").where("productFeatureTypeId", productFeatureTypeIdPar).queryOne();
     context.featureType = featureType;
 }
-packageContents = delegator.findByAnd("ShipmentPackageContent", [shipmentId : shipmentId], null, false);
+packageContents = from("ShipmentPackageContent").where("shipmentId", shipmentId).queryList();
 
 packagesMap = [:];
 if (packageContents) {
     packageContents.each { packageContent ->
-        orderShipments = delegator.findByAnd("OrderShipment", [shipmentId : shipmentId, shipmentItemSeqId : packageContent.shipmentItemSeqId], null, false);
-        orderShipment = EntityUtil.getFirst(orderShipments);
-        orderItem = delegator.findOne("OrderItem", [orderId : orderShipment.orderId, orderItemSeqId : orderShipment.orderItemSeqId], false);
+        orderShipment = from("OrderShipment").where("shipmentId", shipmentId, "shipmentItemSeqId", packageContent.shipmentItemSeqId).queryFirst();
+        orderItem = from("OrderItem").where("orderId", orderShipment.orderId, "orderItemSeqId", orderShipment.orderItemSeqId).queryOne();
         product = orderItem.getRelatedOne("Product", false);
         // verify if the product is a member of the given category (based on the report's parameter)
         if (productCategoryIdPar) {
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/ShipmentLabel.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/ShipmentLabel.groovy
index 1e90e1b..9024462 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/ShipmentLabel.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/ShipmentLabel.groovy
@@ -21,16 +21,16 @@
 import org.ofbiz.order.order.OrderReadHelper;
 
 shipmentId = parameters.shipmentId;
-shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
 
 context.shipmentIdPar = shipment.shipmentId;
 
 if (shipment) {
-    shipmentPackages = delegator.findByAnd("ShipmentPackage", [shipmentId : shipmentId], null, false);
+    shipmentPackages = from("ShipmentPackage").where("shipmentId", shipmentId).queryList();
     records = [];
     orderReaders = [:];
     shipmentPackages.each { shipmentPackage ->
-        shipmentPackageComponents = delegator.findByAnd("ShipmentPackageContent", [shipmentId : shipmentId, shipmentPackageSeqId : shipmentPackage.shipmentPackageSeqId], null, false);
+        shipmentPackageComponents = from("ShipmentPackageContent").where("shipmentId", shipmentId, "shipmentPackageSeqId", shipmentPackage.shipmentPackageSeqId).queryList();;
         shipmentPackageComponents.each { shipmentPackageComponent ->
             shipmentItem = shipmentPackageComponent.getRelatedOne("ShipmentItem", false);
             orderShipments = shipmentItem.getRelated("OrderShipment", null, null, false);
@@ -54,7 +54,7 @@
             record.shipmentPackageSeqId = shipmentPackageComponent.shipmentPackageSeqId;
             record.orderId = orderId;
             record.orderItemSeqId = orderItemSeqId;
-            product = delegator.findOne("Product", [productId : record.productId], false);
+            product = from("Product").where("productId", record.productId).queryOne();
             record.productName = product.internalName;
             record.shipDate = shipment.estimatedShipDate;
             // ---
@@ -62,7 +62,7 @@
             if (orderReaders.containsKey(orderId)) {
                 orderReadHelper = (OrderReadHelper)orderReaders.get(orderId);
             } else {
-                orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+                orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
                 orderReadHelper = new OrderReadHelper(orderHeader);
                 orderReaders.put(orderId, orderReadHelper);
             }
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/ShipmentPlanStockReport.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/ShipmentPlanStockReport.groovy
index d094e55..fa66471 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/ShipmentPlanStockReport.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/ShipmentPlanStockReport.groovy
@@ -22,16 +22,16 @@
 
 inventoryStock = [:];
 shipmentId = parameters.shipmentId;
-shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
 
 context.shipmentIdPar = shipment.shipmentId;
 context.estimatedReadyDatePar = shipment.estimatedReadyDate;
 context.estimatedShipDatePar = shipment.estimatedShipDate;
 records = [];
 if (shipment) {
-    shipmentPlans = delegator.findByAnd("OrderShipment", [shipmentId : shipmentId], null, false);
+    shipmentPlans = from("OrderShipment").where("shipmentId", shipmentId).queryList();
     shipmentPlans.each { shipmentPlan ->
-        orderLine = delegator.findOne("OrderItem", [orderId : shipmentPlan.orderId , orderItemSeqId : shipmentPlan.orderItemSeqId], false);
+        orderLine = from("OrderItem").where("orderId", shipmentPlan.orderId , "orderItemSeqId", shipmentPlan.orderItemSeqId).queryOne();
         recordGroup = [:];
         recordGroup.ORDER_ID = shipmentPlan.orderId;
         recordGroup.ORDER_ITEM_SEQ_ID = shipmentPlan.orderItemSeqId;
@@ -40,7 +40,7 @@
 
         recordGroup.PRODUCT_ID = orderLine.productId;
         recordGroup.QUANTITY = shipmentPlan.quantity;
-        product = delegator.findOne("Product", [productId : orderLine.productId], false);
+        product = from("Product").where("productId", orderLine.productId).queryOne();
         recordGroup.PRODUCT_NAME = product.internalName;
 
         inputPar = [productId : orderLine.productId,
@@ -49,7 +49,7 @@
                                      userLogin: userLogin];
 
         result = [:];
-        result = dispatcher.runSync("getNotAssembledComponents",inputPar);
+        result = runService('getNotAssembledComponents',inputPar);
         if (result) {
             components = (List)result.get("notAssembledComponents");
         }
@@ -63,7 +63,7 @@
             if (facilityId) {
                 if (!inventoryStock.containsKey(oneComponent.getProduct().productId)) {
                     serviceInput = [productId : oneComponent.getProduct().productId , facilityId : facilityId];
-                    serviceOutput = dispatcher.runSync("getInventoryAvailableByFacility",serviceInput);
+                    serviceOutput = runService('getInventoryAvailableByFacility',serviceInput);
                     qha = serviceOutput.quantityOnHandTotal ?: 0.0;
                     inventoryStock.put(oneComponent.getProduct().productId, qha);
                 }
@@ -75,7 +75,7 @@
             // Now we get the products qty already reserved by production runs
             serviceInput = [productId : oneComponent.getProduct().productId,
                                           userLogin : userLogin];
-            serviceOutput = dispatcher.runSync("getProductionRunTotResQty", serviceInput);
+            serviceOutput = runSevice('getProductionRunTotResQty', serviceInput);
             resQty = serviceOutput.reservedQuantity;
             record.reservedQuantity = resQty;
             records.add(record);
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/ShipmentWorkEffortTasks.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/ShipmentWorkEffortTasks.groovy
index 4cb9988..e86067b 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/ShipmentWorkEffortTasks.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/reports/ShipmentWorkEffortTasks.groovy
@@ -20,24 +20,24 @@
 import org.ofbiz.entity.GenericValue;
 
 shipmentId = parameters.shipmentId;
-shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
 
 context.shipmentIdPar = shipment.shipmentId;
 context.date = new Date();
 Double fixedAssetTime = new Double(0);
 
 if (shipment) {
-    shipmentPlans = delegator.findByAnd("OrderShipment", [shipmentId : shipmentId], null, false);
+    shipmentPlans = from("OrderShipment").where("shipmentId", shipmentId).queryList();
     shipmentPlans.each { shipmentPlan ->
-        productionRuns = delegator.findByAnd("WorkOrderItemFulfillment", [orderId : shipmentPlan.orderId, orderItemSeqId : shipmentPlan.orderItemSeqId] , ["workEffortId"], false); // TODO: add shipmentId
+        productionRuns = from("WorkOrderItemFulfillment").where("orderId", shipmentPlan.orderId, "orderItemSeqId", shipmentPlan.orderItemSeqId).orderBy("workEffortId").queryList();
         if (productionRuns) {
             productionRuns.each { productionRun ->
                 productionRunProduct = [:];
-                productionRunProducts = delegator.findByAnd("WorkEffortGoodStandard", [workEffortId : productionRun.workEffortId , workEffortGoodStdTypeId : "PRUN_PROD_DELIV", statusId : "WEGS_CREATED"], null, false);
+                productionRunProducts = from("WorkEffortGoodStandard").where("workEffortId", productionRun.workEffortId , "workEffortGoodStdTypeId", "PRUN_PROD_DELIV", "statusId", "WEGS_CREATED").queryList();
                 if (productionRunProducts) {
                     productionRunProduct = ((GenericValue)productionRunProducts.get(0)).getRelatedOne("Product", false);
                 }
-                tasks = delegator.findByAnd("WorkEffort", [workEffortParentId : productionRun.workEffortId, workEffortTypeId : "PROD_ORDER_TASK"], null, false);
+                tasks = from("WorkEffort").where("workEffortParentId", productionRun.workEffortId, "workEffortTypeId", "PROD_ORDER_TASK").queryList();
                 tasks.each { task ->
                     record = [:];
                     record.productId = productionRunProduct.productId;
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendar.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendar.groovy
index 53d2735..3c18e82 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendar.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendar.groovy
@@ -22,7 +22,7 @@
 requestParams = UtilHttp.getParameterMap(request);
 calendarId = requestParams.get("calendarId") ?: request.getAttribute("calendarId");
 if (calendarId != null) {
-    techDataCalendar = delegator.findOne("TechDataCalendar", [calendarId : calendarId], false);
+    techDataCalendar = from("TechDataCalendar").where("calendarId", calendarId).queryOne();
     context.techDataCalendar = techDataCalendar;
 }
 
@@ -41,5 +41,5 @@
 }
 context.calendarData = calendarData;
 
-allCalendarWeek = delegator.findList("TechDataCalendarWeek", null, null, null, null, false);
+allCalendarWeek = from("TechDataCalendarWeek").queryList();
 context.calendarWeeks = allCalendarWeek;
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 e28d31e..e076d6a 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendarExceptionDay.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendarExceptionDay.groovy
@@ -33,7 +33,7 @@
 
 calendarId = parameters.calendarId ?: request.getAttribute("calendarId");
 if (calendarId) {
-    techDataCalendar = delegator.findOne("TechDataCalendar", [calendarId : calendarId], false);
+    techDataCalendar = from("TechDataCalendar").where("calendarId", calendarId).queryOne();
 }
 if (techDataCalendar) {
     calendarExceptionDays = techDataCalendar.getRelated("TechDataCalendarExcDay", null, null, false);
@@ -52,7 +52,7 @@
 exceptionDateStartTime = ObjectType.simpleTypeConvert(exceptionDateStartTime, "Timestamp", null, null);
 
 if (exceptionDateStartTime) {
-    calendarExceptionDay = delegator.findOne("TechDataCalendarExcDay", [calendarId : calendarId , exceptionDateStartTime : exceptionDateStartTime], false);
+    calendarExceptionDay = from("TechDataCalendarExcDay").where("calendarId", calendarId , "exceptionDateStartTime", exceptionDateStartTime)
     if (calendarExceptionDay) {
         HtmlFormWrapper updateCalendarExceptionDayWrapper = new HtmlFormWrapper("component://manufacturing/widget/manufacturing/CalendarForms.xml", "UpdateCalendarExceptionDay", request, response);
         updateCalendarExceptionDayWrapper.putInContext("calendarExceptionDay", calendarExceptionDay);
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 61b7f26..7907a4f 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendarExceptionWeek.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendarExceptionWeek.groovy
@@ -31,7 +31,7 @@
 
 calendarId = parameters.calendarId ?: request.getAttribute("calendarId");;
 if (calendarId) {
-    techDataCalendar = delegator.findOne("TechDataCalendar", [calendarId : calendarId], false);
+    techDataCalendar = from("TechDataCalendar").where("calendarId", calendarId).queryOne();
 }
 if (techDataCalendar) {
     calendarExceptionWeeks = techDataCalendar.getRelated("TechDataCalendarExcWeek", null, null, false);
@@ -56,7 +56,7 @@
 exceptionDateStart = ObjectType.simpleTypeConvert(exceptionDateStart, "java.sql.Date", null, null);
 
 if (exceptionDateStart) {
-    calendarExceptionWeek = delegator.findOne("TechDataCalendarExcWeek", [calendarId : calendarId , exceptionDateStart : exceptionDateStart], false);
+    calendarExceptionWeek = from("TechDataCalendarExcWeek").where("calendarId", calendarId , "exceptionDateStart", exceptionDateStart).queryOne();
     if (calendarExceptionWeek) {
         HtmlFormWrapper updateCalendarExceptionWeekWrapper = new HtmlFormWrapper("component://manufacturing/widget/manufacturing/CalendarForms.xml", "UpdateCalendarExceptionWeek", request, response);
         updateCalendarExceptionWeekWrapper.putInContext("calendarExceptionWeek", calendarExceptionWeek);
diff --git a/applications/manufacturing/widget/manufacturing/LookupScreens.xml b/applications/manufacturing/widget/manufacturing/LookupScreens.xml
index 720b02d..90147ec 100644
--- a/applications/manufacturing/widget/manufacturing/LookupScreens.xml
+++ b/applications/manufacturing/widget/manufacturing/LookupScreens.xml
@@ -32,6 +32,7 @@
                 <set field="requestParameters.workEffortTypeId" to-scope="screen" default-value="ROUTING"/>
                 <set field="requestParameters.fixedAssetId" to-scope="screen" default-value=""/>
                 <set field="queryString" from-field="result.queryString"/>
+                <set field="searchFields" value="[workEffortId]"/>
                 <set field="viewIndex" from-field="parameters.VIEW_INDEX" type="Integer"/>
                 <property-to-field resource="widget" property="widget.form.defaultViewSize" field="viewSizeDefaultValue"/>
                 <set field="viewSize" from-field="parameters.VIEW_SIZE" type="Integer" default-value="${viewSizeDefaultValue}"/>
diff --git a/applications/marketing/entitydef/entitymodel.xml b/applications/marketing/entitydef/entitymodel.xml
index 0eaa5e7..1300bd0 100644
--- a/applications/marketing/entitydef/entitymodel.xml
+++ b/applications/marketing/entitydef/entitymodel.xml
@@ -532,9 +532,6 @@
       <relation type="one" fk-name="TKNG_CODVST_TKCD" rel-entity-name="TrackingCode">
         <key-map field-name="trackingCodeId"/>
       </relation>
-      <relation type="one" fk-name="TKNG_CODVST_VST" rel-entity-name="Visit">
-        <key-map field-name="visitId"/>
-      </relation>
       <relation type="one" fk-name="TKNG_CODVST_SRCEM" rel-entity-name="Enumeration">
         <key-map field-name="sourceEnumId" rel-field-name="enumId"/>
       </relation>
diff --git a/applications/marketing/webapp/marketing/WEB-INF/actions/contact/GetContactListMarketingEmail.groovy b/applications/marketing/webapp/marketing/WEB-INF/actions/contact/GetContactListMarketingEmail.groovy
index 8ea3a70..ae13c9d 100644
--- a/applications/marketing/webapp/marketing/WEB-INF/actions/contact/GetContactListMarketingEmail.groovy
+++ b/applications/marketing/webapp/marketing/WEB-INF/actions/contact/GetContactListMarketingEmail.groovy
@@ -19,7 +19,7 @@
 
 // figure out the MARKETING_EMAIL of the ContactList owner, for setting in the send email link
 if (!contactList && contactListId) {
-    contactList = delegator.findOne("ContactList", [contactListId : "contactListId"], true);
+    contactList = from("ContactList").where("contactListId", "contactListId").cache(true).queryOne();
 }
 if (contactList) {
     ownerParty = contactList.getRelatedOne("OwnerParty", false);
diff --git a/applications/marketing/webapp/marketing/WEB-INF/actions/reports/EmailStatusReport.groovy b/applications/marketing/webapp/marketing/WEB-INF/actions/reports/EmailStatusReport.groovy
index fcd0c3f..d0352f5 100644
--- a/applications/marketing/webapp/marketing/WEB-INF/actions/reports/EmailStatusReport.groovy
+++ b/applications/marketing/webapp/marketing/WEB-INF/actions/reports/EmailStatusReport.groovy
@@ -42,7 +42,6 @@
     conditionList.add(EntityCondition.makeCondition("roleStatusId", EntityOperator.EQUALS, roleStatusId));
 }
 conditionList.add(EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, "ADDRESSEE"));
-conditions = EntityCondition.makeCondition(conditionList, EntityOperator.AND);
 
-commStatausList = delegator.findList("CommunicationEventAndRole", conditions, null, null, null, false);
+commStatausList = from("CommunicationEventAndRole").where(conditionList).queryList();
 context.commStatausList = commStatausList;
diff --git a/applications/marketing/webapp/marketing/WEB-INF/actions/reports/MarketingCampaignReport.groovy b/applications/marketing/webapp/marketing/WEB-INF/actions/reports/MarketingCampaignReport.groovy
index d078a91..f3b1550 100644
--- a/applications/marketing/webapp/marketing/WEB-INF/actions/reports/MarketingCampaignReport.groovy
+++ b/applications/marketing/webapp/marketing/WEB-INF/actions/reports/MarketingCampaignReport.groovy
@@ -40,11 +40,8 @@
     orderConditionList.add(EntityCondition.makeCondition("marketingCampaignId", EntityOperator.EQUALS, marketingCampaignId));
 }
 
-visitConditions = EntityCondition.makeCondition(visitConditionList, EntityOperator.AND);
-orderConditions = EntityCondition.makeCondition(orderConditionList, EntityOperator.AND);
-
-visits = delegator.findList("MarketingCampaignAndVisit", visitConditions, ['marketingCampaignId', 'visitId'] as Set, ['marketingCampaignId'], null, false);
-orders = delegator.findList("MarketingCampaignAndOrderHeader", orderConditions, ['marketingCampaignId', 'orderId', 'grandTotal'] as Set, ['marketingCampaignId'], null, false);
+visits = select("marketingCampaignId", "visitId").from("MarketingCampaignAndVisit").where(visitConditionList).orderBy("marketingCampaignId").queryList();
+orders = select("marketingCampaignId", "orderId", "grandTotal").from("MarketingCampaignAndOrderHeader").where(orderConditionList).orderBy("marketingCampaignId").queryList();
 
 //use this helper to build a List of visits, orders, order totals, and conversion rates
 marketingCampaignVisitAndOrders = ReportHelper.calcConversionRates(visits, orders, "marketingCampaignId");
diff --git a/applications/marketing/webapp/marketing/WEB-INF/actions/reports/PartyStatusReport.groovy b/applications/marketing/webapp/marketing/WEB-INF/actions/reports/PartyStatusReport.groovy
index 359aba3..666327e 100644
--- a/applications/marketing/webapp/marketing/WEB-INF/actions/reports/PartyStatusReport.groovy
+++ b/applications/marketing/webapp/marketing/WEB-INF/actions/reports/PartyStatusReport.groovy
@@ -36,6 +36,5 @@
 if (statusId) {
     conditionList.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, statusId));
 }
-conditions = EntityCondition.makeCondition(conditionList, EntityOperator.AND);
-partyStatusLists = delegator.findList("ContactListPartyStatus", conditions, null, null, null, false);
+partyStatusLists = from("ContactListPartyStatus").where(conditionList).queryList();
 context.partyStatusLists = partyStatusLists;
diff --git a/applications/marketing/webapp/marketing/WEB-INF/actions/reports/TrackingCodeReport.groovy b/applications/marketing/webapp/marketing/WEB-INF/actions/reports/TrackingCodeReport.groovy
index a1cdd27..906122e 100644
--- a/applications/marketing/webapp/marketing/WEB-INF/actions/reports/TrackingCodeReport.groovy
+++ b/applications/marketing/webapp/marketing/WEB-INF/actions/reports/TrackingCodeReport.groovy
@@ -42,11 +42,8 @@
      orderConditionList.add(EntityCondition.makeCondition("trackingCodeId", EntityOperator.EQUALS, trackingCodeId));
 }
 
-visitConditions = EntityCondition.makeCondition(visitConditionList, EntityOperator.AND);
-orderConditions = EntityCondition.makeCondition(orderConditionList, EntityOperator.AND);
-
-visits = delegator.findList("TrackingCodeAndVisit", visitConditions, ['trackingCodeId', 'visitId'] as Set, ['trackingCodeId'], null, false);
-orders = delegator.findList("TrackingCodeAndOrderHeader", orderConditions, ['trackingCodeId', 'orderId', 'grandTotal'] as Set, ['trackingCodeId'], null, false);
+visits = select("trackingCodeId", "visitId").from("TrackingCodeAndVisit").where(visitConditionList).orderBy("trackingCodeId").queryList();
+orders = select("trackingCodeId", "orderId", "grandTotal").from("TrackingCodeAndOrderHeader").where(orderConditionList).orderBy("trackingCodeId").queryList();
 
 // use this helper to build a List of visits, orders, order totals, and conversion rates
 trackingCodeVisitAndOrders = ReportHelper.calcConversionRates(visits, orders, "trackingCodeId");
diff --git a/applications/marketing/webapp/sfa/WEB-INF/action/CloneLead.groovy b/applications/marketing/webapp/sfa/WEB-INF/action/CloneLead.groovy
index ebd6e11..a1426bb 100644
--- a/applications/marketing/webapp/sfa/WEB-INF/action/CloneLead.groovy
+++ b/applications/marketing/webapp/sfa/WEB-INF/action/CloneLead.groovy
@@ -23,15 +23,17 @@
 
 partyId = parameters.partyId;
 if (partyId) {
-    party =  delegator.findOne("Party", [partyId : partyId], false);
+    party =  from("Party").where("partyId", partyId).queryOne();
     person = party.getRelatedOne("Person", false);
     contactDetailMap = [partyId : partyId, firstName : person.firstName, lastName : person.lastName, suffix : person.suffix];
-    partyRelationship = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findList("PartyRelationship",
-                                EntityCondition.makeCondition([partyIdTo : partyId, roleTypeIdTo : 'EMPLOYEE', roleTypeIdFrom : 'LEAD', partyRelationshipTypeId : 'EMPLOYMENT']),
-                                null, ['-fromDate'], null, false)));
+    partyRelationship = from("PartyRelationship")
+                            .where("partyIdTo", partyId, "roleTypeIdTo", "EMPLOYEE", "roleTypeIdFrom", "LEAD", "partyRelationshipTypeId", "EMPLOYMENT")
+                            .orderBy("-fromDate")
+                            .filterByDate()
+                            .queryFirst();
     if (partyRelationship) {
         contactDetailMap.title = partyRelationship.positionTitle;
-        partyGroup = delegator.findOne("PartyGroup", [partyId : partyRelationship.partyIdFrom], false);
+        partyGroup = from("PartyGroup").where("partyId", partyRelationship.partyIdFrom).queryOne();
         if (partyGroup) {
             if (partyGroup.groupName) {
                 contactDetailMap.groupName = partyGroup.groupName;
diff --git a/applications/marketing/webapp/sfa/WEB-INF/action/MergeContacts.groovy b/applications/marketing/webapp/sfa/WEB-INF/action/MergeContacts.groovy
index 531ac5f..2569f9b 100644
--- a/applications/marketing/webapp/sfa/WEB-INF/action/MergeContacts.groovy
+++ b/applications/marketing/webapp/sfa/WEB-INF/action/MergeContacts.groovy
@@ -27,7 +27,7 @@
 if (partyIdFrom && partyIdTo) {
     partyList = [partyIdTo, partyIdFrom];
     partyList.each { partyId ->
-        party = delegator.findOne("Party", [partyId : partyId], false);
+        party = from("Party").where("partyId", partyId).queryOne();
         person =  party.getRelatedOne("Person", false);
         contactDetailMap = [partyId : partyId, firstName : person.firstName, lastName : person.lastName];
 
@@ -42,10 +42,10 @@
                 if (address2) {
                     contactDetailMap.address2 = address2;
                 }
-                geo = delegator.findOne("Geo", [geoId : postalAddress.stateProvinceGeoId], false);
+                geo = sfrom("Geo").where("geoId", postalAddress.stateProvinceGeoId).queryOne();
                 contactDetailMap.state = geo.geoName;
 
-                geo = delegator.findOne("Geo", [geoId : postalAddress.countryGeoId], false);
+                geo = from("Geo").where("geoId", postalAddress.countryGeoId).queryOne();
                 contactDetailMap.country = geo.geoName;
             }
         }
diff --git a/applications/order/entitydef/entitymodel.xml b/applications/order/entitydef/entitymodel.xml
index 9fd0c42..23f5da6 100644
--- a/applications/order/entitydef/entitymodel.xml
+++ b/applications/order/entitydef/entitymodel.xml
@@ -2756,9 +2756,6 @@
       <field name="wasReserved" type="indicator"></field>
       <prim-key field="visitId"/>
       <prim-key field="cartAbandonedLineSeqId"/>
-      <relation type="one" fk-name="CART_ABLN_VST" rel-entity-name="Visit">
-        <key-map field-name="visitId"/>
-      </relation>
       <relation type="one" fk-name="CART_ABLN_PRD" rel-entity-name="Product">
         <key-map field-name="productId"/>
       </relation>
@@ -2810,9 +2807,6 @@
       <relation type="one" fk-name="SHLIST_PTY" rel-entity-name="Party">
         <key-map field-name="partyId"/>
       </relation>
-      <relation type="one" fk-name="SHLIST_VSTR" rel-entity-name="Visitor">
-        <key-map field-name="visitorId"/>
-      </relation>
       <relation type="many" fk-name="SHLIST_PSSM" rel-entity-name="ProductStoreShipmentMeth">
         <key-map field-name="productStoreId"/>
         <key-map field-name="shipmentMethodTypeId"/>
diff --git a/applications/order/src/org/ofbiz/order/order/OrderServices.java b/applications/order/src/org/ofbiz/order/order/OrderServices.java
index 2ed0630..c3a93ee 100644
--- a/applications/order/src/org/ofbiz/order/order/OrderServices.java
+++ b/applications/order/src/org/ofbiz/order/order/OrderServices.java
@@ -4459,7 +4459,7 @@
                 itemStatus.put("orderId", newItem.get("orderId"));
                 itemStatus.put("orderItemSeqId", newItem.get("orderItemSeqId"));
                 itemStatus.put("statusDatetime", UtilDateTime.nowTimestamp());
-                itemStatus.set("statusUserLogin", userLogin.get("userLogin"));
+                itemStatus.set("statusUserLogin", userLogin.get("userLoginId"));
                 delegator.create(itemStatus);
             }
         }
diff --git a/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCart.java b/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCart.java
index 5549102..90a7a27 100644
--- a/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCart.java
+++ b/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCart.java
@@ -3542,7 +3542,17 @@
             for (ShoppingCartItem item : cartLineItems) {
                 //Debug.logInfo("Item qty: " + item.getQuantity(), module);
                 try {
-                    item.explodeItem(this, dispatcher);
+                    int thisIndex = items().indexOf(item);
+                    List<ShoppingCartItem> explodedItems = item.explodeItem(this, dispatcher);
+
+                    // Add exploded items into cart with order item sequence id and item ship group quantity
+                    for (ShoppingCartItem explodedItem : explodedItems) {
+                        String orderItemSeqId = UtilFormatOut.formatPaddedNumber(nextItemSeq, 5);
+                        explodedItem.setOrderItemSeqId(orderItemSeqId);
+                        addItemToEnd(explodedItem);
+                        setItemShipGroupQty(explodedItem, BigDecimal.ONE, thisIndex);
+                        nextItemSeq++;
+                    }
                 } catch (CartItemModifyException e) {
                     Debug.logError(e, "Problem exploding item! Item not exploded.", module);
                 }
@@ -3563,7 +3573,17 @@
             for (ShoppingCartItem item : shoppingCartItems) {
                 //Debug.logInfo("Item qty: " + item.getQuantity(), module);
                 try {
-                    item.explodeItem(this, dispatcher);
+                    int thisIndex = items().indexOf(item);
+                    List<ShoppingCartItem> explodedItems = item.explodeItem(this, dispatcher);
+
+                    // Add exploded items into cart with order item sequence id and item ship group quantity
+                    for (ShoppingCartItem explodedItem : explodedItems) {
+                        String orderItemSeqId = UtilFormatOut.formatPaddedNumber(nextItemSeq, 5);
+                        explodedItem.setOrderItemSeqId(orderItemSeqId);
+                        addItemToEnd(explodedItem);
+                        setItemShipGroupQty(explodedItem, BigDecimal.ONE, thisIndex);
+                        nextItemSeq++;
+                    }
                 } catch (CartItemModifyException e) {
                     Debug.logError(e, "Problem exploding (unitizing) item! Item not exploded.", module);
                 }
diff --git a/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartEvents.java b/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartEvents.java
index c47e80b..ce29cb2 100644
--- a/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartEvents.java
+++ b/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartEvents.java
@@ -946,6 +946,7 @@
             session.setAttribute("shoppingCart", cart);
         }
 
+        if (currencyUom == null) currencyUom = UtilHttp.getCurrencyUom(request);
         if (cart == null) {
             cart = new WebShoppingCart(request, locale, currencyUom);
             session.setAttribute("shoppingCart", cart);
diff --git a/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartItem.java b/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartItem.java
index 5f9b84a..97ccd7a 100644
--- a/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartItem.java
+++ b/applications/order/src/org/ofbiz/order/shoppingcart/ShoppingCartItem.java
@@ -2511,7 +2511,7 @@
         return delegator;
     }
 
-    public void explodeItem(ShoppingCart cart, LocalDispatcher dispatcher) throws CartItemModifyException {
+    public List<ShoppingCartItem> explodeItem(ShoppingCart cart, LocalDispatcher dispatcher) throws CartItemModifyException {
         BigDecimal baseQuantity = this.getQuantity();
         int thisIndex = cart.items().indexOf(this);
         List<ShoppingCartItem> newItems = new ArrayList<ShoppingCartItem>();
@@ -2523,7 +2523,6 @@
 
                 // set the new item's quantity
                 item.setQuantity(BigDecimal.ONE, dispatcher, cart, false);
-
                 // now copy/calc the adjustments
                 Debug.logInfo("Clone's adj: " + item.getAdjustments(), module);
                 if (UtilValidate.isNotEmpty(item.getAdjustments())) {
@@ -2573,11 +2572,8 @@
                 }
             }
 
-            // add the cloned item(s) to the cart
-            for (ShoppingCartItem sci : newItems) {
-                cart.addItem(thisIndex, sci);
-            }
         }
+        return newItems;
     }
 
     public static String getPurchaseOrderItemDescription(GenericValue product, GenericValue supplierProduct, Locale locale) {
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/AddGiftCertificates.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/AddGiftCertificates.groovy
index 1565d5f..63213bd 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/AddGiftCertificates.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/AddGiftCertificates.groovy
@@ -30,14 +30,14 @@
 
 // Get Gift cards availbale in data
 
-giftCardCategories = delegator.findList("ProductCategory", EntityCondition.makeCondition("productCategoryTypeId", EntityOperator.EQUALS, "GIFT_CARD_CATEGORY"), null, null, null, false);
+giftCardCategories = from("ProductCategory").where("productCategoryTypeId", "GIFT_CARD_CATEGORY").queryList();
 giftCardProductList = FastList.newInstance();
 if (UtilValidate.isNotEmpty(giftCardCategories)) {
     giftCardCategories.each { giftCardCategory -> 
-        giftCardCategoryMembers = delegator.findList("ProductCategoryMember", EntityCondition.makeCondition("productCategoryId", EntityOperator.EQUALS, giftCardCategory.productCategoryId), null, null, null, false);
+        giftCardCategoryMembers = from("ProductCategoryMember").where("productCategoryId", giftCardCategory.productCategoryId).queryList();
         if (UtilValidate.isNotEmpty(giftCardCategoryMembers)) {
             giftCardCategoryMembers.each { giftCardCategoryMember -> 
-                giftCardProducts = delegator.findList("ProductAndPriceView", EntityCondition.makeCondition("productId", EntityOperator.EQUALS, giftCardCategoryMember.productId), null, null, null, false);
+                giftCardProducts = from("ProductAndPriceView").where("productId", giftCardCategoryMember.productId).queryList();
                 if (UtilValidate.isNotEmpty(giftCardProducts)) {
                     giftCardProducts.each { giftCardProduct ->
                         giftCardProductList.add(giftCardProduct);
@@ -51,6 +51,6 @@
 
 // Get Survey Id for Gift Certificates
 
-productStoreFinActSetting = delegator.findOne("ProductStoreFinActSetting", [productStoreId : productStoreId, finAccountTypeId : "GIFTCERT_ACCOUNT"], false);
+productStoreFinActSetting = from("ProductStoreFinActSetting").where("productStoreId", productStoreId, "finAccountTypeId", "GIFTCERT_ACCOUNT").queryOne();
 context.surveyId = productStoreFinActSetting.purchaseSurveyId;
 
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/AdditionalPartyListing.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/AdditionalPartyListing.groovy
index d372f18..a86e2b5 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/AdditionalPartyListing.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/AdditionalPartyListing.groovy
@@ -29,12 +29,12 @@
 partyData = [:];
 
 additionalPartyRole.each { roleTypeId, partyList ->
-    roleData[roleTypeId] = delegator.findOne("RoleType", [roleTypeId : roleTypeId], true);
+    roleData[roleTypeId] = from("RoleType").where("roleTypeId", roleTypeId).queryOne();
 
     partyList.each { partyId ->
         partyMap = [:];
         partyMap.partyId = partyId;
-        party = delegator.findOne("Party", [partyId : partyId], true);
+        party = from("Party").where("partyId", partyId).cache(true).queryOne();
         if (party.partyTypeId.equals("PERSON")) {
             party = party.getRelatedOne("Person", true);
             partyMap.type = "person";
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/BillSettings.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/BillSettings.groovy
index 06cf987..512f6fb 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/BillSettings.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/BillSettings.groovy
@@ -41,7 +41,7 @@
 }
 
 if (orderPartyId && !orderPartyId.equals("_NA_")) {
-    orderParty = delegator.findOne("Party", [partyId : orderPartyId], false);
+    orderParty = from("Party").where("partyId", orderPartyId).queryOne();
     orderPerson = orderParty.getRelatedOne("Person", false);
     context.orderParty = orderParty;
     context.orderPerson = orderPerson;
@@ -58,7 +58,7 @@
 
 if (request.getParameter("useShipAddr") && cart.getShippingContactMechId()) {
     shippingContactMech = cart.getShippingContactMechId();
-    postalAddress = delegator.findOne("PostalAddress", [contactMechId : shippingContactMech], false);
+    postalAddress = from("PostalAddress").where("contactMechId", shippingContactMech).queryOne();
     context.postalFields = postalAddress;
 } else {
     context.postalFields = UtilHttp.getParameterMap(request);
@@ -69,7 +69,7 @@
         checkOutPaymentId = cart.getPaymentMethodIds().get(0);
         context.checkOutPaymentId = checkOutPaymentId;
         if (!orderParty) {
-            paymentMethod = delegator.findOne("PaymentMethod", [paymentMethodId : checkOutPaymentId], false);
+            paymentMethod = from("PaymentMethod").where("paymentMethodId", checkOutPaymentId).queryOne();
             if ("CREDIT_CARD".equals(paymentMethod?.paymentMethodTypeId)) {
                 paymentMethodType = "CC";
                 account = paymentMethod.getRelatedOne("CreditCard", false);
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckInits.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckInits.groovy
index e87b1a9..17bee85 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckInits.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckInits.groovy
@@ -34,29 +34,29 @@
 if (productStore) {
     context.defaultProductStore = productStore;
     if (productStore.defaultSalesChannelEnumId)
-        context.defaultSalesChannel = delegator.findOne("Enumeration", [enumId : productStore.defaultSalesChannelEnumId], true);
+        context.defaultSalesChannel = from("Enumeration").where("enumId", productStore.defaultSalesChannelEnumId).cache(true).queryOne();
 }
 // Get the Cart
 shoppingCart = session.getAttribute("shoppingCart");
 context.shoppingCart = shoppingCart;
 
-salesChannels = delegator.findByAnd("Enumeration", [enumTypeId : "ORDER_SALES_CHANNEL"], ["sequenceId"], true);
+salesChannels = from("Enumeration").where("enumTypeId", "ORDER_SALES_CHANNEL").orderBy("sequenceId").cache(true).queryList();
 context.salesChannels = salesChannels;
 
-productStores = delegator.findList("ProductStore", null, null, ["productStoreId", "storeName"], null, true);
+productStores = from("ProductStore").orderBy("productStoreId", "storeName").cache(true).queryList();
 context.productStores = productStores;
 
-suppliers = delegator.findByAnd("PartyRoleAndPartyDetail", [roleTypeId : "SUPPLIER"], ["groupName", "partyId"], false);
+suppliers = from("PartyRoleAndPartyDetail").where("roleTypeId", "SUPPLIER").orderBy("groupName", "partyId").queryList();
 context.suppliers = suppliers;
 
-organizations = delegator.findByAnd("PartyAcctgPrefAndGroup", null, null, false);
+organizations = from("PartyAcctgPrefAndGroup").queryList();
 context.organizations = organizations;
 
 // Set Shipping From the Party 
 partyId = null;
 partyId = parameters.partyId;
 if (partyId) {
-    party = delegator.findOne("Person", [partyId : partyId], false);
+    party = from("Person").where("partyId", partyId).queryOne();
     if (party) {
         contactMech = EntityUtil.getFirst(ContactHelper.getContactMech(party, "SHIPPING_LOCATION", "POSTAL_ADDRESS", false));
         if (contactMech) {
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutOptions.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutOptions.groovy
index 4f04a2f..776aad8 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutOptions.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutOptions.groovy
@@ -28,7 +28,7 @@
 shoppingCart = session.getAttribute("shoppingCart");
 currencyUomId = shoppingCart.getCurrency();
 partyId = shoppingCart.getPartyId();
-party = delegator.findOne("Party", [partyId : partyId], true);
+party = from("Party").where("partyId", partyId).cache(true).queryOne();
 productStore = ProductStoreWorker.getProductStore(request);
 
 shippingEstWpr = null;
@@ -40,14 +40,14 @@
     shoppingCart.createDropShipGroups(dispatcher);    
 }
 
-profiledefs = delegator.findOne("PartyProfileDefault", [partyId : userLogin.partyId, productStoreId : productStoreId], false);
+profiledefs = from("PartyProfileDefault").where("partyId", userLogin.partyId, "productStoreId", productStoreId).queryOne();
 context.profiledefs = profiledefs;
 
 context.shoppingCart = shoppingCart;
 context.userLogin = userLogin;
 context.productStoreId = productStore.get("productStoreId");
 context.productStore = productStore;
-shipToParty = delegator.findOne("Party", [partyId : shoppingCart.getShipToCustomerPartyId()], true);
+shipToParty = from("Party").where("partyId", shoppingCart.getShipToCustomerPartyId()).cache(true).queryOne();
 context.shippingContactMechList = ContactHelper.getContactMech(shipToParty, "SHIPPING_LOCATION", "POSTAL_ADDRESS", false);
 context.emailList = ContactHelper.getContactMechByType(party, "EMAIL_ADDRESS", false);
 
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutPayment.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutPayment.groovy
index 06431e6..fcade34 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutPayment.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutPayment.groovy
@@ -28,7 +28,7 @@
 currencyUomId = cart.getCurrency();
 userLogin = session.getAttribute("userLogin");
 partyId = cart.getPartyId();
-party = delegator.findOne("Party", [partyId : partyId], true);
+party = from("Party").where("partyId", partyId).cache(true).queryOne();
 productStoreId = ProductStoreWorker.getProductStoreId(request);
 
 checkOutPaymentId = "";
@@ -40,9 +40,7 @@
     }
 }
 
-finAccounts = delegator.findByAnd("FinAccountAndRole", [partyId : partyId, roleTypeId : "OWNER"], null, false);
-finAccounts = EntityUtil.filterByDate(finAccounts, UtilDateTime.nowTimestamp(), "roleFromDate", "roleThruDate", true);
-finAccounts = EntityUtil.filterByDate(finAccounts);
+finAccounts = from("FinAccountAndRole").where("partyId", partyId, "roleTypeId", "OWNER").filterByDate(UtilDateTime.nowTimestamp(), "fromDate", "thruDate", "roleFromDate", "roleThruDate").queryList();
 context.finAccounts = finAccounts;
 
 context.shoppingCart = cart;
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutReview.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutReview.groovy
index 279f97e..bc06ce8 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutReview.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutReview.groovy
@@ -87,7 +87,7 @@
 paymentMethodTypeId = null;
 if (paymentMethodTypeIds) {
     paymentMethodTypeId = paymentMethodTypeIds.get(0);
-    paymentMethodType = delegator.findOne("PaymentMethodType", [paymentMethodTypeId : paymentMethodTypeId], false);
+    paymentMethodType = from("PaymentMethodType").where("paymentMethodTypeId", paymentMethodTypeId).queryOne();
     context.paymentMethodType = paymentMethodType;
 }
 
@@ -107,7 +107,7 @@
 }
 if (billingAddress) context.billingAddress = billingAddress;
 
-billingAccount = cart.getBillingAccountId() ? delegator.findOne("BillingAccount", [billingAccountId : cart.getBillingAccountId()], false) : null;
+billingAccount = cart.getBillingAccountId() ? from("BillingAccount").where("billingAccountId", cart.getBillingAccountId()).queryOne() : null;
 if (billingAccount) context.billingAccount = billingAccount;
 
 context.customerPoNumber = cart.getPoNumber();
@@ -120,7 +120,7 @@
 context.shipBeforeDate = cart.getShipBeforeDate();
 context.shipAfterDate = cart.getShipAfterDate();
 
-shipmentMethodType = delegator.findOne("ShipmentMethodType", [shipmentMethodTypeId : cart.getShipmentMethodTypeId()], false);
+shipmentMethodType = from("ShipmentMethodType").where("shipmentMethodTypeId", cart.getShipmentMethodTypeId()).queryOne();
 if (shipmentMethodType) context.shipMethDescription = shipmentMethodType.description;
 
 orh = new OrderReadHelper(orderAdjustments, orderItems);
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutShippingAddress.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutShippingAddress.groovy
index e660786..db6ca94 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutShippingAddress.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/CheckoutShippingAddress.groovy
@@ -44,11 +44,7 @@
     supplierPartyId = cart.getSupplierPartyId(shipGroupIndex);
     context[shipGroupIndex + "_supplierPartyId"] = supplierPartyId;
 }
-exprs = FastList.newInstance();
-exprs.add(EntityCondition.makeCondition("partyIdTo", EntityOperator.EQUALS, payToPartyId));
-exprs.add(EntityCondition.makeCondition("partyIdFrom", EntityOperator.EQUALS, partyId));
-agreements = delegator.findList("Agreement", EntityCondition.makeCondition(exprs, EntityOperator.AND), null, null, null, true);
-agreements = EntityUtil.filterByDate(agreements);
+agreements = from("Agreement").where("partyIdTo", payToPartyId, "partyIdFrom", partyId).filterByDate().cache(true).queryList();
 context.agreements = agreements;
 
 context.shoppingCart = cart;
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/OptionSettings.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/OptionSettings.groovy
index 44d9d3b..df030e4 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/OptionSettings.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/OptionSettings.groovy
@@ -30,7 +30,7 @@
 productStore = ProductStoreWorker.getProductStore(request);
 if (productStore) {
     context.productStore = productStore;
-    context.carrierShipmentMethodList = delegator.findByAnd('ProductStoreShipmentMethView', [productStoreId: productStore.productStoreId], ['sequenceNumber'], true);
+    context.carrierShipmentMethodList = from("ProductStoreShipmentMethView").where("productStoreId", productStore.productStoreId).orderBy("sequenceNumber").cache(true).queryList();
 }
 
 // nuke the event messages
@@ -39,7 +39,7 @@
 party = null;
 orderPartyIdId = cart.getPartyId();
 if (orderPartyIdId) {
-    orderPartyId = delegator.findOne("Party", [partyId : orderPartyIdId], false);
+    orderPartyId = from("Party").where("partyId", orderPartyIdId).queryOne();
     context.orderPartyId = orderPartyId;
 }
 
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/OrderAgreements.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/OrderAgreements.groovy
index 6290c64..715d877 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/OrderAgreements.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/OrderAgreements.groovy
@@ -64,13 +64,12 @@
 
 }
 
-agreements = delegator.findList('Agreement', agreementCondition, null, null, null, true);
-agreements = EntityUtil.filterByDate(agreements);
+agreements = from("Agreement").where(agreementCondition).filterByDate().cache(true).queryList();
 if (agreements) {
     context.agreements = agreements;
 }
 
-agreementRoles = delegator.findList('AgreementRole', agreementRoleCondition, null, null, null, true);
+agreementRoles = from("AgreementRole").where(agreementRoleCondition).cache(true).queryList();
 if (agreementRoles) {
     context.agreementRoles = agreementRoles;
 }
@@ -92,5 +91,5 @@
 }
 
 // currencies and shopping cart currency
-context.currencies = delegator.findByAnd('Uom', [uomTypeId: 'CURRENCY_MEASURE'], null, true);
+context.currencies = from("Uom").where("uomTypeId", "CURRENCY_MEASURE").cache(true).queryList();
 context.currencyUomId = shoppingCart.getCurrency();
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/OrderTerms.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/OrderTerms.groovy
index aa6303d..ccef13e 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/OrderTerms.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/OrderTerms.groovy
@@ -52,4 +52,4 @@
 
 }
 
-context.termTypes = delegator.findList('TermType', null, null, null, null, false);
+context.termTypes = from("TermType").queryList();
\ No newline at end of file
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/SetAdditionalParty.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/SetAdditionalParty.groovy
index 3708d6b..3b61477 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/SetAdditionalParty.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/SetAdditionalParty.groovy
@@ -32,7 +32,7 @@
     additionalPartyId = request.getParameter("additionalPartyId");
     context.additionalPartyId = additionalPartyId;
 
-    roles = delegator.findByAnd("PartyRole", [partyId : additionalPartyId], null, false);
+    roles = from("PartyRole").where("partyId", additionalPartyId).queryList();
     roleData = [];
     roles.each { role ->
         roleData.add(role.getRelatedOne("RoleType", false));
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/ShipSettings.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/ShipSettings.groovy
index 0804d6c..e2576c9 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/ShipSettings.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/ShipSettings.groovy
@@ -46,7 +46,7 @@
 
 if ("SALES_ORDER".equals(cart.getOrderType())) {
     if (!"_NA_".equals(orderPartyId)) {
-        orderParty = delegator.findOne("Party", [partyId : orderPartyId], false);
+        orderParty = from("Party").where("partyId", orderPartyId).queryOne();
         if (orderParty) {
             shippingContactMechList = ContactHelper.getContactMech(orderParty, "SHIPPING_LOCATION", "POSTAL_ADDRESS", false);
             orderPerson = orderParty.getRelatedOne("Person", false);
@@ -57,7 +57,7 @@
     }
     // Ship to another party
     if (shipToPartyId) {
-        shipToParty = delegator.findOne("Party", [partyId : shipToPartyId], false);
+        shipToParty = from("Party").where("partyId", shipToPartyId).queryOne();
         if (shipToParty) {
             context.shipToParty = shipToParty;
             shipToPartyShippingContactMechList = ContactHelper.getContactMech(shipToParty, "SHIPPING_LOCATION", "POSTAL_ADDRESS", false);
@@ -65,16 +65,16 @@
         }
     }
     // suppliers for the drop-ship select box
-    suppliers = delegator.findByAnd("PartyRole", [roleTypeId : "SUPPLIER"], null, false);
+    suppliers = from("PartyRole").where("roleTypeId", "SUPPLIER").queryList();
     context.suppliers = suppliers;
 
     // facilities used to reserve the items per ship group
-    productStoreFacilities = delegator.findByAnd("ProductStoreFacility", [productStoreId : cart.getProductStoreId()], null, false);
+    productStoreFacilities = from("ProductStoreFacility").where("productStoreId", cart.getProductStoreId()).queryList();
     context.productStoreFacilities = productStoreFacilities;
 } else {
     // Purchase order
     if (!"_NA_".equals(orderPartyId)) {
-        orderParty = delegator.findOne("Party", [partyId : orderPartyId], false);
+        orderParty = from("Party").where("partyId", orderPartyId).queryOne();
         if (orderParty) {
            orderPerson = orderParty.getRelatedOne("Person", false);
            context.orderParty = orderParty;
@@ -85,14 +85,14 @@
     companyId = cart.getBillToCustomerPartyId();
     if (companyId) {
         facilityMaps = FastList.newInstance();
-        facilities = delegator.findByAnd("Facility", [ownerPartyId : companyId], null, true);
+        facilities = from("Facility").where("ownerPartyId", companyId).cache(true).queryList();
 
         // if facilites is null then check the PartyRelationship where there is a relationship set for Parent & Child organization. Then also fetch the value of companyId from there.
         if (UtilValidate.isEmpty(facilities)) {
-            partyRelationship = EntityUtil.getFirst(delegator.findList("PartyRelationship", EntityCondition.makeCondition(["roleTypeIdFrom": "PARENT_ORGANIZATION", "partyIdTo": companyId]), null, null, null, false));
+            partyRelationship = from("PartyRelationship").where("roleTypeIdFrom": "PARENT_ORGANIZATION", "partyIdTo": companyId).queryFirst();
             if (UtilValidate.isNotEmpty(partyRelationship)) {
                 companyId = partyRelationship.partyIdFrom;
-                facilities = delegator.findByAnd("Facility", [ownerPartyId : companyId], null, true);
+                facilities = from("Facility").where("ownerPartyId", companyId).cache(true).queryList();
             }
         }
         facilities.each { facility ->
@@ -106,7 +106,7 @@
     }
     // Ship to another party
     if (shipToPartyId) {
-        shipToParty = delegator.findOne("Party", [partyId : shipToPartyId], false);
+        shipToParty = from("Party").where("partyId", shipToPartyId).queryOne();
         if (shipToParty)
         {
             context.shipToParty = shipToParty;
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/ShoppingList.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/ShoppingList.groovy
index 959f4f3..ba4ddd9 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/ShoppingList.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/ShoppingList.groovy
@@ -28,7 +28,7 @@
 partyId = shoppingCart.getPartyId();
 
 // Get the party's collection of Shopping Lists
-shoppingLists = delegator.findByAnd("ShoppingList", [partyId : partyId], null, true);
+shoppingLists = from("ShoppingList").where("partyId", partyId).cache(true).queryList();
 if (shoppingLists) {
     context.shoppingLists = shoppingLists;
 }
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/ShowCart.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/ShowCart.groovy
index b04f485..521a5f2 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/ShowCart.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/ShowCart.groovy
@@ -53,7 +53,7 @@
 context.orderType = shoppingCart.getOrderType();
 
 // get all the possible gift wrap options
-allgiftWraps = delegator.findByAnd("ProductFeature", [productFeatureTypeId : "GIFT_WRAP"], ["defaultSequenceNum"], false);
+allgiftWraps = from("ProductFeature").where("productFeatureTypeId", "GIFT_WRAP").orderBy("defaultSequenceNum").queryList();
 context.allgiftWraps = allgiftWraps;
 
 context.contentPathPrefix = CatalogWorker.getContentPathPrefix(request);
@@ -82,24 +82,24 @@
 
 // get all party shopping lists
 if (partyId) {
-  shoppingLists = delegator.findByAnd("ShoppingList", [partyId : partyId], null, false);
+  shoppingLists = from("ShoppingList").where("partyId", partyId).queryList();
   context.shoppingLists = shoppingLists;
 }
 
 // get product inventory summary for each shopping cart item
-productStore = delegator.findOne("ProductStore", [productStoreId : productStoreId], true);
+productStore = from("ProductStore").where("productStoreId", productStoreId).cache(true).queryOne();
 context.productStore = productStore
 productStoreFacilityId = null;
 if (productStore) {
     productStoreFacilityId = productStore.inventoryFacilityId;
 }
 context.facilityId = productStoreFacilityId;
-inventorySummary = dispatcher.runSync("getProductInventorySummaryForItems", [orderItems : shoppingCart.makeOrderItems(), facilityId : productStoreFacilityId]);
+inventorySummary = runService('getProductInventorySummaryForItems', [orderItems : shoppingCart.makeOrderItems(), facilityId : productStoreFacilityId]);
 context.availableToPromiseMap = inventorySummary.availableToPromiseMap;
 context.quantityOnHandMap = inventorySummary.quantityOnHandMap;
 context.mktgPkgATPMap = inventorySummary.mktgPkgATPMap;
 context.mktgPkgQOHMap = inventorySummary.mktgPkgQOHMap;
 
 // get purchase order item types
-purchaseOrderItemTypeList = delegator.findByAnd("OrderItemType", [parentTypeId : "PURCHASE_SPECIFIC"], null, true);
+purchaseOrderItemTypeList = from("OrderItemType").where("parentTypeId", "PURCHASE_SPECIFIC").cache(true).queryList();
 context.purchaseOrderItemTypeList = purchaseOrderItemTypeList;
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/SplitShip.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/SplitShip.groovy
index 65f00e3..e7e9409 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/SplitShip.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/SplitShip.groovy
@@ -22,11 +22,12 @@
 
 shoppingCart = session.getAttribute("shoppingCart");
 partyId = shoppingCart.getPartyId();
-party = delegator.findOne("Party", [partyId : partyId], true);
+party = from("Party").where("partyId", partyId).cache(true).queryOne();
 productStoreId = ProductStoreWorker.getProductStoreId(request);
 
 context.cart = shoppingCart;
 context.shippingContactMechList = ContactHelper.getContactMech(party, "SHIPPING_LOCATION", "POSTAL_ADDRESS", false);
 
-profiledefs = delegator.findOne("PartyProfileDefault", [partyId : partyId, productStoreId : productStoreId], true);
+profiledefs = from("PartyProfileDefault").where("partyId", partyId, "productStoreId", productStoreId).cache(true).queryOne();
+
 context.profileDefs = profiledefs;
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/cart/LookupBulkAddProducts.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/cart/LookupBulkAddProducts.groovy
index ada2d5e..0d1ffea 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/cart/LookupBulkAddProducts.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/cart/LookupBulkAddProducts.groovy
@@ -50,6 +50,5 @@
 
 mainConditionList.add(orConditions);
 mainConditionList.add(conditions);
-mainConditions = EntityCondition.makeCondition(mainConditionList, EntityOperator.AND);
 
-context.productList = delegator.findList("Product", mainConditions, ["productId", "brandName", "internalName"] as Set, ["productId"], null, false);
+context.productList = select("productId", "brandName", "internalName").from("Product").where(mainConditionList).orderBy("productId").queryList();
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/cart/LookupBulkAddSupplierProducts.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/cart/LookupBulkAddSupplierProducts.groovy
index a38c969..e8eb927 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/cart/LookupBulkAddSupplierProducts.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/cart/LookupBulkAddSupplierProducts.groovy
@@ -48,11 +48,9 @@
 
 orderId = parameters.orderId;
 if (orderId) {
-    orderItemShipGroup = EntityUtil.getFirst(delegator.findList("OrderItemShipGroup", null, null, ["orderId" , "orderId"], null, false));
-    orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
-    EntityCondition cond = EntityCondition.makeCondition([EntityCondition.makeCondition("orderId", orderId),
-            EntityCondition.makeCondition("roleTypeId", "BILL_FROM_VENDOR")], EntityOperator.AND);
-    supplier = EntityUtil.getFirst(delegator.findList("OrderHeaderAndRoles", cond, null, null, null, false));
+    orderItemShipGroup = from("OrderItemShipGroup").orderBy("orderId").queryFirst();
+    orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
+    supplier = from("OrderHeaderAndRoles").where("orderId", orderId, "roleTypeId", "BILL_FROM_VENDOR").queryFirst();
     context.shipGroupSeqId =  orderItemShipGroup.shipGroupSeqId ;
     context.orderHeader = orderHeader;
 }
@@ -75,10 +73,11 @@
 
 conditionList.add(EntityCondition.makeCondition("currencyUomId", EntityOperator.EQUALS, shoppingCart.getCurrency()));
 conditionList.add(EntityCondition.makeConditionDate("availableFromDate", "availableThruDate"));
-conditions = EntityCondition.makeCondition(conditionList, EntityOperator.AND);
 
-selectedFields = ["productId", "supplierProductId", "supplierProductName", "lastPrice", "minimumOrderQuantity", "orderQtyIncrements"] as Set;
-supplierProducts = delegator.findList("SupplierProduct", conditions, selectedFields, ["productId"], null, false);
+supplierProducts = select("productId", "supplierProductId", "supplierProductName", "lastPrice", "minimumOrderQuantity", "orderQtyIncrements").from("SupplierProduct")
+                    .where(conditionList)
+                    .orderBy("productId")
+                    .queryList();
 
 newProductList = [];
 for (supplierProduct in supplierProducts) {
@@ -86,9 +85,9 @@
 
     String facilityId = parameters.facilityId;
     if (facilityId) {
-        productFacilityList = delegator.findByAnd("ProductFacility", ["productId": productId, "facilityId" : facilityId], null, true);
+        productFacilityList = from("ProductFacility").where("productId", productId, "facilityId", facilityId).cache(true).queryList();
     } else {
-        productFacilityList = delegator.findByAnd("ProductFacility", ["productId": productId], null, true);
+        productFacilityList = from("ProductFacility").where("productId", productId).cache(true).queryList();
     }
     if (newProductList.size() >= maxRows) {
         // We've got enough results to display, keep going to get the result size but skip the heavy stuff
@@ -96,10 +95,7 @@
     } else {
         quantityOnOrder = 0.0;
         // find approved purchase orders
-        condition = EntityCondition.makeCondition(EntityCondition.makeCondition("orderTypeId", "PURCHASE_ORDER"), EntityOperator.AND,
-                EntityCondition.makeCondition("statusId", "ORDER_APPROVED"));
-    
-        orderHeaders = delegator.findList("OrderHeader", condition, null, ["orderId DESC"], null, false);
+        orderHeaders = from("OrderHeader").where("orderTypeId", "PURCHASE_ORDER", "statusId", "ORDER_APPROVED").orderBy("orderId DESC").queryList();
         orderHeaders.each { orderHeader ->
             orderReadHelper = new OrderReadHelper(orderHeader);
             orderItems = orderReadHelper.getOrderItems();
@@ -113,9 +109,9 @@
                 }
             }
         }
-        product = delegator.findOne("Product", ["productId" : productId], true);
+        product = from("Product").where("productId", productId).cache(true).queryOne();
         productFacilityList.each { productFacility ->
-            result = dispatcher.runSync("getInventoryAvailableByFacility", ["productId" : productId, "facilityId" : productFacility.facilityId]);
+            result = runService('getInventoryAvailableByFacility', ["productId" : productId, "facilityId" : productFacility.facilityId]);
             qohAtp = result.quantityOnHandTotal.toPlainString() + "/" + result.availableToPromiseTotal.toPlainString();
             productInfoMap = [:];
             
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/cart/ShowPromotionDetails.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/cart/ShowPromotionDetails.groovy
index 2425aa8..392fc4e 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/cart/ShowPromotionDetails.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/cart/ShowPromotionDetails.groovy
@@ -23,11 +23,11 @@
 
 productPromoId = request.getParameter("productPromoId");
 if (!productPromoId) productPromoId = parameters.productPromoId;
-productPromo = delegator.findOne("ProductPromo", [productPromoId : productPromoId], false);
+productPromo = from("ProductPromo").where("productPromoId", productPromoId).queryOne();
 
 promoAutoDescription = ProductPromoWorker.makeAutoDescription(productPromo, delegator, locale);
 
-productPromoCategoryList = delegator.findByAnd("ProductPromoCategory", [productPromoId : productPromoId], null, true);
+productPromoCategoryList = from("ProductPromoCategory").where("productPromoId", productPromoId).cache(true).queryList();
 productPromoCategoryIncludeList = EntityUtil.filterByAnd(productPromoCategoryList, [productPromoApplEnumId : "PPPA_INCLUDE"]);
 productPromoCategoryExcludeList = EntityUtil.filterByAnd(productPromoCategoryList, [productPromoApplEnumId : "PPPA_EXCLUDE"]);
 productPromoCategoryAlwaysList = EntityUtil.filterByAnd(productPromoCategoryList, [productPromoApplEnumId : "PPPA_ALWAYS"]);
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/AdvancedSearchOptions.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/AdvancedSearchOptions.groovy
index d9423c9..e04bd8b 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/AdvancedSearchOptions.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/AdvancedSearchOptions.groovy
@@ -34,12 +34,12 @@
     currentCatalogId = CatalogWorker.getCurrentCatalogId(request);
     searchCategoryId = CatalogWorker.getCatalogSearchCategoryId(request, currentCatalogId);
 }
-searchCategory = delegator.findOne("ProductCategory", [productCategoryId : searchCategoryId], false);
+searchCategory = from("ProductCategory").where("productCategoryId", searchCategoryId).queryOne();
 
 productFeaturesByTypeMap = ParametricSearch.makeCategoryFeatureLists(searchCategoryId, delegator);
 productFeatureTypeIdsOrdered = new TreeSet(productFeaturesByTypeMap.keySet()) as List;
 if(productFeatureTypeIdsOrdered) {
-    context.productFeatureTypes = delegator.findList("ProductFeatureType", EntityCondition.makeCondition("productFeatureTypeId", EntityOperator.IN, productFeatureTypeIdsOrdered), null, null, null, false);
+    context.productFeatureTypes = from("ProductFeatureType").where(EntityCondition.makeCondition("productFeatureTypeId", EntityOperator.IN, productFeatureTypeIdsOrdered)).queryList();
 }
 
 searchOperator = parameters.SEARCH_OPERATOR;
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/Category.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/Category.groovy
index ef60d8e..984a702 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/Category.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/Category.groovy
@@ -60,22 +60,22 @@
 }
  */
 
-category = delegator.findOne("ProductCategory", [productCategoryId : productCategoryId], true);
+category = from("ProductCategory").where("productCategoryId", productCategoryId).cache(true).queryOne();
 if (category) {
     if (category.detailScreen) {
         detailScreen = category.detailScreen;
     }
-    categoryPageTitle = delegator.findByAnd("ProductCategoryContentAndInfo", [productCategoryId : productCategoryId, prodCatContentTypeId : "PAGE_TITLE"], null, true);
+    categoryPageTitle = from("ProductCategoryContentAndInfo").where("productCategoryId", productCategoryId, "prodCatContentTypeId", "PAGE_TITLE").cache(true).queryList();
     if (categoryPageTitle) {
-        pageTitle = delegator.findOne("ElectronicText", [dataResourceId : categoryPageTitle.get(0).dataResourceId], true);
+        pageTitle = from("ElectronicText").where("dataResourceId", categoryPageTitle.get(0).dataResourceId).cache(true).queryOne();
     }
-    categoryMetaDescription = delegator.findByAnd("ProductCategoryContentAndInfo", [productCategoryId : productCategoryId, prodCatContentTypeId : "META_DESCRIPTION"], null, true);
+    categoryMetaDescription = from("ProductCategoryContentAndInfo").where("productCategoryId", productCategoryId, "prodCatContentTypeId", "META_DESCRIPTION").cache(true).queryList();
     if (categoryMetaDescription) {
-        metaDescription = delegator.findOne("ElectronicText", [dataResourceId : categoryMetaDescription.get(0).dataResourceId], true);
+        metaDescription = from("ElectronicText").where("dataResourceId", categoryMetaDescription.get(0).dataResourceId).cache(true).queryOne();
     }
-    categoryMetaKeywords = delegator.findByAnd("ProductCategoryContentAndInfo", [productCategoryId : productCategoryId, prodCatContentTypeId : "META_KEYWORD"], null, true);
+    categoryMetaKeywords = from("ProductCategoryContentAndInfo").where("productCategoryId", productCategoryId, "prodCatContentTypeId", "META_KEYWORD").cache(true).queryList();
     if (categoryMetaKeywords) {
-        metaKeywords = delegator.findOne("ElectronicText", [dataResourceId : categoryMetaKeywords.get(0).dataResourceId], true);
+        metaKeywords = from("ElectronicText").where("dataResourceId", categoryMetaKeywords.get(0).dataResourceId).cache(true).queryOne();
     }
     categoryContentWrapper = new CategoryContentWrapper(category, request);
     
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CategoryDetail.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CategoryDetail.groovy
index a77ca2e..14d74fe 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CategoryDetail.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CategoryDetail.groovy
@@ -39,7 +39,7 @@
 currentCatalogId = CatalogWorker.getCurrentCatalogId(request);
 
 // set the default view size
-defaultViewSize = request.getAttribute("defaultViewSize") ?: UtilProperties.getPropertyValue("widget", "widget.form.defaultViewSize", "20");
+defaultViewSize = request.getAttribute("defaultViewSize") ?: EntityUtilProperties.getPropertyValue("widget", "widget.form.defaultViewSize", "20", delegator);
 context.defaultViewSize = defaultViewSize;
 
 // set the limit view
@@ -64,7 +64,7 @@
 } else {
     andMap.put("orderByFields", ["sequenceNum", "productId"]);
 }
-catResult = dispatcher.runSync("getProductCategoryAndLimitedMembers", andMap);
+catResult = runService('getProductCategoryAndLimitedMembers', andMap);
 productCategory = catResult.productCategory;
 productCategoryMembers = catResult.productCategoryMembers;
 context.productCategoryMembers = productCategoryMembers;
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CompareProducts.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CompareProducts.groovy
index 24b706f..6fd6a65 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CompareProducts.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/CompareProducts.groovy
@@ -54,15 +54,14 @@
     priceContext.agreementId = cart.getAgreementId();
     priceContext.partyId = cart.getPartyId();  // IMPORTANT: otherwise it'll be calculating prices using the logged in user which could be a CSR instead of the customer
     priceContext.checkIncludeVat = "Y";
-    productData.priceMap = dispatcher.runSync("calculateProductPrice", priceContext);
+    productData.priceMap = runService('calculateProductPrice', priceContext);
     
     condList = [
                 EntityCondition.makeCondition("productId", product.productId),
                 EntityUtil.getFilterByDateExpr(),
                 EntityCondition.makeCondition("productFeatureApplTypeId", EntityOperator.IN, ["STANDARD_FEATURE", "DISTINGUISHING_FEAT", "SELECTABLE_FEATURE"])
                ];
-    cond = EntityCondition.makeCondition(condList);
-    productFeatureAppls = delegator.findList("ProductFeatureAppl", cond, null, ["sequenceNum"], null, true);
+    productFeatureAppls = from("ProductFeatureAppl").where(condList).orderBy("sequenceNum").cache(true).queryList();
     productFeatureAppls.each { productFeatureAppl ->
         productFeature = productFeatureAppl.getRelatedOne("ProductFeature", true);
         if (!productData[productFeature.productFeatureTypeId]) {
@@ -76,5 +75,5 @@
     } 
 }
 productFeatureTypeIds.each { productFeatureTypeId ->
-    productFeatureTypeMap[productFeatureTypeId] = delegator.findOne("ProductFeatureType", [productFeatureTypeId : productFeatureTypeId], true);
+    productFeatureTypeMap[productFeatureTypeId] = from("ProductFeatureType").where("productFeatureTypeId", productFeatureTypeId).cache(true).queryOne();
 }
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/InlineProductDetail.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/InlineProductDetail.groovy
index b28cbd8..b623879 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/InlineProductDetail.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/InlineProductDetail.groovy
@@ -47,7 +47,7 @@
 currentCatalogId = CatalogWorker.getCurrentCatalogId(request);
 
 if (inlineProductId) {
-    inlineProduct = delegator.findOne("Product", [productId : inlineProductId], true);
+    inlineProduct = from("Product").where("productId", inlineProductId).cache(true).queryOne();
     if (inlineProduct) {
         context.product = inlineProduct;
         contentWrapper = new ProductContentWrapper(inlineProduct, request);
@@ -134,13 +134,13 @@
         priceContext.checkIncludeVat = "Y";
         priceContext.agreementId = cart.getAgreementId();
         priceContext.partyId = cart.getPartyId();  // IMPORTANT: must put this in, or price will be calculated for the CSR instead of the customer
-        priceMap = dispatcher.runSync("calculateProductPrice", priceContext);
+        priceMap = runService('calculateProductPrice', priceContext);
         context.priceMap = priceMap;
     } else {
         // purchase order: run the "calculatePurchasePrice" service
         priceContext = [product : inlineProduct, currencyUomId : cart.getCurrency(),
                 partyId : cart.getPartyId(), userLogin : userLogin];
-        priceMap = dispatcher.runSync("calculatePurchasePrice", priceContext);
+        priceMap = runService('calculatePurchasePrice', priceContext);
         context.priceMap = priceMap;
     }
 
@@ -154,10 +154,10 @@
         if ("VV_FEATURETREE".equals(ProductWorker.getProductVirtualVariantMethod(delegator, inlineProductId))) {
             context.featureLists = ProductWorker.getSelectableProductFeaturesByTypesAndSeq(inlineProduct);
         } else {
-            featureMap = dispatcher.runSync("getProductFeatureSet", [productId : inlineProductId]);
+            featureMap = runService("getProductFeatureSet", [productId : inlineProductId]);
             featureSet = featureMap.featureSet;
             if (featureSet) {
-                variantTreeMap = dispatcher.runSync("getProductVariantTree", [productId : inlineProductId, featureOrder : featureSet, productStoreId : productStoreId]);
+                variantTreeMap = runService('getProductVariantTree', [productId : inlineProductId, featureOrder : featureSet, productStoreId : productStoreId]);
                 variantTree = variantTreeMap.variantTree;
                 imageMap = variantTreeMap.variantSample;
                 virtualVariant = variantTreeMap.virtualVariant;
@@ -176,7 +176,7 @@
                 if (variantTree) {
                     featureOrder = new LinkedList(featureSet);
                     featureOrder.each { featureKey ->
-                        featureValue = delegator.findOne("ProductFeatureType", [productFeatureTypeId : featureKey], true);
+                        featureValue = from("ProductFeatureType").where("productFeatureTypeId", featureKey).cache(true).queryOne();
                         fValue = featureValue.get("description") ?: featureValue.productFeatureTypeId;
                         featureTypes[featureKey] = fValue;
                     }
@@ -268,7 +268,7 @@
                     }
 
                     // make a list of variant sku with requireAmount
-                    variantsRes = dispatcher.runSync("getAssociatedProducts", [productId : inlineProductId, type : "PRODUCT_VARIANT", checkViewAllow : true, prodCatalogId : currentCatalogId]);
+                    variantsRes = runService('getAssociatedProducts', [productId : inlineProductId, type : "PRODUCT_VARIANT", checkViewAllow : true, prodCatalogId : currentCatalogId]);
                     variants = variantsRes.assocProducts;
                     if (variants) {
                         amt = new StringBuffer();
@@ -289,7 +289,7 @@
                             if (cart.isSalesOrder()) {
                                 // sales order: run the "calculateProductPrice" service
                                 priceContext.product = variant;
-                                variantPriceMap = dispatcher.runSync("calculateProductPrice", priceContext);
+                                variantPriceMap = runService('calculateProductPrice', priceContext);
                             }
                             amt.append(" if (sku == \"" + variant.productId + "\") return \"" + (variant.requireAmount ?: "N") + "\"; ");
                             variantPriceJS.append("  if (sku == \"" + variant.productId + "\") return \"" + numberFormat.format(variantPriceMap.basePrice) + "\"; ");
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/Product.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/Product.groovy
index 5428f47..22c8b09 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/Product.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/Product.groovy
@@ -42,12 +42,11 @@
 
 // get the product entity
 if (productId) {
-    product = delegator.findOne("Product", [productId : productId], true);
+    product = from("Product").where("productId", productId).cache(true).queryOne();
     if (product) {
         // first make sure this isn't a virtual-variant that has an associated virtual product, if it does show that instead of the variant
         if("Y".equals(product.isVirtual) && "Y".equals(product.isVariant)){
-            virtualVariantProductAssocs = delegator.findByAnd("ProductAssoc", ["productId": productId, "productAssocTypeId": "ALTERNATIVE_PACKAGE"], ["-fromDate"], true);
-            virtualVariantProductAssocs = EntityUtil.filterByDate(virtualVariantProductAssocs);
+            virtualVariantProductAssocs = from("ProductAssoc").where("productId", productId, "productAssocTypeId", "ALTERNATIVE_PACKAGE").orderBy("-fromDate").filterByDate().cache(true).queryList();
             if (virtualVariantProductAssocs) {
                 productAssoc = EntityUtil.getFirst(virtualVariantProductAssocs);
                 product = productAssoc.getRelatedOne("AssocProduct", true);
@@ -59,20 +58,20 @@
     virtualProductId = ProductWorker.getVariantVirtualId(product);
     if (virtualProductId) {
         productId = virtualProductId;
-        product = delegator.findOne("Product", [productId : productId], true);
+        product = from("Product").where("productId", productId).cache(true).queryOne();
     }
 
-    productPageTitle = delegator.findByAnd("ProductContentAndInfo", [productId : productId, productContentTypeId : "PAGE_TITLE"], null, true);
+    productPageTitle = from("ProductContentAndInfo").where("productId", productId, "productContentTypeId", "PAGE_TITLE").cache(true).queryList();
     if (productPageTitle) {
-        pageTitle = delegator.findOne("ElectronicText", [dataResourceId : productPageTitle.get(0).dataResourceId], true);
+        pageTitle = from("ElectronicText").where("dataResourceId", productPageTitle.get(0).dataResourceId).cache(true).queryOne();
     }
-    productMetaDescription = delegator.findByAnd("ProductContentAndInfo", [productId : productId, productContentTypeId : "META_DESCRIPTION"], null, true);
+    productMetaDescription = from("ProductContentAndInfo").where("productId", productId, "productContentTypeId", "META_DESCRIPTION").cache(true).queryList();
     if (productMetaDescription) {
-        metaDescription = delegator.findOne("ElectronicText", [dataResourceId : productMetaDescription.get(0).dataResourceId], true);
+        metaDescription = from("ElectronicText").where("dataResourceId", productMetaDescription.get(0).dataResourceId).cache(true).queryOne();
     }
-    productMetaKeywords = delegator.findByAnd("ProductContentAndInfo", [productId : productId, productContentTypeId : "META_KEYWORD"], null, true);
+    productMetaKeywords = from("ProductContentAndInfo").where("productId", productId, "productContentTypeId", "META_KEYWORD").cache(true).queryList();
     if (productMetaKeywords) {
-        metaKeywords = delegator.findOne("ElectronicText", [dataResourceId : productMetaKeywords.get(0).dataResourceId], true);
+        metaKeywords = from("ElectronicText").where("dataResourceId", productMetaKeywords.get(0).dataResourceId).cache(true).queryOne();
     }
 
     context.productId = productId;
@@ -110,7 +109,7 @@
             keywords = [];
             keywords.add(contentWrapper.get("PRODUCT_NAME"));
             keywords.add(catalogName);
-            members = delegator.findByAnd("ProductCategoryMember", [productId : productId], null, true);
+            members = from("ProductCategoryMember").where("productId", productId).cache(true).queryList();
             members.each { member ->
                 category = member.getRelatedOne("ProductCategory", true);
                 if (category.description) {
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy
index 17fb02c..ce47d06 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy
@@ -83,8 +83,7 @@
 if (userLogin) {
     exprList = [EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, userLogin.partyId),
                 EntityCondition.makeCondition("listName", EntityOperator.NOT_EQUAL, "auto-save")];
-    condition = EntityCondition.makeCondition(exprList, EntityOperator.AND);
-    allShoppingLists = delegator.findList("ShoppingList", condition, null, ["listName"], null, false);
+    allShoppingLists = from("ShoppingList").where(exprList).orderBy("listName").queryList();
     context.shoppingLists = allShoppingLists;
 }
 
@@ -136,7 +135,7 @@
     if (categoryId) {
         prevNextMap = [categoryId : categoryId, productId : productId];
         prevNextMap.orderByFields = context.orderByFields ?: ["sequenceNum", "productId"];
-        catNextPreviousResult = dispatcher.runSync("getPreviousNextProducts", prevNextMap);
+        catNextPreviousResult = runService('getPreviousNextProducts', prevNextMap);
         if (ServiceUtil.isError(catNextPreviousResult)) {
             request.setAttribute("errorMessageList", [ServiceUtil.getErrorMessage(catNextPreviousResult)]);
             return;
@@ -182,13 +181,13 @@
         priceContext.checkIncludeVat = "Y";
         priceContext.agreementId = cart.getAgreementId();
         priceContext.partyId = cart.getPartyId();  // IMPORTANT: must put this in, or price will be calculated for the CSR instead of the customer
-        priceMap = dispatcher.runSync("calculateProductPrice", priceContext);
+        priceMap = runService('calculateProductPrice', priceContext);
         context.priceMap = priceMap;
     } else {
         // purchase order: run the "calculatePurchasePrice" service
         priceContext = [product : product, currencyUomId : cart.getCurrency(),
                 partyId : cart.getPartyId(), userLogin : userLogin];
-        priceMap = dispatcher.runSync("calculatePurchasePrice", priceContext);
+        priceMap = runService('calculatePurchasePrice', priceContext);
         context.priceMap = priceMap;
     }
 
@@ -219,15 +218,14 @@
         context.daysToShip = productFacility?.daysToShip
         */
 
-        resultOutput = dispatcher.runSync("getInventoryAvailableByFacility", [productId : productId, facilityId : facilityId, useCache : false]);
+        resultOutput = runService('getInventoryAvailableByFacility', [productId : productId, facilityId : facilityId, useCache : false]);
         totalAvailableToPromise = resultOutput.availableToPromiseTotal;
         if (totalAvailableToPromise) {
-            productFacility = delegator.findOne("ProductFacility", [productId : productId, facilityId : facilityId], true);
+            productFacility = from("ProductFacility").where("productId", productId, "facilityId", facilityId).cache(true).queryOne();
             context.daysToShip = productFacility?.daysToShip
         }
     } else {
-       supplierProducts = delegator.findByAnd("SupplierProduct", [productId : productId], ["-availableFromDate"], true);
-       supplierProduct = EntityUtil.getFirst(supplierProducts);
+       supplierProduct = from("SupplierProduct").where("productId", productId).orderBy("-availableFromDate").cache(true).queryFirst();
        if (supplierProduct?.standardLeadTimeDays) {
            standardLeadTimeDays = supplierProduct.standardLeadTimeDays;
            daysToShip = standardLeadTimeDays + 1;
@@ -236,12 +234,12 @@
     }
 
     // get the product distinguishing features
-    disFeatureMap = dispatcher.runSync("getProductFeatures", [productId : productId, type : "DISTINGUISHING_FEAT"]);
+    disFeatureMap = runService('getProductFeatures', [productId : productId, type : "DISTINGUISHING_FEAT"]);
     disFeatureList = disFeatureMap.productFeatures;
     context.disFeatureList = disFeatureList;
 
     // an example of getting features of a certain type to show
-    sizeProductFeatureAndAppls = delegator.findByAnd("ProductFeatureAndAppl", [productId : productId, productFeatureTypeId : "SIZE"], ["sequenceNum", "defaultSequenceNum"], false);
+    sizeProductFeatureAndAppls = from("ProductFeatureAndAppl").where("productId", productId, "productFeatureTypeId", "SIZE").orderBy("sequenceNum", "defaultSequenceNum").queryList();
     context.sizeProductFeatureAndAppls = sizeProductFeatureAndAppls;
     
     // get product variant for Box/Case/Each
@@ -249,7 +247,7 @@
     boolean isAlternativePacking = ProductWorker.isAlternativePacking(delegator, product.productId, null);
     mainProducts = [];
     if(isAlternativePacking){
-        productVirtualVariants = delegator.findByAnd("ProductAssoc", UtilMisc.toMap("productIdTo", product.productId , "productAssocTypeId", "ALTERNATIVE_PACKAGE"), null, true);
+        productVirtualVariants = from("ProductAssoc").where("productIdTo", product.productId , "productAssocTypeId", "ALTERNATIVE_PACKAGE").cache(true).queryList();
         if(productVirtualVariants){
             productVirtualVariants.each { virtualVariantKey ->
                 mainProductMap = [:];
@@ -269,14 +267,14 @@
         if ("VV_FEATURETREE".equals(ProductWorker.getProductVirtualVariantMethod(delegator, productId))) {
             context.featureLists = ProductWorker.getSelectableProductFeaturesByTypesAndSeq(product);
         } else {
-            featureMap = dispatcher.runSync("getProductFeatureSet", [productId : productId]);
+            featureMap = runService('getProductFeatureSet', [productId : productId]);
             featureSet = featureMap.featureSet;
             if (featureSet) {
                 //if order is purchase then don't calculate available inventory for product.
                 if (cart.isPurchaseOrder()) {
-                    variantTreeMap = dispatcher.runSync("getProductVariantTree", [productId : productId, featureOrder : featureSet, checkInventory: false]);
+                    variantTreeMap = runService('getProductVariantTree', [productId : productId, featureOrder : featureSet, checkInventory: false]);
                 } else {
-                    variantTreeMap = dispatcher.runSync("getProductVariantTree", [productId : productId, featureOrder : featureSet, productStoreId : productStoreId]);
+                    variantTreeMap = runService('getProductVariantTree', [productId : productId, featureOrder : featureSet, productStoreId : productStoreId]);
                 }
                 variantTree = variantTreeMap.variantTree;
                 imageMap = variantTreeMap.variantSample;
@@ -300,7 +298,7 @@
                 if (variantTree) {
                     featureOrder = new LinkedList(featureSet);
                     featureOrder.each { featureKey ->
-                        featureValue = delegator.findOne("ProductFeatureType", [productFeatureTypeId : featureKey], true);
+                        featureValue = from("ProductFeatureType").where("productFeatureTypeId", featureKey).cache(true).queryOne();
                         fValue = featureValue.get("description") ?: featureValue.productFeatureTypeId;
                         featureTypes[featureKey] = fValue;
                     }
@@ -392,7 +390,7 @@
                     }
 
                     // make a list of variant sku with requireAmount
-                    variantsRes = dispatcher.runSync("getAssociatedProducts", [productId : productId, type : "PRODUCT_VARIANT", checkViewAllow : true, prodCatalogId : currentCatalogId]);
+                    variantsRes = runService('getAssociatedProducts', [productId : productId, type : "PRODUCT_VARIANT", checkViewAllow : true, prodCatalogId : currentCatalogId]);
                     variants = variantsRes.assocProducts;
                     variantPriceList = [];
                     if (variants) {
@@ -414,7 +412,7 @@
                             priceContext.product = variant;
                             if (cart.isSalesOrder()) {
                                 // sales order: run the "calculateProductPrice" service
-                                variantPriceMap = dispatcher.runSync("calculateProductPrice", priceContext);
+                                variantPriceMap = runService('calculateProductPrice', priceContext);
                                 BigDecimal calculatedPrice = (BigDecimal)variantPriceMap.get("price");
                                 // Get the minimum quantity for variants if MINIMUM_ORDER_PRICE is set for variants.
                                 variantPriceMap.put("minimumQuantity", ShoppingCart.getMinimumOrderQuantity(delegator, calculatedPrice, variant.get("productId")));
@@ -440,7 +438,7 @@
                                 }
                                 variantPriceList.add(variantPriceMap);
                             } else {
-                                variantPriceMap = dispatcher.runSync("calculatePurchasePrice", priceContext);
+                                variantPriceMap = runService('calculatePurchasePrice', priceContext);
                             }
                             amt.append(" if (sku == \"" + variant.productId + "\") return \"" + (variant.requireAmount ?: "N") + "\"; ");
                             if (variantPriceMap && variantPriceMap.basePrice) {
@@ -448,7 +446,7 @@
                             }
                             
                             // make a list of virtual variants sku with requireAmount
-                            virtualVariantsRes = dispatcher.runSync("getAssociatedProducts", [productIdTo : variant.productId, type : "ALTERNATIVE_PACKAGE", checkViewAllow : true, prodCatalogId : currentCatalogId]);
+                            virtualVariantsRes = runService('getAssociatedProducts', [productIdTo : variant.productId, type : "ALTERNATIVE_PACKAGE", checkViewAllow : true, prodCatalogId : currentCatalogId]);
                             virtualVariants = virtualVariantsRes.assocProducts;
                             
                             if(virtualVariants){
@@ -458,7 +456,7 @@
                                     priceContext.product = virtual;
                                     if (cart.isSalesOrder()) {
                                         // sales order: run the "calculateProductPrice" service
-                                        virtualPriceMap = dispatcher.runSync("calculateProductPrice", priceContext);
+                                        virtualPriceMap = runService('calculateProductPrice', priceContext);
                                         BigDecimal calculatedPrice = (BigDecimal)virtualPriceMap.get("price");
                                         // Get the minimum quantity for variants if MINIMUM_ORDER_PRICE is set for variants.
                                         virtualPriceMap.put("minimumQuantity", ShoppingCart.getMinimumOrderQuantity(delegator, calculatedPrice, virtual.get("productId")));
@@ -485,7 +483,7 @@
                                         variantPriceList.add(virtualPriceMap);
                                         variantPriceJS.append("  if (sku == \"" + virtual.productId + "\") return \"" + UtilFormatOut.formatCurrency(variantPriceMap.basePrice, currencyUomId, locale, 10) + "\"; ");
                                     } else {
-                                        virtualPriceMap = dispatcher.runSync("calculatePurchasePrice", priceContext);
+                                        virtualPriceMap = runService('calculatePurchasePrice', priceContext);
                                         variantPriceJS.append("  if (sku == \"" + virtual.productId + "\") return \"" + UtilFormatOut.formatCurrency(variantPriceMap.price, currencyUomId, locale, 10) + "\"; ");
                                     }
                                 }
@@ -512,7 +510,7 @@
             jsBuf.append("<script language=\"JavaScript\" type=\"text/javascript\">");
             
             // make a list of variant sku with requireAmount
-            virtualVariantsRes = dispatcher.runSync("getAssociatedProducts", [productIdTo : productId, type : "ALTERNATIVE_PACKAGE", checkViewAllow : true, prodCatalogId : categoryId]);
+            virtualVariantsRes = runService('getAssociatedProducts', [productIdTo : productId, type : "ALTERNATIVE_PACKAGE", checkViewAllow : true, prodCatalogId : categoryId]);
             virtualVariants = virtualVariantsRes.assocProducts;
             // Format to apply the currency code to the variant price in the javascript
             if (productStore) {
@@ -535,13 +533,13 @@
                     priceContext.product = virtual;
                     if (cart.isSalesOrder()) {
                         // sales order: run the "calculateProductPrice" service
-                        virtualPriceMap = dispatcher.runSync("calculateProductPrice", priceContext);
+                        virtualPriceMap = runService('calculateProductPrice', priceContext);
                         BigDecimal calculatedPrice = (BigDecimal)virtualPriceMap.get("price");
                         // Get the minimum quantity for variants if MINIMUM_ORDER_PRICE is set for variants.
                         virtualVariantPriceList.add(virtualPriceMap);
                         variantPriceJS.append(" if (sku == \"" + virtual.productId + "\") return \"" + UtilFormatOut.formatCurrency(virtualPriceMap.basePrice, currencyUomId, locale, 10) + "\"; ");
                     } else {
-                        virtualPriceMap = dispatcher.runSync("calculatePurchasePrice", priceContext);
+                        virtualPriceMap = runService('calculatePurchasePrice', priceContext);
                         variantPriceJS.append(" if (sku == \"" + virtual.productId + "\") return \"" + UtilFormatOut.formatCurrency(virtualPriceMap.price, currencyUomId, locale, 10) + "\"; ");
                     }
                 }
@@ -560,11 +558,11 @@
 
     // if the product is a MARKETING_PKG_AUTO/PICK, then also get the quantity which can be produced from components
     if (isMarketingPackage) {
-        resultOutput = dispatcher.runSync("getMktgPackagesAvailable", [productId : productId]);
+        resultOutput = runService('getMktgPackagesAvailable', [productId : productId]);
         availableInventory = resultOutput.availableToPromiseTotal;
     } else {
         //get last inventory count from product facility for the product
-        facilities = delegator.findList("ProductFacility", EntityCondition.makeCondition([productId : product.productId]), null, null, null, false)
+        facilities = from("ProductFacility").where("productId", product.productId).queryList();
         if(facilities) {
             facilities.each { facility ->
                 lastInventoryCount = facility.lastInventoryCount;
@@ -577,22 +575,22 @@
     context.availableInventory = availableInventory;
 
     // get product associations
-    alsoBoughtProducts = dispatcher.runSync("getAssociatedProducts", [productId : productId, type : "ALSO_BOUGHT", checkViewAllow : true, prodCatalogId : currentCatalogId, bidirectional : false, sortDescending : true]);
+    alsoBoughtProducts = runService('getAssociatedProducts', [productId : productId, type : "ALSO_BOUGHT", checkViewAllow : true, prodCatalogId : currentCatalogId, bidirectional : false, sortDescending : true]);
     context.alsoBoughtProducts = alsoBoughtProducts.assocProducts;
 
-    obsoleteProducts = dispatcher.runSync("getAssociatedProducts", [productId : productId, type : "PRODUCT_OBSOLESCENCE", checkViewAllow : true, prodCatalogId : currentCatalogId]);
+    obsoleteProducts = runService('getAssociatedProducts', [productId : productId, type : "PRODUCT_OBSOLESCENCE", checkViewAllow : true, prodCatalogId : currentCatalogId]);
     context.obsoleteProducts = obsoleteProducts.assocProducts;
 
-    crossSellProducts = dispatcher.runSync("getAssociatedProducts", [productId : productId, type : "PRODUCT_COMPLEMENT", checkViewAllow : true, prodCatalogId : currentCatalogId]);
+    crossSellProducts = runService('getAssociatedProducts', [productId : productId, type : "PRODUCT_COMPLEMENT", checkViewAllow : true, prodCatalogId : currentCatalogId]);
     context.crossSellProducts = crossSellProducts.assocProducts;
 
-    upSellProducts = dispatcher.runSync("getAssociatedProducts", [productId : productId, type : "PRODUCT_UPGRADE", checkViewAllow : true, prodCatalogId : currentCatalogId]);
+    upSellProducts = runService('getAssociatedProducts', [productId : productId, type : "PRODUCT_UPGRADE", checkViewAllow : true, prodCatalogId : currentCatalogId]);
     context.upSellProducts = upSellProducts.assocProducts;
 
-    obsolenscenseProducts = dispatcher.runSync("getAssociatedProducts", [productIdTo : productId, type : "PRODUCT_OBSOLESCENCE", checkViewAllow : true, prodCatalogId : currentCatalogId]);
+    obsolenscenseProducts = runService('getAssociatedProducts', [productIdTo : productId, type : "PRODUCT_OBSOLESCENCE", checkViewAllow : true, prodCatalogId : currentCatalogId]);
     context.obsolenscenseProducts = obsolenscenseProducts.assocProducts;
 
-    accessoryProducts = dispatcher.runSync("getAssociatedProducts", [productId : productId, type : "PRODUCT_ACCESSORY", checkViewAllow : true, prodCatalogId : currentCatalogId]);
+    accessoryProducts = runService('getAssociatedProducts', [productId : productId, type : "PRODUCT_ACCESSORY", checkViewAllow : true, prodCatalogId : currentCatalogId]);
     context.accessoryProducts = accessoryProducts.assocProducts;
 
     /*
@@ -639,7 +637,7 @@
     */
 
     // get the DIGITAL_DOWNLOAD related Content records to show the contentName/description
-    downloadProductContentAndInfoList = delegator.findByAnd("ProductContentAndInfo", [productId : productId, productContentTypeId : "DIGITAL_DOWNLOAD"], null, true);
+    downloadProductContentAndInfoList = from("ProductContentAndInfo").where("productId", productId, "productContentTypeId", "DIGITAL_DOWNLOAD").cache(true).queryList();
     context.downloadProductContentAndInfoList = downloadProductContentAndInfoList;
 
     // not the best to save info in an action, but this is probably the best place to count a view; it is done async
@@ -647,15 +645,14 @@
 
     //get product image from image management
     productImageList = [];
-    productContentAndInfoImageManamentList = delegator.findByAnd("ProductContentAndInfo", ["productId": productId, productContentTypeId : "IMAGE", "statusId" : "IM_APPROVED", "drIsPublic" : "Y"], ["sequenceNum"], false);
+    productContentAndInfoImageManamentList = from("ProductContentAndInfo").where("productId", productId, "productContentTypeId", "IMAGE", "statusId", "IM_APPROVED", "drIsPublic", "Y").orderBy("sequenceNum").queryList();
     if(productContentAndInfoImageManamentList) {
         productContentAndInfoImageManamentList.each { productContentAndInfoImageManament ->
-            contentAssocThumbList = delegator.findByAnd("ContentAssoc", [contentId : productContentAndInfoImageManament.contentId, contentAssocTypeId : "IMAGE_THUMBNAIL"], null, false);
-            contentAssocThumb = EntityUtil.getFirst(contentAssocThumbList);
+            contentAssocThumb = from("ContentAssoc").where("contentId", productContentAndInfoImageManament.contentId, "contentAssocTypeId", "IMAGE_THUMBNAIL").queryFirst();
             if(contentAssocThumb) {
-                imageContentThumb = delegator.findOne("Content", [contentId : contentAssocThumb.contentIdTo], false);
+                imageContentThumb = from("Content").where("contentId", contentAssocThumb.contentIdTo).queryOne();
                 if(imageContentThumb) {
-                    productImageThumb = delegator.findOne("ContentDataResourceView", [contentId : imageContentThumb.contentId, drDataResourceId : imageContentThumb.dataResourceId], false);
+                    productImageThumb = from("ContentDataResourceView").where("contentId", imageContentThumb.contentId, "drDataResourceId", imageContentThumb.dataResourceId).queryOne();
                     productImageMap = [:];
                     productImageMap.productImageThumb = productImageThumb.drObjectInfo;
                     productImageMap.productImage = productContentAndInfoImageManament.drObjectInfo;
@@ -672,15 +669,11 @@
     }
     
     // get product tags
-    productKeywords = delegator.findByAnd("ProductKeyword", ["productId": productId, "keywordTypeId" : "KWT_TAG", "statusId" : "KW_APPROVED"], null, false);
+    productKeywords = from("ProductKeyword").where("productId": productId, "keywordTypeId" : "KWT_TAG", "statusId" : "KW_APPROVED").queryList();
     keywordMap = [:];
     if (productKeywords) {
         for (productKeyword in productKeywords) {
-            keywordConds = [EntityCondition.makeCondition("keyword", EntityOperator.EQUALS, productKeyword.keyword),
-                            EntityCondition.makeCondition("keywordTypeId", EntityOperator.EQUALS, "KWT_TAG"),
-                            EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "KW_APPROVED")];
-                keywordCond = EntityCondition.makeCondition(keywordConds, EntityOperator.AND);
-            productKeyWordCount = delegator.findCountByCondition("ProductKeyword", keywordCond, null, null);
+            productKeyWordCount = from("ProductKeyword").where("keyword", productKeyword.keyword, "keywordTypeId", "KWT_TAG", "statusId", "KW_APPROVED").queryCount();
             keywordMap.put(productKeyword.keyword,productKeyWordCount);
         }
         context.productTags = keywordMap;
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductSummary.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductSummary.groovy
index 33edab0..2da1315 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductSummary.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductSummary.groovy
@@ -54,7 +54,7 @@
 }
 
 if (!facilityId) {
-    productStoreFacility = EntityQuery.use(delegator).select("facilityId").from("ProductStoreFacility").where(UtilMisc.toList(EntityCondition.makeCondition("productStoreId", EntityOperator.EQUALS, productStoreId))).queryFirst();
+    productStoreFacility = EntityQuery.use(delegator).select("facilityId").from("ProductStoreFacility").where("productStoreId", productStoreId).queryFirst();
     if (productStoreFacility) {
         facilityId = productStoreFacility.facilityId;
     }
@@ -70,22 +70,21 @@
 
 // get the product entity
 if (!product && productId) {
-    product = delegator.findOne("Product", [productId : productId], true);
+    product = from("Product").where("productId", productId).cache(true).queryOne();
 }
 if (product) {
     //if order is purchase then don't calculate available inventory for product.
     if (cart.isSalesOrder()) {
-        resultOutput = dispatcher.runSync("getInventoryAvailableByFacility", [productId : product.productId, facilityId : facilityId, useCache : true]);
+        resultOutput = runService('getInventoryAvailableByFacility', [productId : product.productId, facilityId : facilityId, useCache : true]);
         totalAvailableToPromise = resultOutput.availableToPromiseTotal;
         if (totalAvailableToPromise && totalAvailableToPromise.doubleValue() > 0) {
-            productFacility = delegator.findOne("ProductFacility", [productId : product.productId, facilityId : facilityId], true);
+            productFacility = from("ProductFacility").where("productId", product.productId, "facilityId", facilityId).cache(true).queryOne();
             if (productFacility?.daysToShip != null) {
                 context.daysToShip = productFacility.daysToShip;
             }
         }
     } else {
-       supplierProducts = delegator.findByAnd("SupplierProduct", [productId : product.productId], ["-availableFromDate"], true);
-       supplierProduct = EntityUtil.getFirst(supplierProducts);
+       supplierProduct = from("SupplierProduct").where("productId", product.productId).orderBy("-availableFromDate").cache(true).queryFirst();
        if (supplierProduct?.standardLeadTimeDays != null) {
            standardLeadTimeDays = supplierProduct.standardLeadTimeDays;
            daysToShip = standardLeadTimeDays + 1;
@@ -113,14 +112,14 @@
         priceContext.agreementId = cart.getAgreementId();
         priceContext.partyId = cart.getPartyId();  // IMPORTANT: otherwise it'll be calculating prices using the logged in user which could be a CSR instead of the customer
         priceContext.checkIncludeVat = "Y";
-        priceMap = dispatcher.runSync("calculateProductPrice", priceContext);
+        priceMap = runService('calculateProductPrice', priceContext);
 
         context.price = priceMap;
     } else {
         // purchase order: run the "calculatePurchasePrice" service
         priceContext = [product : product, currencyUomId : cart.getCurrency(),
                 partyId : cart.getPartyId(), userLogin : userLogin];
-        priceMap = dispatcher.runSync("calculatePurchasePrice", priceContext);
+        priceMap = runService('calculatePurchasePrice', priceContext);
 
         context.price = priceMap;
     }
@@ -142,7 +141,7 @@
     boolean isAlternativePacking = ProductWorker.isAlternativePacking(delegator, product.productId, null);
     mainProducts = [];
     if(isAlternativePacking){
-        productVirtualVariants = delegator.findByAnd("ProductAssoc", UtilMisc.toMap("productIdTo", product.productId , "productAssocTypeId", "ALTERNATIVE_PACKAGE"), null, true);
+        productVirtualVariants = from("ProductAssoc").where("productIdTo", product.productId , "productAssocTypeId", "ALTERNATIVE_PACKAGE").cache(true).queryList();
         if(productVirtualVariants){
             productVirtualVariants.each { virtualVariantKey ->
                 mainProductMap = [:];
@@ -160,7 +159,7 @@
         jsBuf.append("<script language=\"JavaScript\" type=\"text/javascript\">");
         
         // make a list of variant sku with requireAmount
-        virtualVariantsRes = dispatcher.runSync("getAssociatedProducts", [productIdTo : productId, type : "ALTERNATIVE_PACKAGE", checkViewAllow : true, prodCatalogId : categoryId]);
+        virtualVariantsRes = runService('getAssociatedProducts', [productIdTo : productId, type : "ALTERNATIVE_PACKAGE", checkViewAllow : true, prodCatalogId : categoryId]);
         virtualVariants = virtualVariantsRes.assocProducts;
         // Format to apply the currency code to the variant price in the javascript
         if (productStore) {
@@ -184,12 +183,12 @@
                 priceContext.product = virtual;
                 if (cart.isSalesOrder()) {
                     // sales order: run the "calculateProductPrice" service
-                    virtualPriceMap = dispatcher.runSync("calculateProductPrice", priceContext);
+                    virtualPriceMap = runService('calculateProductPrice', priceContext);
                     BigDecimal calculatedPrice = (BigDecimal)virtualPriceMap.get("price");
                     // Get the minimum quantity for variants if MINIMUM_ORDER_PRICE is set for variants.
                     variantPriceList.add(virtualPriceMap);
                 } else {
-                    virtualPriceMap = dispatcher.runSync("calculatePurchasePrice", priceContext);
+                    virtualPriceMap = runService('calculatePurchasePrice', priceContext);
                 }
                 variantPriceJS.append("  if (sku == \"" + virtual.productId + "\") return \"" + numberFormat.format(virtualPriceMap.basePrice) + "\"; ");
             }
@@ -223,7 +222,7 @@
 }
 
 // an example of getting features of a certain type to show
-sizeProductFeatureAndAppls = delegator.findByAnd("ProductFeatureAndAppl", [productId : productId, productFeatureTypeId : "SIZE"], ["sequenceNum", "defaultSequenceNum"], true);
+sizeProductFeatureAndAppls = from("ProductFeatureAndAppl").where("productId", productId, "productFeatureTypeId", "SIZE").orderBy("sequenceNum", "defaultSequenceNum").cache(true).queryList();
 
 context.product = product;
 context.categoryId = categoryId;
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductUomDropDownOnly.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductUomDropDownOnly.groovy
index d9dadda..b26004a 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductUomDropDownOnly.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductUomDropDownOnly.groovy
@@ -19,9 +19,9 @@
 
 import org.ofbiz.base.util.*;
 
-product = delegator.findOne("Product", UtilMisc.toMap("productId", parameters.productId), false);
+product = from("Product").where("productId", parameters.productId).queryOne();
 if (product) {
-    productVirtualVariants = delegator.findByAnd("ProductAssoc", UtilMisc.toMap("productIdTo", product.productId , "productAssocTypeId", "ALTERNATIVE_PACKAGE"), null, true);
+    productVirtualVariants = from("ProductAssoc").where("productIdTo", product.productId , "productAssocTypeId", "ALTERNATIVE_PACKAGE").cache(true).queryList();
     if(productVirtualVariants){
         def mainProducts = [];
         productVirtualVariants.each { virtualVariantKey ->
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/QuickAdd.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/QuickAdd.groovy
index 41775a3..87bf91e 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/QuickAdd.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/QuickAdd.groovy
@@ -39,12 +39,12 @@
 if (categoryId) {
     fields = [productCategoryId : categoryId, defaultViewSize : 10,
             limitView : false, prodCatalogId : currentCatalogId, checkViewAllow : true];
-    result = dispatcher.runSync("getProductCategoryAndLimitedMembers", fields);
+    result = runService('getProductCategoryAndLimitedMembers', fields);
     if (result) {
         result.each { key, value ->
             context[key] = value;
         }
     }
-    productCategory = delegator.findOne("ProductCategory", ["productCategoryId" : categoryId], false);
+    productCategory = from("ProductCategory").where("productCategoryId", categoryId).queryOne();
     context.productCategory = productCategory;
 }
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/lookup/LookupAssociatedProducts.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/lookup/LookupAssociatedProducts.groovy
index 4af99d2..a4fe97c 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/lookup/LookupAssociatedProducts.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/lookup/LookupAssociatedProducts.groovy
@@ -26,7 +26,7 @@
 productId = request.getParameter("productId");
 
 if (productId != null) {
-    product = delegator.findOne("Product", [productId : productId], false);
+    product = from("Product").where("productId", productId).queryOne();
     prodAssocs = product.getRelated("MainProductAssoc", null, null, false);
     if (UtilValidate.isNotEmpty(prodAssocs)) {
         products = EntityUtil.filterByAnd(prodAssocs, [EntityCondition.makeCondition("productAssocTypeId", EntityOperator.NOT_EQUAL, "PRODUCT_VARIANT")]);
@@ -36,8 +36,7 @@
             products.each { product ->
                 if (product != null) {
                     String productIdTo = product.getString("productIdTo");
-                    prodAssocRecord = delegator.findByAnd("Product", [productId : productIdTo], null, false);
-                    productList.add(EntityUtil.getFirst(prodAssocRecord));
+                    productList.add(from("Product").where("productId", productIdTo).queryFirst());
                 }
             }
             context.put("productList",productList);
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/order/CompanyHeader.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/order/CompanyHeader.groovy
index 750c6fa..dd4656d 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/order/CompanyHeader.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/order/CompanyHeader.groovy
@@ -41,22 +41,22 @@
 fromPartyId = parameters.fromPartyId;
 
 if (!orderHeader && orderId) {
-    orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+    orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
 } else if (shipmentId) {
-    shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+    shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
     orderHeader = shipment.getRelatedOne("PrimaryOrderHeader", false);
 }
 
 if (!invoice && invoiceId)    {
-    invoice = delegator.findOne("Invoice", [invoiceId : invoiceId], false);
+    invoice = from("Invoice").where("invoiceId", invoiceId).queryOne();
 }
 
 if (!returnHeader && returnId) {
-    returnHeader = delegator.findOne("ReturnHeader", [returnId : returnId], false);
+    returnHeader = from("ReturnHeader").where("returnId", returnId).queryOne();
 }
 
 if (quoteId) {
-    quote = delegator.findOne("Quote", [quoteId : quoteId], false);
+    quote = from("Quote").where("quoteId", quoteId).queryOne();
 }
 
 // defaults:
@@ -118,7 +118,7 @@
 }
 
 // the logo
-partyGroup = delegator.findOne("PartyGroup", [partyId : partyId], false);
+partyGroup = from("PartyGroup").where("partyId", partyId).queryOne();
 if (partyGroup) {
     partyContentWrapper = new PartyContentWrapper(dispatcher, partyGroup, locale, "text/html");
     partyContent = partyContentWrapper.getFirstPartyContentByType(partyGroup.partyId , partyGroup, "LGOIMGURL", delegator);
@@ -143,12 +143,13 @@
 context.companyName = companyName;
 
 // the address
-addresses = delegator.findByAnd("PartyContactWithPurpose", [partyId : partyId, contactMechPurposeTypeId : "GENERAL_LOCATION"], null, false);
-addresses = EntityUtil.filterByDate(addresses, null, "contactFromDate", "contactThruDate", true);
-addresses = EntityUtil.filterByDate(addresses, null, "purposeFromDate", "purposeThruDate", true);
+addresses = from("PartyContactWithPurpose")
+                .where("partyId", partyId, "contactMechPurposeTypeId", "GENERAL_LOCATION")
+                .filterByDate("contactFromDate", "contactThruDate", "purposeFromDate", "purposeThruDate")
+                .queryList();
 address = null;
 if (addresses) {
-    address = delegator.findOne("PostalAddress", [contactMechId : addresses[0].contactMechId], false);
+    address = from("PostalAddress").where("contactMechId", addresses[0].contactMechId).queryOne();
 }
 if (address)    {
    // get the country name and state/province abbreviation
@@ -164,30 +165,34 @@
 context.postalAddress = address;
 
 //telephone
-phones = delegator.findByAnd("PartyContactWithPurpose", [partyId : partyId, contactMechPurposeTypeId : "PRIMARY_PHONE"], null, false);
-phones = EntityUtil.filterByDate(phones, null, "contactFromDate", "contactThruDate", true);
-phones = EntityUtil.filterByDate(phones, null, "purposeFromDate", "purposeThruDate", true);
+phones = from("PartyContactWithPurpose")
+             .where("partyId", partyId, "contactMechPurposeTypeId", "PRIMARY_PHONE")
+             .filterByDate("contactFromDate", "contactThruDate", "purposeFromDate", "purposeThruDate")
+             .queryList();
 if (phones) {
-    context.phone = delegator.findOne("TelecomNumber", [contactMechId : phones[0].contactMechId], false);
+    context.phone = from("TelecomNumber").where("contactMechId", phones[0].contactMechId).queryOne();
 }
 
 // Fax
-faxNumbers = delegator.findByAnd("PartyContactWithPurpose", [partyId : partyId, contactMechPurposeTypeId : "FAX_NUMBER"], null, false);
-faxNumbers = EntityUtil.filterByDate(faxNumbers, null, "contactFromDate", "contactThruDate", true);
-faxNumbers = EntityUtil.filterByDate(faxNumbers, null, "purposeFromDate", "purposeThruDate", true);
+faxNumbers = from("PartyContactWithPurpose")
+                 .where("partyId", partyId, "contactMechPurposeTypeId", "FAX_NUMBER")
+                 .filterByDate("contactFromDate", "contactThruDate", "purposeFromDate", "purposeThruDate")
+                 .queryList();
 if (faxNumbers) {
-    context.fax = delegator.findOne("TelecomNumber", [contactMechId : faxNumbers[0].contactMechId], false);
+    context.fax = from("TelecomNumber").where("contactMechId", faxNumbers[0].contactMechId).queryOne();
 }
 
 //Email
-emails = delegator.findByAnd("PartyContactWithPurpose", [partyId : partyId, contactMechPurposeTypeId : "PRIMARY_EMAIL"], null, false);
-emails = EntityUtil.filterByDate(emails, null, "contactFromDate", "contactThruDate", true);
-emails = EntityUtil.filterByDate(emails, null, "purposeFromDate", "purposeThruDate", true);
+emails = from("PartyContactWithPurpose")
+             .where("partyId", partyId, "contactMechPurposeTypeId", "PRIMARY_EMAIL")
+             .filterByDate("contactFromDate", "contactThruDate", "purposeFromDate", "purposeThruDate")
+             .queryList();
 if (emails) {
-    context.email = delegator.findOne("ContactMech", [contactMechId : emails[0].contactMechId], false);
+    context.email = from("ContactMech").where("contactMechId", emails[0].contactMechId).queryOne();
 } else {    //get email address from party contact mech
-    contacts = delegator.findByAnd("PartyContactMech", [partyId : partyId], null, false);
-    selContacts = EntityUtil.filterByDate(contacts, nowTimestamp, "fromDate", "thruDate", true);
+    selContacts = from("PartyContactMech")
+                      .where("partyId", partyId).filterByDate(nowTimestamp, "fromDate", "thruDate")
+                      .queryList();
     if (selContacts) {
         i = selContacts.iterator();
         while (i.hasNext())    {
@@ -201,15 +206,18 @@
 }
 
 // website
-websiteUrls = delegator.findByAnd("PartyContactWithPurpose", [partyId : partyId, contactMechPurposeTypeId : "PRIMARY_WEB_URLs"], null, false);
-websiteUrls = EntityUtil.filterByDate(websiteUrls, null, "contactFromDate", "contactThruDate", true);
-websiteUrls = EntityUtil.filterByDate(websiteUrls, null, "purposeFromDate", "purposeThruDate", true);
+websiteUrls = from("PartyContactWithPurpose")
+                  .where("partyId", partyId, "contactMechPurposeTypeId", "PRIMARY_WEB_URLs")
+                  .filterByDate("contactFromDate", "contactThruDate", "purposeFromDate", "purposeThruDate")
+                  .queryList();
 if (websiteUrls) {
     websiteUrl = EntityUtil.getFirst(websiteUrls);
-    context.website = delegator.findOne("ContactMech", [contactMechId : websiteUrl.contactMechId], false);
+    context.website = from("ContactMech").where("contactMechId", websiteUrl.contactMechId).queryOne();
 } else { //get web address from party contact mech
-contacts = delegator.findByAnd("PartyContactMech", [partyId : partyId], null, false);
-selContacts = EntityUtil.filterByDate(contacts, nowTimestamp, "fromDate", "thruDate", true);
+selContacts = from("PartyContactMech")
+                  .where("partyId", partyId)
+                  .filterByDate(nowTimestamp, "fromDate", "thruDate")
+                  .queryList();
 if (selContacts) {
     Iterator i = selContacts.iterator();
     while (i.hasNext())    {
@@ -223,14 +231,16 @@
 }
 
 //Bank account
-paymentMethods = delegator.findByAnd("PaymentMethod", [partyId : partyId, paymentMethodTypeId : "EFT_ACCOUNT"], null, false);
-selPayments = EntityUtil.filterByDate(paymentMethods, nowTimestamp, "fromDate", "thruDate", true);
+selPayments = from("PaymentMethod")
+              .where("partyId", partyId, "paymentMethodTypeId", "EFT_ACCOUNT")
+              .filterByDate(nowTimestamp, "fromDate", "thruDate")
+              .queryList();
 if (selPayments) {
-    context.eftAccount = delegator.findOne("EftAccount", [paymentMethodId : selPayments[0].paymentMethodId], false);
+    context.eftAccount = from("EftAccount").where("paymentMethodId", selPayments[0].paymentMethodId).queryOne();
 }
 
 // Tax ID Info
-partyTaxAuthInfoList = delegator.findByAnd("PartyTaxAuthInfo", [partyId : partyId], null, false);
+partyTaxAuthInfoList = from("PartyTaxAuthInfo").where("partyId", partyId).queryList();
 if (partyTaxAuthInfoList) {
     if (address.countryGeoId) {
         // if we have an address with country filter by that
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/order/FindOrders.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/order/FindOrders.groovy
index 3eaa2a9..442b16c 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/order/FindOrders.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/order/FindOrders.groovy
@@ -26,72 +26,72 @@
 module = "FindOrders.groovy";
 
 // get the order types
-orderTypes = delegator.findList("OrderType", null, null, ["description"], null, false);
+orderTypes = from("OrderType").orderBy("description").queryList();
 context.orderTypes = orderTypes;
 
 // get the role types
-roleTypes = delegator.findList("RoleType", null, null, ["description"], null, false);
+roleTypes = from("RoleType").orderBy("description").queryList();
 context.roleTypes = roleTypes;
 
 // get the order statuses
-orderStatuses = delegator.findByAnd("StatusItem", [statusTypeId : "ORDER_STATUS"], ["sequenceId", "description"], false);
+orderStatuses = from("StatusItem").where("statusTypeId", "ORDER_STATUS").orderBy("sequenceId", "description").queryList();
 context.orderStatuses = orderStatuses;
 
 // get websites
-websites = delegator.findList("WebSite", null, null, ["siteName"], null, false);
+websites = from("WebSite").orderBy("siteName").queryList();
 context.webSites = websites;
 
 // get the stores
-stores = delegator.findList("ProductStore", null, null, ["storeName"], null, false);
+stores = from("ProductStore").orderBy("storeName").queryList();
 context.productStores = stores;
 
 // get the channels
-channels = delegator.findByAnd("Enumeration", [enumTypeId : "ORDER_SALES_CHANNEL"], ["sequenceId"], false);
+channels = from("Enumeration").where("enumTypeId", "ORDER_SALES_CHANNEL").orderBy("sequenceId").queryList();
 context.salesChannels = channels;
 
 // get the Shipping Methods
-carrierShipmentMethods = delegator.findList("CarrierShipmentMethod", null, null, null, null, false);
+carrierShipmentMethods = from("CarrierShipmentMethod").queryList();
 context.carrierShipmentMethods = carrierShipmentMethods;
 
 // get the Payment Status
-paymentStatusList = delegator.findByAnd("StatusItem", [statusTypeId : "PAYMENT_PREF_STATUS"], ["description"], false);
+paymentStatusList = from("StatusItem").where("statusTypeId", "PAYMENT_PREF_STATUS").orderBy("description").queryList();
 context.paymentStatusList = paymentStatusList;
 
 // get the good identification types
-goodIdentificationTypes = delegator.findList("GoodIdentificationType", null, null, ["goodIdentificationTypeId", "description"], null, false);
+goodIdentificationTypes = from("GoodIdentificationType").orderBy("goodIdentificationTypeId", "description").queryList();
 context.goodIdentificationTypes = goodIdentificationTypes;
 
 // current role type
 currentRoleTypeId = request.getParameter("roleTypeId");
 if (currentRoleTypeId) {
-    currentRole = delegator.findOne("RoleType", [roleTypeId : currentRoleTypeId], true);
+    currentRole = from("RoleType").where("roleTypeId", currentRoleTypeId).cache(true).queryOne();
     context.currentRole = currentRole;
 }
 
 // current selected type
 currentTypeId = request.getParameter("orderTypeId");
 if (currentTypeId) {
-    currentType = delegator.findOne("OrderType", [orderTypeId : currentTypeId], true);
+    currentType = from("OrderType").where("orderTypeId", currentTypeId).cache(true).queryOne();
     context.currentType = currentType;
 }
 // current selected status
 currentStatusId = request.getParameter("orderStatusId");
 if (currentStatusId) {
-    currentStatus = delegator.findOne("StatusItem", [statusId : currentStatusId], true);
+    currentStatus = from("StatusItem").where("statusId", currentStatusId).cache(true).queryOne();
     context.currentStatus = currentStatus;
 }
 
 // current website
 currentWebSiteId = request.getParameter("orderWebSiteId");
 if (currentWebSiteId) {
-    currentWebSite = delegator.findOne("WebSite", [webSiteId : currentWebSiteId], true);
+    currentWebSite = from("WebSite").where("webSiteId", currentWebSiteId).cache(true).queryOne();
     context.currentWebSite = currentWebSite;
 }
 
 // current store
 currentProductStoreId = request.getParameter("productStoreId");
 if (currentProductStoreId) {
-    currentProductStore = delegator.findOne("ProductStore", [productStoreId : currentProductStoreId], true);
+    currentProductStore = from("ProductStore").where("productStoreId", currentProductStoreId).cache(true).queryOne();
     context.currentProductStore = currentProductStore;
 }
 
@@ -101,7 +101,7 @@
     carrierPartyId = shipmentMethod.substring(0, shipmentMethod.indexOf("@"));
     shipmentMethodTypeId = shipmentMethod.substring(shipmentMethod.indexOf("@")+1);
     if (carrierPartyId && shipmentMethodTypeId) {
-        currentCarrierShipmentMethod = EntityUtil.getFirst(delegator.findByAnd("CarrierShipmentMethod", [partyId : carrierPartyId, shipmentMethodTypeId : shipmentMethodTypeId], null, false));
+        currentCarrierShipmentMethod = from("CarrierShipmentMethod").where("partyId", carrierPartyId, "shipmentMethodTypeId", shipmentMethodTypeId).queryFirst();
         context.currentCarrierShipmentMethod = currentCarrierShipmentMethod;
     }
 }
@@ -109,14 +109,14 @@
 // current channel
 currentSalesChannelId = request.getParameter("salesChannelEnumId");
 if (currentSalesChannelId) {
-    currentSalesChannel = delegator.findOne("Enumeration", [enumId : currentSalesChannelId], false);
+    currentSalesChannel = from("Enumeration").where("enumId", currentSalesChannelId).queryOne();
     context.currentSalesChannel = currentSalesChannel;
 }
 
 // current good identification type
 currentGoodIdentificationTypeId = request.getParameter("goodIdentificationTypeId");
 if (currentGoodIdentificationTypeId) {
-    currentGoodIdentificationType = delegator.findByPrimaryKey("GoodIdentificationType", ["goodIdentificationTypeId" : currentGoodIdentificationTypeId]);
+    currentGoodIdentificationType = from("GoodIdentificationType").where("goodIdentificationTypeId", currentGoodIdentificationTypeId).queryOne();
     context.currentGoodIdentificationType = currentGoodIdentificationType;
 }
 
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 5700236..9fbd1b9 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderDeliveryScheduleInfo.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderDeliveryScheduleInfo.groovy
@@ -23,17 +23,16 @@
 
 orderId = request.getParameter("orderId");
 orderTypeId = null;
-orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
 if (orderHeader) {
     orderTypeId = orderHeader.orderTypeId;
 }
 
 //Determine whether a schedule has already been defined for this PO
-schedule = delegator.findOne("OrderDeliverySchedule", [orderId : orderId, orderItemSeqId : "_NA_"], false);
+schedule = from("OrderDeliverySchedule").where("orderId", orderId, "orderItemSeqId", "_NA_").queryOne();
 
 // Determine whether the current user can VIEW the order
-checkMap = [orderId : orderId, userLogin : session.getAttribute("userLogin"), checkAction : "VIEW"];
-checkResult = dispatcher.runSync("checkSupplierRelatedOrderPermission", checkMap);
+checkResult = runService('checkSupplierRelatedOrderPermission', [orderId : orderId, userLogin : session.getAttribute("userLogin"), checkAction : "VIEW"]);
 hasSupplierRelatedPermissionStr = checkResult.hasSupplierRelatedPermission;
 
 // Determine what the reuslt is, no result is FALSE
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderHistory.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderHistory.groovy
index 8647f1a..3cd2878 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderHistory.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderHistory.groovy
@@ -25,25 +25,25 @@
 
 orderHeader = null;
 if (orderId) {
-    orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+    orderHeader = from("OrderHeader").where(orderId : orderId).queryOne();
 }
 
 if (orderHeader) {
     shipmentMethodCond = [EntityCondition.makeCondition("changedEntityName", EntityOperator.EQUALS, "OrderItemShipGroup"),
                           EntityCondition.makeCondition("changedFieldName", EntityOperator.EQUALS, "shipmentMethodTypeId"),
                           EntityCondition.makeCondition("pkCombinedValueText", EntityOperator.LIKE, orderId + "%")];
-    shipmentMethodHistories = delegator.findList("EntityAuditLog", EntityCondition.makeCondition(shipmentMethodCond, EntityOperator.AND), null, ["-changedDate"], null, false);
+    shipmentMethodHistories = from("EntityAuditLog").where(shipmentMethodCond).orderBy("-changedDate").queryList();
 
     carrierPartyCond = [EntityCondition.makeCondition("changedEntityName", EntityOperator.EQUALS, "OrderItemShipGroup"),
                         EntityCondition.makeCondition("changedFieldName", EntityOperator.EQUALS, "carrierPartyId"),
                         EntityCondition.makeCondition("pkCombinedValueText", EntityOperator.LIKE, orderId + "%")];
-    carrierPartyHistories = delegator.findList("EntityAuditLog", EntityCondition.makeCondition(carrierPartyCond, EntityOperator.AND), null, null, null, false);
+    carrierPartyHistories = from("EntityAuditLog").where(carrierPartyCond).queryList();
 
     orderShipmentHistories = [];
     shipmentMethodHistories.each { shipmentMethodHistory ->
         orderShipmentHistory = [:];
         if ("shipmentMethodTypeId".equals(shipmentMethodHistory.changedFieldName)) {
-            shipmentMethodType = delegator.findOne("ShipmentMethodType", ["shipmentMethodTypeId" : shipmentMethodHistory.newValueText], false);
+            shipmentMethodType = from("ShipmentMethodType").where("shipmentMethodTypeId", shipmentMethodHistory.newValueText).queryOne();
             if (shipmentMethodType != null){
                 carrierPartyHistories.each { carrierPartyHistory ->
                     if (carrierPartyHistory.lastUpdatedTxStamp == shipmentMethodHistory.lastUpdatedTxStamp) {
@@ -66,13 +66,13 @@
     changedByInfoCond = [EntityCondition.makeCondition("changedEntityName", EntityOperator.EQUALS, "OrderItem"),
                          EntityCondition.makeCondition("changedFieldName", EntityOperator.EQUALS, "changeByUserLoginId"),
                          EntityCondition.makeCondition("pkCombinedValueText", EntityOperator.LIKE, orderId + "%")];
-    changedByInfoHistories = delegator.findList("EntityAuditLog", EntityCondition.makeCondition(changedByInfoCond, EntityOperator.AND), null, ["-changedDate"], null, false);
+    changedByInfoHistories = from("EntityAuditLog").where(changedByInfoCond).orderBy("-changedDate").queryList();
 
     orderUnitPriceHistories = [];
     unitPriceCond = [EntityCondition.makeCondition("changedEntityName", EntityOperator.EQUALS, "OrderItem"),
                      EntityCondition.makeCondition("changedFieldName", EntityOperator.EQUALS, "unitPrice"),
                      EntityCondition.makeCondition("pkCombinedValueText", EntityOperator.LIKE, orderId + "%")];
-    unitPriceHistories = delegator.findList("EntityAuditLog", EntityCondition.makeCondition(unitPriceCond, EntityOperator.AND), null, ["-changedDate"], null, false);
+    unitPriceHistories = from("EntityAuditLog").where(unitPriceCond).orderBy("-changedDate").queryList();
     unitPriceHistories.each { unitPriceHistory ->
         orderUnitPriceHistory = [:];
         if  ((unitPriceHistory.oldValueText) && (unitPriceHistory.newValueText)) {
@@ -81,7 +81,7 @@
                 orderUnitPriceHistory.newValue = unitPriceHistory.newValueText;
                 orderUnitPriceHistory.changedDate = unitPriceHistory.changedDate;
                 orderItemSeqId = (unitPriceHistory.pkCombinedValueText).substring((unitPriceHistory.pkCombinedValueText).indexOf("::") + 2, (unitPriceHistory.pkCombinedValueText).length());
-                orderItem = delegator.findOne("OrderItem", [orderId : orderId, orderItemSeqId : orderItemSeqId], false);
+                orderItem = from("OrderItem").where("orderId", orderId, "orderItemSeqId", orderItemSeqId).queryOne();
                 orderUnitPriceHistory.productId = orderItem.productId;
                 changedByInfoHistories.each { changedByInfoHistory ->
                     if (changedByInfoHistory.lastUpdatedTxStamp == unitPriceHistory.lastUpdatedTxStamp) {
@@ -102,7 +102,7 @@
     quantityCond = [EntityCondition.makeCondition("changedEntityName", EntityOperator.EQUALS, "OrderItem"),
                     EntityCondition.makeCondition("changedFieldName", EntityOperator.EQUALS, "quantity"),
                     EntityCondition.makeCondition("pkCombinedValueText", EntityOperator.LIKE, orderId + "%")];
-    quantityHistories = delegator.findList("EntityAuditLog", EntityCondition.makeCondition(quantityCond, EntityOperator.AND), null, ["-changedDate"], null, false);
+    quantityHistories = from("EntityAuditLog").where(quantityCond).orderBy("-changedDate").queryList();
     quantityHistories.each { quantityHistory ->
         orderQuantityHistory = [:];
         if ((quantityHistory.oldValueText) && (quantityHistory.newValueText)) {
@@ -111,7 +111,7 @@
                 orderQuantityHistory.newValue = quantityHistory.newValueText;
                 orderQuantityHistory.changedDate = quantityHistory.changedDate;
                 orderItemSeqId = (quantityHistory.pkCombinedValueText).substring((quantityHistory.pkCombinedValueText).indexOf("::") + 2, (quantityHistory.pkCombinedValueText).length());
-                orderItem = delegator.findOne("OrderItem", [orderId : orderId, orderItemSeqId : orderItemSeqId], false);
+                orderItem = from("OrderItem").where("orderId", orderId, "orderItemSeqId", orderItemSeqId).queryOne();
                 orderQuantityHistory.productId = orderItem.productId;
                 changedByInfoHistories.each { changedByInfoHistory ->
                     if (changedByInfoHistory.lastUpdatedTxStamp == quantityHistory.lastUpdatedTxStamp) {
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderList.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderList.groovy
index 6bca5e0..cb77ed0 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderList.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderList.groovy
@@ -50,7 +50,7 @@
 context.orderHeaderList = orderHeaderList;
 
 // a list of order type descriptions
-ordertypes = delegator.findList("OrderType", null, null, null, null, true);
+ordertypes = from("OrderType").cache(true).queryList();
 ordertypes.each { type ->
     context["descr_" + type.orderTypeId] = type.get("description",locale);
 }
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderStats.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderStats.groovy
index 3ed6f30..05b3444 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderStats.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderStats.groovy
@@ -58,7 +58,7 @@
                         EntityCondition.makeCondition("statusDatetime", EntityOperator.GREATER_THAN_EQUAL_TO, dayBegin),
                         EntityCondition.makeCondition("statusDatetime", EntityOperator.LESS_THAN_EQUAL_TO, dayEnd)],
                     EntityOperator.AND);
-dayList = delegator.findList("OrderStatus", ecl, null, null, null, false);
+dayList = from("OrderStatus").where(ecl).queryList();
 context.dayOrder = EntityUtil.filterByAnd(dayList, [statusId : "ORDER_CREATED"]);
 context.dayApprove = EntityUtil.filterByAnd(dayList, [statusId : "ORDER_APPROVED"]);
 context.dayComplete = EntityUtil.filterByAnd(dayList, [statusId : "ORDER_COMPLETED"]);
@@ -71,7 +71,7 @@
                         EntityCondition.makeCondition("statusDatetime", EntityOperator.GREATER_THAN_EQUAL_TO, weekBegin),
                         EntityCondition.makeCondition("statusDatetime", EntityOperator.LESS_THAN_EQUAL_TO, weekEnd)],
                     EntityOperator.AND);
-weekList = delegator.findList("OrderStatus", ecl, null, null, null, false);
+weekList = from("OrderStatus").where(ecl).queryList();
 context.weekOrder = EntityUtil.filterByAnd(weekList, [statusId : "ORDER_CREATED"]);
 context.weekApprove = EntityUtil.filterByAnd(weekList, [statusId: "ORDER_APPROVED"]);
 context.weekComplete = EntityUtil.filterByAnd(weekList, [statusId : "ORDER_COMPLETED"]);
@@ -84,7 +84,7 @@
                         EntityCondition.makeCondition("statusDatetime", EntityOperator.GREATER_THAN_EQUAL_TO, monthBegin),
                         EntityCondition.makeCondition("statusDatetime", EntityOperator.LESS_THAN_EQUAL_TO, monthEnd)],
                     EntityOperator.AND);
-monthList = delegator.findList("OrderStatus", ecl, null, null, null, false);
+monthList = from("OrderStatus").where(ecl).queryList();
 context.monthOrder = EntityUtil.filterByAnd(monthList, [statusId : "ORDER_CREATED"]);
 context.monthApprove = EntityUtil.filterByAnd(monthList, [statusId : "ORDER_APPROVED"]);
 context.monthComplete = EntityUtil.filterByAnd(monthList, [statusId : "ORDER_COMPLETED"]);
@@ -97,7 +97,7 @@
                         EntityCondition.makeCondition("statusDatetime", EntityOperator.GREATER_THAN_EQUAL_TO, yearBegin),
                         EntityCondition.makeCondition("statusDatetime", EntityOperator.LESS_THAN_EQUAL_TO, yearEnd)],
                     EntityOperator.AND);
-yearList = delegator.findList("OrderStatus", ecl, null, null, null, false);
+yearList = from("OrderStatus").where(ecl).queryList();
 context.yearOrder = EntityUtil.filterByAnd(yearList, [statusId : "ORDER_CREATED"]);
 context.yearApprove = EntityUtil.filterByAnd(yearList, [statusId : "ORDER_APPROVED"]);
 context.yearComplete = EntityUtil.filterByAnd(yearList, [statusId : "ORDER_COMPLETED"]);
@@ -112,7 +112,7 @@
                         EntityCondition.makeCondition("orderDate", EntityOperator.LESS_THAN_EQUAL_TO, dayEnd),
                         EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER")],
                     EntityOperator.AND);
-dayItems = delegator.findList("OrderHeaderAndItems", ecl, null, null, null, false);
+dayItems = from("OrderHeaderAndItems").where(ecl).queryList();
 dayItemsPending = EntityUtil.filterByAnd(dayItems, [itemStatusId : "ITEM_ORDERED"]);
 
 ecl = EntityCondition.makeCondition([
@@ -122,7 +122,7 @@
                         EntityCondition.makeCondition("orderDate", EntityOperator.LESS_THAN_EQUAL_TO, dayEnd),
                         EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER")],
                     EntityOperator.AND);
-dayHeaders = delegator.findList("OrderHeader", ecl, null, null, null, false);
+dayHeaders = from("OrderHeader").where(ecl).queryList();
 dayHeadersPending = EntityUtil.filterByAnd(dayHeaders, [statusId : "ORDER_CREATED"]);
 
 dayItemTotal = calcItemTotal(dayHeaders);
@@ -145,7 +145,7 @@
                         EntityCondition.makeCondition("orderDate", EntityOperator.LESS_THAN_EQUAL_TO, weekEnd),
                         EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER")],
                     EntityOperator.AND);
-weekItems = delegator.findList("OrderHeaderAndItems", ecl, null, null, null, false);
+weekItems = from("OrderHeaderAndItems").where(ecl).queryList();
 weekItemsPending = EntityUtil.filterByAnd(weekItems, [itemStatusId : "ITEM_ORDERED"]);
 
 ecl = EntityCondition.makeCondition([
@@ -155,7 +155,7 @@
                         EntityCondition.makeCondition("orderDate", EntityOperator.LESS_THAN_EQUAL_TO, weekEnd),
                         EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER")],
                     EntityOperator.AND);
-weekHeaders = delegator.findList("OrderHeader", ecl, null, null, null, false);
+weekHeaders = from("OrderHeader").where(ecl).queryList();
 weekHeadersPending = EntityUtil.filterByAnd(weekHeaders, [statusId : "ORDER_CREATED"]);
 
 weekItemTotal = calcItemTotal(weekHeaders);
@@ -178,7 +178,7 @@
                         EntityCondition.makeCondition("orderDate", EntityOperator.LESS_THAN_EQUAL_TO, monthEnd),
                         EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER")],
                     EntityOperator.AND);
-monthItems = delegator.findList("OrderHeaderAndItems", ecl, null, null, null, false);
+monthItems = from("OrderHeaderAndItems").where(ecl).queryList()
 monthItemsPending = EntityUtil.filterByAnd(monthItems, [itemStatusId : "ITEM_ORDERED"]);
 
 ecl = EntityCondition.makeCondition([
@@ -188,7 +188,7 @@
                         EntityCondition.makeCondition("orderDate", EntityOperator.LESS_THAN_EQUAL_TO, monthEnd),
                         EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER")],
                     EntityOperator.AND);
-monthHeaders = delegator.findList("OrderHeader", ecl, null, null, null, false);
+monthHeaders = from("OrderHeader").where(ecl).queryList();
 monthHeadersPending = EntityUtil.filterByAnd(monthHeaders, [statusId : "ORDER_CREATED"]);
 
 monthItemTotal = calcItemTotal(monthHeaders);
@@ -211,7 +211,7 @@
                         EntityCondition.makeCondition("orderDate", EntityOperator.LESS_THAN_EQUAL_TO, yearEnd),
                         EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER")],
                     EntityOperator.AND);
-yearItems = delegator.findList("OrderHeaderAndItems", ecl, null, null, null, false);
+yearItems = from("OrderHeaderAndItems").where(ecl).queryList();
 yearItemsPending = EntityUtil.filterByAnd(yearItems, [itemStatusId : "ITEM_ORDERED"]);
 
 ecl = EntityCondition.makeCondition([
@@ -221,7 +221,7 @@
                         EntityCondition.makeCondition("orderDate", EntityOperator.LESS_THAN_EQUAL_TO, yearEnd),
                         EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER")],
                     EntityOperator.AND);
-yearHeaders = delegator.findList("OrderHeader", ecl, null, null, null, false);
+yearHeaders = from("OrderHeader").where(ecl).queryList();
 yearHeadersPending = EntityUtil.filterByAnd(yearHeaders, [statusId : "ORDER_CREATED"]);
 
 yearItemTotal = calcItemTotal(yearHeaders);
@@ -238,11 +238,11 @@
 context.yearItemCountPaid = yearItemCountPaid;
 
 // order state report
-waitingPayment = delegator.findByAnd("OrderHeader", [statusId : "ORDER_CREATED", orderTypeId : "SALES_ORDER"], null, false);
+waitingPayment = from("OrderHeader").where("statusId", "ORDER_CREATED", "orderTypeId", "SALES_ORDER").queryList();
 context.waitingPayment = waitingPayment.size();
 
-waitingApproval = delegator.findByAnd("OrderHeader", [statusId : "ORDER_PROCESSING", orderTypeId : "SALES_ORDER"], null, false);
+waitingApproval = from("OrderHeader").where("statusId", "ORDER_PROCESSING", "orderTypeId", "SALES_ORDER").queryList();
 context.waitingApproval = waitingApproval.size();
 
-waitingComplete = delegator.findByAnd("OrderHeader", [statusId : "ORDER_APPROVED", orderTypeId : "SALES_ORDER"], null, false);
+waitingComplete = from("OrderHeader").where("statusId", "ORDER_APPROVED", "orderTypeId", "SALES_ORDER").queryList();
 context.waitingComplete = waitingComplete.size();
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderView.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderView.groovy
index d6fee90..775c61f 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderView.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderView.groovy
@@ -169,18 +169,18 @@
     context.itemIssuancesPerItem = itemIssuancesPerItem;
 
     // get a list of all invoices
-    orderBilling = delegator.findByAnd("OrderItemBilling", [orderId : orderId], ["invoiceId"], false);
+    orderBilling = from("OrderItemBilling").where("orderId", orderId).orderBy("invoiceId").queryList();
     context.invoices = orderBilling*.invoiceId.unique();
 
     ecl = EntityCondition.makeCondition([
                                     EntityCondition.makeCondition("orderId", EntityOperator.EQUALS, orderId),
                                     EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_CANCELLED")],
                                 EntityOperator.AND);
-    orderPaymentPreferences = delegator.findList("OrderPaymentPreference", ecl, null, null, null, false);
+    orderPaymentPreferences = from("OrderPaymentPreference").where(ecl).queryList();
     context.orderPaymentPreferences = orderPaymentPreferences;
 
     // ship groups
-    shipGroups = delegator.findByAnd("OrderItemShipGroup", [orderId : orderId], ["shipGroupSeqId"], false);
+    shipGroups = from("OrderItemShipGroup").where("orderId", orderId).orderBy("shipGroupSeqId").queryList();
     context.shipGroups = shipGroups;
 
 
@@ -243,15 +243,12 @@
     context.put("actualDateStr", actualDateStr);
 
     // get Shipment tracking info
-    osisCond = EntityCondition.makeCondition([orderId : orderId], EntityOperator.AND);
-    osisOrder = ["shipmentId", "shipmentRouteSegmentId", "shipmentPackageSeqId"];
-    osisFields = ["shipGroupSeqId", "shipmentId", "shipmentRouteSegmentId", "carrierPartyId", "shipmentMethodTypeId"] as Set;
-    osisFields.add("shipmentPackageSeqId");
-    osisFields.add("trackingCode");
-    osisFields.add("boxNumber");
-    osisFindOptions = new EntityFindOptions();
-    osisFindOptions.setDistinct(true);
-    orderShipmentInfoSummaryList = delegator.findList("OrderShipmentInfoSummary", osisCond, osisFields, osisOrder, osisFindOptions, false);
+    orderShipmentInfoSummaryList = select("shipGroupSeqId", "shipmentId", "shipmentRouteSegmentId", "carrierPartyId", "shipmentMethodTypeId", "shipmentPackageSeqId", "trackingCode", "boxNumber")
+                                    .from("OrderShipmentInfoSummary")
+                                    .where("orderId", orderId)
+                                    .orderBy("shipmentId", "shipmentRouteSegmentId", "shipmentPackageSeqId")
+                                    .distinct()
+                                    .queryList();
     context.orderShipmentInfoSummaryList = orderShipmentInfoSummaryList;
 
     customerPoNumber = null;
@@ -260,7 +257,7 @@
     }
     context.customerPoNumber = customerPoNumber;
 
-    statusChange = delegator.findByAnd("StatusValidChange", [statusId : orderHeader.statusId], null, false);
+    statusChange = from("StatusValidChange").where("statusId", orderHeader.statusId).queryList();
     context.statusChange = statusChange;
 
     currentStatus = orderHeader.getRelatedOne("StatusItem", false);
@@ -269,10 +266,10 @@
     orderHeaderStatuses = orderReadHelper.getOrderHeaderStatuses();
     context.orderHeaderStatuses = orderHeaderStatuses;
 
-    adjustmentTypes = delegator.findList("OrderAdjustmentType", null, null, ["description"], null, false);
+    adjustmentTypes = from("OrderAdjustmentType").orderBy("description").queryList();
     context.orderAdjustmentTypes = adjustmentTypes;
 
-    notes = delegator.findByAnd("OrderHeaderNoteView", [orderId : orderId], ["-noteDateTime"], false);
+    notes = from("OrderHeaderNoteView").where("orderId", orderId).orderBy("-noteDateTime").queryList();
     context.orderNotes = notes;
 
     showNoteHeadingOnPDF = false;
@@ -284,7 +281,7 @@
     cmvm = ContactMechWorker.getOrderContactMechValueMaps(delegator, orderId);
     context.orderContactMechValueMaps = cmvm;
 
-    orderItemChangeReasons = delegator.findByAnd("Enumeration", [enumTypeId : "ODR_ITM_CH_REASON"], ["sequenceId"], false);
+    orderItemChangeReasons = from("Enumeration").where("enumTypeId", "ODR_ITM_CH_REASON").orderBy("sequenceId").queryList();
     context.orderItemChangeReasons = orderItemChangeReasons;
 
     if ("PURCHASE_ORDER".equals(orderType)) {
@@ -309,7 +306,7 @@
             }
         }
         // get purchase order item types
-        purchaseOrderItemTypeList = delegator.findByAnd("OrderItemType", [parentTypeId : "PURCHASE_SPECIFIC"], null, true);
+        purchaseOrderItemTypeList = from("OrderItemType").where("parentTypeId", "PURCHASE_SPECIFIC").cache(true).queryList();
         context.purchaseOrderItemTypeList = purchaseOrderItemTypeList;
     }
 
@@ -357,7 +354,7 @@
                 if (shipGroup.contactMechId) {
                     lookupMap.contactMechId = shipGroup.contactMechId;
                 }
-                facilities = delegator.findByAnd("FacilityAndContactMech", lookupMap, null, true);
+                facilities = from("FacilityAndContactMech").where(lookupMap).cache(true).queryList();
                 facilitiesForShipGroup[shipGroup.shipGroupSeqId] = facilities;
                 facilities.each { facility ->
                     ownedFacilities[facility.facilityId] = facility;
@@ -420,13 +417,13 @@
     }
 
         // list to find all the POSTAL_ADDRESS for the shipment party.
-    orderParty = delegator.findOne("Party", [partyId : partyId], false);
+    orderParty = from("Party").where("partyId", partyId).queryOne();
     shippingContactMechList = ContactHelper.getContactMech(orderParty, "SHIPPING_LOCATION", "POSTAL_ADDRESS", false);
     context.shippingContactMechList = shippingContactMechList;
 
     // list to find all the shipmentMethods from the view named "ProductStoreShipmentMethView".
     if (productStore) {
-        context.productStoreShipmentMethList = delegator.findByAnd('ProductStoreShipmentMethView', [productStoreId: productStore.productStoreId], ['sequenceNumber'], true);
+        context.productStoreShipmentMethList = from("ProductStoreShipmentMethView").where("productStoreId", productStore.productStoreId).orderBy("sequenceNumber").cache(true).queryList();
     }
 
     // Get a map of returnable items
@@ -454,7 +451,7 @@
     }
 
    // list to find all the POSTAL_ADDRESS for the party.
-   orderParty = delegator.findOne("Party", [partyId : partyId], false);
+   orderParty = from("Party").where("partyId", partyId).queryOne();
    postalContactMechList = ContactHelper.getContactMechByType(orderParty,"POSTAL_ADDRESS", false);
    context.postalContactMechList = postalContactMechList;
 
@@ -477,11 +474,10 @@
 
 workEffortStatus = null;
 if (workEffortId && assignPartyId && assignRoleTypeId && fromDate) {
-    fields = [workEffortId : workEffortId, partyId : assignPartyId, roleTypeId : assignRoleTypeId, fromDate : fromDate];
-    wepa = delegator.findOne("WorkEffortPartyAssignment", fields, false);
+    wepa = from("WorkEffortPartyAssignment").where("workEffortId", workEffortId, "partyId", assignPartyId, "roleTypeId", assignRoleTypeId, "fromDate", fromDate).queryOne();
 
     if ("CAL_ACCEPTED".equals(wepa?.statusId)) {
-        workEffort = delegator.findOne("WorkEffort", [workEffortId : workEffortId], false);
+        workEffort = from("WorkEffort").where("workEffortId", workEffortId).queryOne();
         workEffortStatus = workEffort.currentStatusId;
         if (workEffortStatus) {
             context.workEffortStatus = workEffortStatus;
@@ -491,8 +487,7 @@
 
         if (workEffort) {
             if ("true".equals(delegate) || "WF_RUNNING".equals(workEffortStatus)) {
-                actFields = [packageId : workEffort.workflowPackageId, packageVersion : workEffort.workflowPackageVersion, processId : workEffort.workflowProcessId, processVersion : workEffort.workflowProcessVersion, activityId : workEffort.workflowActivityId];
-                activity = delegator.findOne("WorkflowActivity", actFields, false);
+                activity = from("WorkflowActivity").where("packageId", workEffort.workflowPackageId, "packageVersion", workEffort.workflowPackageVersion, "processId", workEffort.workflowProcessId, "processVersion", workEffort.workflowProcessVersion, "activityId", workEffort.workflowActivityId).queryOne();
                 if (activity) {
                     transitions = activity.getRelated("FromWorkflowTransition", null, ["-transitionId"], false);
                     context.wfTransitions = transitions;
@@ -510,14 +505,10 @@
 // getting online ship estimates corresponding to this Order from UPS when "Hold" button will be clicked, when user packs from weight package screen.
 // This case comes when order's shipping amount is  more then or less than default percentage (defined in shipment.properties) of online UPS shipping amount.
 
-condn = EntityCondition.makeCondition([
-            EntityCondition.makeCondition("primaryOrderId", EntityOperator.EQUALS, orderId),
-            EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "SHIPMENT_PICKED")],
-            EntityOperator.AND);
-shipments = delegator.findList("Shipment", condn, null, null, null, false);
+shipments = from("Shipment").where("primaryOrderId", orderId, "statusId", "SHIPMENT_PICKED").queryList();
 if (shipments) {
     pickedShipmentId = EntityUtil.getFirst(shipments).shipmentId;
-    shipmentRouteSegment = EntityUtil.getFirst(delegator.findList("ShipmentRouteSegment",EntityCondition.makeCondition([shipmentId : pickedShipmentId]), null, null, null, false));
+    shipmentRouteSegment = from("ShipmentRouteSegment").where("shipmentId", pickedShipmentId).queryFirst();
     context.shipmentRouteSegmentId = shipmentRouteSegment.shipmentRouteSegmentId;
     context.pickedShipmentId = pickedShipmentId;
     if (pickedShipmentId && shipmentRouteSegment.trackingIdNumber) {
@@ -529,7 +520,7 @@
                 shippingMethodAndRate = [:];
                 serviceCodes = shippingRate.keySet();
                 serviceCodes.each { serviceCode ->
-                    carrierShipmentMethod = EntityUtil.getFirst(delegator.findByAnd("CarrierShipmentMethod", [partyId : "UPS", carrierServiceCode : serviceCode], null, false));
+                    carrierShipmentMethod = from("CarrierShipmentMethod").where("partyId", "UPS", "carrierServiceCode", serviceCode).queryFirst();
                     shipmentMethodTypeId = carrierShipmentMethod.shipmentMethodTypeId;
                     rate = shippingRate.get(serviceCode);
                     shipmentMethodDescription = EntityUtil.getFirst(carrierShipmentMethod.getRelated("ShipmentMethodType", null, null, false)).description;
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/order/ReceivePayment.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/order/ReceivePayment.groovy
index a224af5..33a3347 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/order/ReceivePayment.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/order/ReceivePayment.groovy
@@ -22,7 +22,7 @@
 import org.ofbiz.base.util.*;
 
 orderId = request.getParameter("orderId");
-paymentMethodTypes = delegator.findList("PaymentMethodType", EntityCondition.makeCondition("paymentMethodTypeId", EntityOperator.NOT_EQUAL, "EXT_OFFLINE"), null, null, null, false);
+paymentMethodTypes = from("PaymentMethodType").where(EntityCondition.makeCondition("paymentMethodTypeId", EntityOperator.NOT_EQUAL, "EXT_OFFLINE")).queryList();
 context.paymentMethodTypes = paymentMethodTypes;
 
 workEffortId = request.getParameter("workEffortId");
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/order/SendConfirmationEmail.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/order/SendConfirmationEmail.groovy
index 665f4f9..0bfb957 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/order/SendConfirmationEmail.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/order/SendConfirmationEmail.groovy
@@ -35,9 +35,9 @@
 context.donePage = donePage;
 
 // Provide the correct order confirmation ProductStoreEmailSetting, if one exists
-orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
 if (orderHeader.productStoreId) {
-    productStoreEmailSetting = delegator.findOne("ProductStoreEmailSetting", [productStoreId : orderHeader.productStoreId, emailType : emailType], true);
+    productStoreEmailSetting = from("ProductStoreEmailSetting").where("productStoreId", orderHeader.productStoreId, "emailType", emailType)context.queryOne();
     if (productStoreEmailSetting) {
         context.productStoreEmailSetting = productStoreEmailSetting;
     }
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/order/ShipGroups.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/order/ShipGroups.groovy
index 103815e..191bdcf 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/order/ShipGroups.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/order/ShipGroups.groovy
@@ -33,7 +33,7 @@
 findMap = [orderId: orderId];
 if (shipGroupSeqId) findMap.shipGroupSeqId = shipGroupSeqId;
 
-shipGroups = delegator.findByAnd("OrderItemShipGroup", findMap, ["shipGroupSeqId"], false);
+shipGroups = from("OrderItemShipGroup").where(findMap).orderBy("shipGroupSeqId").queryList();
 context.shipGroups = shipGroups;
 
 // method to expand the marketing packages
@@ -90,7 +90,7 @@
 
         // the quantity shipped
         quantityShipped = 0.0;
-        issuances = delegator.findByAnd("ItemIssuance", [orderId : orderItem.orderId, orderItemSeqId : orderItem.orderItemSeqId, shipGroupSeqId : orderItemAssoc.shipGroupSeqId], null, false);
+        issuances = from("ItemIssuance").where("orderId", orderItem.orderId, "orderItemSeqId", orderItem.orderItemSeqId, "shipGroupSeqId", orderItemAssoc.shipGroupSeqId).queryList();
         issuances.each { issuance ->
             quantityShipped += issuance.quantity;
         }
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/order/ViewImage.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/order/ViewImage.groovy
index e69f36c..94aeef2 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/order/ViewImage.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/order/ViewImage.groovy
@@ -26,10 +26,10 @@
 
 order = null;
 if (orderId && !orderItemSeqId) {
-    order = delegator.findOne("OrderHeader", [orderId : orderId], false);
+    order = from("OrderHeader").where("orderId", orderId).queryOne();
 }
 if (orderId && orderItemSeqId) {
-    order = delegator.findOne("OrderItem", [orderId : orderId, orderItemSeqId : orderItemSeqId], false);
+    order = from("OrderItem").where("orderId", orderId, "orderItemSeqId", orderItemSeqId).queryOne();
 }
 
 wrapper = OrderContentWrapper.makeOrderContentWrapper(order, request);
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/quote/ManageQuotePrices.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/quote/ManageQuotePrices.groovy
index 6940f89..17caa54 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/quote/ManageQuotePrices.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/quote/ManageQuotePrices.groovy
@@ -52,9 +52,7 @@
 
     try {
         if (currency && quoteItem.productId) {
-            productPrices = delegator.findByAnd("ProductPrice", [productId : quoteItem.productId, currencyUomId : currency, productPriceTypeId : "AVERAGE_COST"], null, false);
-            productPrices = EntityUtil.filterByDate(productPrices);
-            productPrice = EntityUtil.getFirst(productPrices);
+            productPrice = from("ProductPrice").where("productId", quoteItem.productId, "currencyUomId", currency, "productPriceTypeId", "AVERAGE_COST").filterByDate().queryFirst();
             if (productPrice?.price != null) {
                 averageCost = productPrice.price;
             }
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/quote/ViewQuoteProfit.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/quote/ViewQuoteProfit.groovy
index c840130..adc802a 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/quote/ViewQuoteProfit.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/quote/ViewQuoteProfit.groovy
@@ -22,6 +22,7 @@
 import org.ofbiz.base.util.UtilDateTime;
 import org.ofbiz.base.util.UtilMisc;
 import org.ofbiz.entity.util.EntityUtil;
+import org.ofbiz.base.util.Debug;
 
 costMult = 0.0;
 quoteCoefficients.each { quoteCoefficient ->
@@ -53,11 +54,10 @@
 
     try {
         if (currency && quoteItem.productId) {
-            productPrices = delegator.findByAnd("ProductPrice", [productId : quoteItem.productId,
-                                                                 currencyUomId : currency,
-                                                                 productPriceTypeId : "AVERAGE_COST"], null, false);
-            productPrices = EntityUtil.filterByDate(productPrices, issueDate);
-            productPrice = EntityUtil.getFirst(productPrices);
+            productPrice = from("ProductPrice")
+                              .where(productId : quoteItem.productId, currencyUomId : currency, productPriceTypeId : "AVERAGE_COST")
+                              .filterByDate(issueDate)
+                              .queryFirst();
             if (productPrice?.price != null) {
                 averageCost = productPrice.price * selectedAmount;
             }
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/reports/OpenOrderItemsReport.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/reports/OpenOrderItemsReport.groovy
index 552abae..d5d2124 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/reports/OpenOrderItemsReport.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/reports/OpenOrderItemsReport.groovy
@@ -46,7 +46,7 @@
 if (productStoreId) {
     conditions.add(EntityCondition.makeCondition("productStoreId", EntityOperator.EQUALS, productStoreId));
     // for generating a title (given product store)
-    context.productStore = delegator.findOne("ProductStore", [productStoreId : productStoreId], true);
+    context.productStore = from("ProductStore").where("productStoreId", productStoreId).cache(true).queryOne();
 } else {
     // for generating a title (all stores)  TODO: use UtilProperties to internationalize
     context.productStore = [storeName : "All Stores"];
@@ -70,13 +70,13 @@
 conditions.add(EntityCondition.makeCondition("orderItemStatusId", EntityOperator.NOT_EQUAL, "ITEM_REJECTED"));
 
 // get the results as an entity list iterator
-allConditions = EntityCondition.makeCondition( conditions, EntityOperator.AND );
-fieldsToSelect = ["orderId", "orderDate", "productId", "quantityOrdered", "quantityIssued", "quantityOpen"] as Set;
-fieldsToSelect.add("shipBeforeDate");
-fieldsToSelect.add("shipAfterDate");
-fieldsToSelect.add("itemDescription");
-findOptions = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
-listIt = delegator.find("OrderItemQuantityReportGroupByItem", allConditions, null, fieldsToSelect, ["orderDate DESC"], findOptions);
+listIt = select("orderId", "orderDate", "productId", "quantityOrdered", "quantityIssued", "quantityOpen", "shipBeforeDate", "shipAfterDate", "itemDescription")
+            .from("OrderItemQuantityReportGroupByItem")
+            .where(conditions)
+            .orderBy("orderDate DESC")
+            .cursorScrollInsensitive()
+            .distinct()
+            .queryIterator();
 orderItemList = [];
 totalCostPrice = 0.0;
 totalListPrice = 0.0;
@@ -96,10 +96,8 @@
     itemDescription = listValue.itemDescription;
     shipAfterDate = listValue.shipAfterDate;
     shipBeforeDate = listValue.shipBeforeDate;
-    fieldsToSelect = ["price","productPriceTypeId"] as Set;
     productIdCondExpr =  [EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId)];
-    prodPriceCond = EntityCondition.makeCondition(productIdCondExpr, EntityOperator.AND);
-    productPrices = delegator.findList("ProductPrice", prodPriceCond, fieldsToSelect, null, null, false);
+    productPrices = select("price","productPriceTypeId").from("ProductPrice").where(productIdCondExpr).queryList();
     costPrice = 0.0;
     retailPrice = 0.0;
     listPrice = 0.0;
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/request/RequestItemNotes.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/request/RequestItemNotes.groovy
index 3763155..c4949f4 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/request/RequestItemNotes.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/request/RequestItemNotes.groovy
@@ -29,7 +29,7 @@
 if (showAll.equals("false")) {
     fields.custRequestItemSeqId = custRequestItemSeqId;
 }
-notes = delegator.findByAnd("CustRequestItemNoteView", fields, ["-noteDateTime"], false);
+notes = from("CustRequestItemNoteView").where(fields).orderBy("-noteDateTime").queryList();
 if (notes) {
     context.notes = notes;
 }
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/request/SetRequestQuote.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/request/SetRequestQuote.groovy
index e954935..1be3155 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/request/SetRequestQuote.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/request/SetRequestQuote.groovy
@@ -22,8 +22,7 @@
 
 custRequestId = parameters.custRequestId;
 if (custRequestId) {
-    requestQuotes = delegator.findByAnd("QuoteItem", [custRequestId : custRequestId], null, false);
-    requestQuote = EntityUtil.getFirst(requestQuotes);
+    requestQuote = from("QuoteItem").where("custRequestId", custRequestId).queryFirst();
     if (requestQuote) {
         context.quoteId = requestQuote.quoteId;
     }
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/requirement/ApprovedProductRequirements.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/requirement/ApprovedProductRequirements.groovy
index bb8dcc0..6b60234 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/requirement/ApprovedProductRequirements.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/requirement/ApprovedProductRequirements.groovy
@@ -17,9 +17,9 @@
  * under the License.
  */
 
-prepare = dispatcher.runSync("prepareFind", [inputFields : parameters, entityName : "Requirement"]);
+prepare = runService('prepareFind', [inputFields : parameters, entityName : "Requirement"]);
 if (prepare.entityConditionList) {
-    results = dispatcher.runSync("getRequirementsForSupplier", [requirementConditions : prepare.entityConditionList, partyId : parameters.partyId]);
+    results = runService('getRequirementsForSupplier', [requirementConditions : prepare.entityConditionList, partyId : parameters.partyId]);
     context.requirementsForSupplier = results.requirementsForSupplier;
     context.quantityReport = [distinctProductCount : results.distinctProductCount, quantityTotal : results.quantityTotal, amountTotal : results.amountTotal];
 }
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/requirement/ApprovedProductRequirementsByVendor.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/requirement/ApprovedProductRequirementsByVendor.groovy
index 4aa6449..5ade87b 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/requirement/ApprovedProductRequirementsByVendor.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/requirement/ApprovedProductRequirementsByVendor.groovy
@@ -29,14 +29,11 @@
 import org.ofbiz.entity.util.*;
 import org.ofbiz.entity.condition.*;
 
-fields = ["partyId", "productId"] as Set;
-options = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
-orderBy = ["partyId"];
 conditions = EntityCondition.makeCondition([
             EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, "SUPPLIER"),
             EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "REQ_APPROVED"),
             EntityCondition.makeCondition("requirementTypeId", EntityOperator.EQUALS, "PRODUCT_REQUIREMENT"),
             EntityUtil.getFilterByDateExpr()
             ], EntityOperator.AND);
-requirements = delegator.find("RequirementPartyProductCount", conditions, null, fields, orderBy, options);
+requirements = select("partyId", "productId").from("RequirementPartyProductCount").where(conditions).orderBy("partyId").cursorScrollInsensitive().distinct().queryIterator();
 context.requirements = requirements;
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/requirement/SelectCreatedProposed.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/requirement/SelectCreatedProposed.groovy
index c4eb35b..6dcd358 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/requirement/SelectCreatedProposed.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/requirement/SelectCreatedProposed.groovy
@@ -24,7 +24,7 @@
 import org.ofbiz.entity.condition.EntityExpr;
 import org.ofbiz.entity.condition.EntityOperator;
 
-prepare = dispatcher.runSync("prepareFind", [inputFields : parameters, entityName : "Requirement"]);
+prepare = runService('prepareFind', [inputFields : parameters, entityName : "Requirement"]);
 statusCondition = EntityCondition.makeCondition([
                                               EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "REQ_CREATED"),
                                               EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "REQ_PROPOSED")],
@@ -35,5 +35,5 @@
 } else {
     ecl = statusCondition;
 }
-results = dispatcher.runSync("executeFind", [entityConditionList : ecl, entityName : "Requirement"]);
+results = runService('executeFind', [entityConditionList : ecl, entityName : "Requirement"]);
 context.requirements = results.listIt;
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/return/QuickReturn.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/return/QuickReturn.groovy
index 55f32a0..f840af4 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/return/QuickReturn.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/return/QuickReturn.groovy
@@ -36,16 +36,16 @@
     if (("VENDOR_RETURN").equals(returnHeaderTypeId)) {
         context.toPartyId = partyId;
     }
-    party = delegator.findOne("Party", [partyId : partyId], false);
+    party = from("Party").where("partyId", partyId).queryOne();
     context.party = party;
 }
 
-returnHeaders = delegator.findByAnd("ReturnHeader", [statusId : "RETURN_REQUESTED"], ["entryDate"], false);
+returnHeaders = from("ReturnHeader").where("statusId", "RETURN_REQUESTED").queryList();
 context.returnHeaders = returnHeaders;
 
 // put in the return to party information from the order header
 if (orderId) {
-    order = delegator.findOne("OrderHeader", [orderId : orderId], false);
+    order = from("OrderHeader").where("orderId", orderId).queryOne();
     productStore = order.getRelatedOne("ProductStore", false);
     if (productStore) {
         if (("VENDOR_RETURN").equals(returnHeaderTypeId)) {
@@ -64,37 +64,37 @@
 
 // payment method info
 if (partyId) {
-    creditCardList = EntityUtil.filterByDate(delegator.findByAnd("PaymentMethodAndCreditCard", [partyId : partyId], null, false));
+    creditCardList = from("PaymentMethodAndCreditCard").where("partyId", partyId).filterByDate().queryList();
     if (creditCardList) {
         context.creditCardList = creditCardList;
     }
-    eftAccountList = EntityUtil.filterByDate(delegator.findByAnd("PaymentMethodAndEftAccount", [partyId : partyId], null, false));
+    eftAccountList = from("PaymentMethodAndEftAccount").where("partyId", partyId).filterByDate().queryList();
     if (eftAccountList) {
         context.eftAccountList = eftAccountList;
     }
 }
 
 
-returnTypes = delegator.findList("ReturnType", null, null, ["sequenceId"], null, false);
+returnTypes = from("ReturnType").orderBy("sequenceId").queryList();
 context.returnTypes = returnTypes;
 
-returnReasons = delegator.findList("ReturnReason", null, null, ["sequenceId"], null, false);
+returnReasons = from("ReturnReason").orderBy("sequenceId").queryList();
 context.returnReasons = returnReasons;
 
-itemStts = delegator.findByAnd("StatusItem", [statusTypeId : "INV_SERIALIZED_STTS"], ["sequenceId"], false);
+itemStts = from("StatusItem").where("statusTypeId", "INV_SERIALIZED_STTS").orderBy("sequenceId").queryList();
 context.itemStts = itemStts;
 
 typeMap = [:];
-returnItemTypeMap = delegator.findByAnd("ReturnItemTypeMap", [returnHeaderTypeId : returnHeaderTypeId], null, false);
+returnItemTypeMap = from("ReturnItemTypeMap").where("returnHeaderTypeId", returnHeaderTypeId).queryList();
 returnItemTypeMap.each { value ->
     typeMap[value.returnItemMapKey] = value.returnItemTypeId;
 }
 context.returnItemTypeMap = typeMap;
 
 if (orderId) {
-    returnRes = dispatcher.runSync("getReturnableItems", [orderId : orderId]);
+    returnRes = runService('getReturnableItems', [orderId : orderId]);
     context.returnableItems = returnRes.returnableItems;
-    orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+    orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
     context.orderHeader = orderHeader;
 }
 
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnHeader.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnHeader.groovy
index 42942f1..8883422 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnHeader.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnHeader.groovy
@@ -40,7 +40,7 @@
     returnId = parameters.returnId;
 }
 if (returnId) {
-    returnHeader = delegator.findOne("ReturnHeader", [returnId : returnId], false);
+    returnHeader = from("ReturnHeader").where("returnId", returnId).queryOne();
     if (returnHeader) {
         partyId = returnHeader.fromPartyId;
         toPartyId = parameters.toPartyId;
@@ -54,16 +54,14 @@
 //fin account info
 finAccounts = null;
 if (partyId) {
-    finAccounts = delegator.findByAnd("FinAccountAndRole", [partyId: partyId, finAccountTypeId: "STORE_CREDIT_ACCT", roleTypeId: "OWNER", statusId: "FNACT_ACTIVE"], null, false);
-    finAccounts = EntityUtil.filterByDate(finAccounts);
+    finAccounts = from("FinAccountAndRole").where("partyId", partyId, "finAccountTypeId", "STORE_CREDIT_ACCT", "roleTypeId", "OWNER", "statusId", "FNACT_ACTIVE").filterByDate().queryList();
 }
 context.finAccounts = finAccounts;
 
 // billing account info
 billingAccountList = null;
 if (partyId) {
-    billingAccountList = delegator.findByAnd("BillingAccountAndRole", [partyId : partyId], null, false);
-    billingAccountList = EntityUtil.filterByDate(billingAccountList);
+    billingAccountList = from("BillingAccountAndRole").where("partyId", partyId).filterByDate().queryList();
 }
 context.billingAccountList = billingAccountList;
 
@@ -71,8 +69,8 @@
 List creditCardList = null;
 List eftAccountList = null;
 if (partyId) {
-    creditCardList = EntityUtil.filterByDate(delegator.findByAnd("PaymentMethodAndCreditCard", [partyId : partyId], null, false));
-    eftAccountList = EntityUtil.filterByDate(delegator.findByAnd("PaymentMethodAndEftAccount", [partyId : partyId], null, false));
+    creditCardList = from("PaymentMethodAndCreditCard").where("partyId", partyId).filterByDate().queryList();
+    eftAccountList = from("PaymentMethodAndEftAccount").where("partyId", partyId).filterByDate().queryList();
 }
 context.creditCardList = creditCardList;
 context.eftAccountList = eftAccountList;
@@ -80,9 +78,8 @@
 orderRole = null;
 orderHeader = null;
 if (orderId) {
-    orderRoles = delegator.findByAnd("OrderRole", [orderId : orderId, roleTypeId : "BILL_TO_CUSTOMER"], null, false);
-    orderRole = EntityUtil.getFirst(orderRoles);
-    orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+    orderRole = from("OrderRole").where("orderId", orderId, "roleTypeId", "BILL_TO_CUSTOMER").queryFirst();
+    orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
 }
 context.orderRole = orderRole;
 context.orderHeader = orderHeader;
@@ -98,15 +95,15 @@
 if (returnHeader) {
     contactMechTo = ContactMechWorker.getFacilityContactMechByPurpose(delegator, returnHeader.destinationFacilityId, ["PUR_RET_LOCATION", "SHIPPING_LOCATION", "PRIMARY_LOCATION"]);
     if (contactMechTo) {
-        postalAddressTo = delegator.findOne("PostalAddress", [contactMechId : contactMechTo.contactMechId], true);
+        postalAddressTo = from("PostalAddress").where("contactMechId", contactMechTo.contactMechId).cache(true).queryOne();
         context.postalAddressTo = postalAddressTo;
     }
     
-    party = delegator.findOne("Party", [partyId : partyId], true);
+    party = from("Party").where("partyId", partyId).cache(true).queryOne();
     if (party) {
         shippingContactMechList = ContactHelper.getContactMech(party, "SHIPPING_LOCATION", "POSTAL_ADDRESS", false);
         if (shippingContactMechList) {
-            context.postalAddressFrom = delegator.findOne("PostalAddress", [contactMechId : EntityUtil.getFirst(shippingContactMechList).contactMechId], true);
+            context.postalAddressFrom = from("PostalAddress").where("contactMechId", EntityUtil.getFirst(shippingContactMechList).contactMechId).cache(true).queryOne();
         }
     }
 }
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnHistory.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnHistory.groovy
index eeced8a..5efeafc 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnHistory.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnHistory.groovy
@@ -26,7 +26,7 @@
                            EntityCondition.makeCondition("newValueText", EntityOperator.NOT_EQUAL, null),
                            EntityCondition.makeCondition("oldValueText", EntityOperator.NOT_EQUAL, null)];
 
-returnHistoryList = delegator.findList("EntityAuditLog", EntityCondition.makeCondition(commonReturnHistoryCond, EntityOperator.AND), null, null, null, false);
+returnHistoryList = from("EntityAuditLog").where(commonReturnHistoryCond).queryList();
 
 orderReturnItemHistories = [];
 returnHistoryList.each { returnHistory ->
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnItems.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnItems.groovy
index 6b3d085..7f28c17 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnItems.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/return/ReturnItems.groovy
@@ -31,32 +31,32 @@
 orderId = parameters.orderId;
 context.orderId = orderId;
 
-returnHeader = delegator.findOne("ReturnHeader", [returnId : returnId], false);
+returnHeader = from("ReturnHeader").where("returnId", returnId).queryOne();
 context.returnHeader = returnHeader;
 
 returnHeaderTypeId = returnHeader.returnHeaderTypeId;
 context.toPartyId = returnHeader.toPartyId;
 
-returnItems = delegator.findByAnd("ReturnItem", [returnId : returnId], null, false);
+returnItems = from("ReturnItem").where("returnId", returnId).queryList();
 context.returnItems = returnItems;
 
 // these are just the adjustments not associated directly with a return item--the rest are gotten with a .getRelated on the returnItems in the .FTL
-returnAdjustments = delegator.findByAnd("ReturnAdjustment", [returnId : returnId, returnItemSeqId : "_NA_"], ["returnItemSeqId", "returnAdjustmentTypeId"], false);
+returnAdjustments = from("ReturnAdjustment").where("returnId", returnId, "returnItemSeqId", "_NA_").orderBy("returnItemSeqId", "returnAdjustmentTypeId").queryList();
 context.returnAdjustments = returnAdjustments;
 
-returnTypes = delegator.findList("ReturnType", null, null, ["sequenceId"], null, false);
+returnTypes = from("ReturnType").orderBy("sequenceId").queryList();
 context.returnTypes = returnTypes;
 
-itemStatus = delegator.findByAnd("StatusItem", [statusTypeId : "INV_SERIALIZED_STTS"], ["statusId", "description"], false);
+itemStatus = from("StatusItem").where("statusTypeId", "INV_SERIALIZED_STTS").orderBy("statusId", "description").queryList();
 context.itemStatus = itemStatus;
 
-returnReasons = delegator.findList("ReturnReason", null, null, ["sequenceId"], null, false);
+returnReasons = from("ReturnReason").orderBy("sequenceId").queryList();
 context.returnReasons = returnReasons;
 
-itemStts = delegator.findByAnd("StatusItem", [statusTypeId : "INV_SERIALIZED_STTS"], ["sequenceId"], false);
+itemStts = from("StatusItem").where("statusTypeId", "INV_SERIALIZED_STTS").orderBy("sequenceId").queryList();
 context.itemStts = itemStts;
 
-returnItemTypeMap = delegator.findByAnd("ReturnItemTypeMap", [returnHeaderTypeId : returnHeaderTypeId], null, false);
+returnItemTypeMap = from("ReturnItemTypeMap").where("returnHeaderTypeId", returnHeaderTypeId).queryList();
 typeMap = [:];
 returnItemTypeMap.each { value ->
     typeMap[value.returnItemMapKey] = value.returnItemTypeId;
@@ -64,8 +64,8 @@
 context.returnItemTypeMap = typeMap;
 
 if (orderId) {
-    order = delegator.findOne("OrderHeader", [orderId : orderId], false);
-    returnRes = dispatcher.runSync("getReturnableItems", [orderId : orderId]);
+    order = from("OrderHeader").where("orderId", orderId).queryOne();
+    returnRes = runService('getReturnableItems', [orderId : orderId]);
     context.returnableItems = returnRes.returnableItems;
 
     orh = new OrderReadHelper(order);
@@ -73,7 +73,7 @@
     context.orderHeaderAdjustments = orh.getAvailableOrderHeaderAdjustments();
 
     // get the order shipping amount
-    shipRes = dispatcher.runSync("getOrderShippingAmount", [orderId : orderId]);
+    shipRes = runService('getOrderShippingAmount', [orderId : orderId]);
     shippingAmount = shipRes.shippingAmount;
     context.shippingAmount = shippingAmount;
 }
@@ -83,12 +83,10 @@
     roleTypeId = "BILL_FROM_VENDOR";
     partyId = returnHeader.toPartyId;
 }
-partyOrders = delegator.findByAnd("OrderHeaderAndRoles", [roleTypeId : roleTypeId, partyId : partyId], ["orderId"], false);
+partyOrders = from("OrderHeaderAndRoles").where("roleTypeId", roleTypeId, "partyId", partyId).orderBy("orderId").queryList();
 context.partyOrders = partyOrders;
 context.partyId = partyId;
 
 // get the list of return shipments associated to the return
-findOptions = new EntityFindOptions();
-findOptions.setDistinct(true);
-returnShipmentIds = delegator.findList("ReturnItemShipment", EntityCondition.makeCondition("returnId", returnId), ["shipmentId"] as Set, null, findOptions, true);
+returnShipmentIds = select("shipmentId").from("ReturnItemShipment").where("returnId", returnId).distinct().cache(true).queryList();
 context.returnShipmentIds = returnShipmentIds;
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/setup/PaymentSetup.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/setup/PaymentSetup.groovy
index e429479..3766142 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/setup/PaymentSetup.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/setup/PaymentSetup.groovy
@@ -20,7 +20,7 @@
 import org.ofbiz.entity.*;
 import org.ofbiz.base.util.*;
 
-paymentSetup = delegator.findList("WebSitePaymentSettingView", null, null, ["webSiteId", "paymentMethodTypeId"], null, false);
+paymentSetup = from("WebSitePaymentSettingView").orderBy("webSiteId", "paymentMethodTypeId").queryList();
 context.paymentSetups = paymentSetup;
 
 webSiteId = parameters.webSiteId;
@@ -28,14 +28,14 @@
 
 webSitePayment = null;
 if (webSiteId && paymentMethodTypeId) {
-    webSitePayment = delegator.findOne("WebSitePaymentSettingView", [webSiteId : webSiteId, paymentMethodTypeId : paymentMethodTypeId], false);
+    webSitePayment = from("WebSitePaymentSettingView").where("webSiteId", webSiteId, "paymentMethodTypeId", paymentMethodTypeId).queryOne();
 }
 context.webSitePayment = webSitePayment;
 
-webSites = delegator.findList("WebSite", null, null, ["siteName"], null, false);
+webSites = from("WebSite").orderBy("siteName").queryList();
 context.webSites = webSites;
 
-paymentMethodTypes = delegator.findList("PaymentMethodType", null, null, ["description"], null, false);
+paymentMethodTypes = from("PaymentMethodType").orderBy("description").queryList();
 context.paymentMethodTypes = paymentMethodTypes;
 
 payInfo = UtilHttp.getParameterMap(request);
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/task/OrderTaskList.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/task/OrderTaskList.groovy
index 3c49df7..6c39fd7 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/task/OrderTaskList.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/task/OrderTaskList.groovy
@@ -42,8 +42,7 @@
 partyBase = [EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "CAL_ACCEPTED"), EntityCondition.makeCondition("wepaPartyId", EntityOperator.EQUALS, userLogin.partyId)];
 partyRole = [EntityCondition.makeCondition("orderRoleTypeId", EntityOperator.EQUALS, "PLACING_CUSTOMER"), EntityCondition.makeCondition("orderRoleTypeId", EntityOperator.EQUALS, "SUPPLIER_AGENT")];
 partyExpr = [EntityCondition.makeCondition(partyBase, EntityOperator.AND), EntityCondition.makeCondition(partyRole, EntityOperator.OR)];
-partyCond = EntityCondition.makeCondition(partyExpr, EntityOperator.AND);
-partyTasks = delegator.findList("OrderTaskList", partyCond, null, sortOrder, null, false);
+partyTasks = from("OrderTaskList").where(partyExpr).orderBy(sortOrder).queryList();
 
 if (partyTasks) partyTasks = EntityUtil.filterByDate(partyTasks);
 context.partyTasks = partyTasks;
@@ -51,12 +50,12 @@
 // Build a map of orderId and currency
 orderCurrencyMap = [:];
 partyTasks.each { ptItem ->
-    orderHeader = delegator.findOne("OrderHeader", [orderId : ptItem.orderId], false);
+    orderHeader = from("OrderHeader").where("orderId", ptItem.orderId).queryOne();
     orderCurrencyMap[ptItem.orderId] = orderHeader.currencyUom;
 }
 
 // get this user's roles
-partyRoles = delegator.findByAnd("PartyRole", [partyId : userLogin.partyId], null, false);
+partyRoles = from("PartyRole").where("partyId", userLogin.partyId).queryList();
 
 // build the role list
 pRolesList = [];
@@ -71,17 +70,16 @@
 expressions.add(EntityCondition.makeCondition(custList, EntityOperator.OR));
 if (pRolesList) expressions.add(EntityCondition.makeCondition(pRolesList, EntityOperator.OR));
 expressions.add(EntityCondition.makeCondition(baseList, EntityOperator.AND));
-conditions = EntityCondition.makeCondition(expressions, EntityOperator.AND);
 
 // invoke the query
-roleTasks = delegator.findList("OrderTaskList", conditions, null, sortOrder, null, false);
+roleTasks = from("OrderTaskList").where(expressions).orderBy(sortOrder).queryList();
 roleTasks = EntityUtil.filterByAnd(roleTasks, baseList);
 roleTasks = EntityUtil.filterByDate(roleTasks);
 context.roleTasks = roleTasks;
 
 // Add to the map of orderId and currency
 roleTasks.each { rtItem ->
-    orderHeader = delegator.findOne("OrderHeader", [orderId : rtItem.orderId], false);
+    orderHeader = from("OrderHeader").where("orderId", rtItem.orderId).queryOne();
     orderCurrencyMap[rtItem.orderId] = orderHeader.currencyUom;
 }
 context.orderCurrencyMap = orderCurrencyMap;
@@ -89,7 +87,7 @@
 context.now = nowTimestamp;
 
 // purchase order schedule
-poList = delegator.findByAnd("OrderHeaderAndRoles", [partyId : userLogin.partyId, orderTypeId : "PURCHASE_ORDER"], null, false);
+poList = from("OrderHeaderAndRoles").where("partyId", userLogin.partyId, "orderTypeId", "PURCHASE_ORDER").queryList();
 poIter = poList.iterator();
 listedPoIds = new HashSet();
 while (poIter.hasNext()) {
diff --git a/applications/order/webapp/ordermgr/return/returnItems.ftl b/applications/order/webapp/ordermgr/return/returnItems.ftl
index 0030478..d690a0c 100644
--- a/applications/order/webapp/ordermgr/return/returnItems.ftl
+++ b/applications/order/webapp/ordermgr/return/returnItems.ftl
@@ -94,7 +94,7 @@
     </div>
     <div class="screenlet-body">
 <!-- if we're called with loadOrderItems or createReturn, then orderId would exist -->
-<#if !requestParameters.orderId??>
+<#if !requestParameters.orderId?? && returnHeader?has_content>
           <form method="post" action="<@ofbizUrl>updateReturnItems</@ofbizUrl>">
           <input type="hidden" name="_useRowSubmit" value="Y" />
         <table cellspacing="0" class="basic-table">
@@ -386,13 +386,14 @@
         </form>
         </#if>
 <!-- if no requestParameters.orderId??, then show list of items -->
-<#else>
-        <#assign selectAllFormName = "returnItems"/>
+<#elseif returnHeader?has_content>
         <form name="returnItems" method="post" action="<@ofbizUrl>createReturnItems</@ofbizUrl>">
           <input type="hidden" name="returnId" value="${returnId}" />
           <input type="hidden" name="_useRowSubmit" value="Y" />
           <#include "returnItemInc.ftl"/>
         </form>
+<#else>
+  ${uiLabelMap.CommonErrorMessage2} : ${uiLabelMap.CommonPleaseSelect}. ${uiLabelMap.CommonUseBackButton}
 </#if>
     </div>
 </div>
diff --git a/applications/party/entitydef/entitymodel.xml b/applications/party/entitydef/entitymodel.xml
index 60df88d..51d85f5 100644
--- a/applications/party/entitydef/entitymodel.xml
+++ b/applications/party/entitydef/entitymodel.xml
@@ -1482,9 +1482,6 @@
       <relation type="one" fk-name="PARTY_NEED_PCAT" rel-entity-name="ProductCategory">
         <key-map field-name="productCategoryId"/>
       </relation>
-      <relation type="one" fk-name="PARTY_NEED_VSIT" rel-entity-name="Visit">
-        <key-map field-name="visitId"/>
-      </relation>
     </entity>
 
   <!-- ========================================================= -->
@@ -2013,9 +2010,6 @@
       <relation type="one" fk-name="PARTY_DATSRC_DSC" rel-entity-name="DataSource">
         <key-map field-name="dataSourceId"/>
       </relation>
-      <relation type="one" fk-name="PARTY_DATSRC_VST" rel-entity-name="Visit">
-        <key-map field-name="visitId"/>
-      </relation>
     </entity>
     <entity entity-name="PartyGroup"
             package-name="org.ofbiz.party.party"
@@ -2183,39 +2177,6 @@
         <key-map field-name="partyId"/>
       </relation>
     </view-entity>
-  <view-entity entity-name="PartyNameVisitView"
-    package-name="org.ofbiz.party.party"
-    title="Party Name visit View Entity">
-    <member-entity entity-alias="PTY" entity-name="Party"/>
-    <member-entity entity-alias="PER" entity-name="Person"/>
-    <member-entity entity-alias="PTYGRP" entity-name="PartyGroup"/>
-    <member-entity entity-alias="VISIT" entity-name="Visit"/>
-    <alias entity-alias="PTY" name="partyId"/>
-    <alias entity-alias="PTY" name="partyTypeId"/>
-    <alias entity-alias="PER" name="firstName"/>
-    <alias entity-alias="PER" name="middleName"/>
-    <alias entity-alias="PER" name="lastName"/>
-    <alias entity-alias="PER" name="firstNameLocal"/>
-    <alias entity-alias="PER" name="lastNameLocal"/>
-    <alias entity-alias="PER" name="personalTitle"/>
-    <alias entity-alias="PER" name="suffix"/>
-    <alias entity-alias="PTYGRP" name="groupName"/>
-    <alias entity-alias="PTYGRP" name="groupNameLocal"/>
-    <alias entity-alias="VISIT" name="webappName"/>
-    <alias entity-alias="VISIT" name="fromDate"/>
-    <view-link entity-alias="PTY" rel-entity-alias="PER" rel-optional="true">
-      <key-map field-name="partyId"/>
-    </view-link>
-    <view-link entity-alias="PTY" rel-entity-alias="PTYGRP" rel-optional="true">
-      <key-map field-name="partyId"/>
-    </view-link>
-    <view-link entity-alias="PTY" rel-entity-alias="VISIT" rel-optional="false">
-      <key-map field-name="partyId"/>
-    </view-link>
-    <relation type="one-nofk" rel-entity-name="Party">
-      <key-map field-name="partyId"/>
-    </relation>
-  </view-entity>
   <entity entity-name="PartyNote"
             package-name="org.ofbiz.party.party"
             title="Party Note Entity">
@@ -2899,25 +2860,9 @@
         <field name="contactMechId" type="id"></field>
         <field name="partyId" type="id"></field>
         <field name="roleTypeId" type="id"></field>
-        <relation type="one" fk-name="VISIT_CONT_MECH" rel-entity-name="ContactMech">
-            <key-map field-name="contactMechId"/>
-        </relation>
-        <relation type="one" fk-name="VISIT_PARTY" rel-entity-name="Party">
-            <key-map field-name="partyId"/>
-        </relation>
-        <relation type="one" fk-name="VISIT_ROLE_TYPE" rel-entity-name="RoleType">
-            <key-map field-name="roleTypeId"/>
-        </relation>
-        <relation type="one" fk-name="VISIT_PARTY_ROLE" rel-entity-name="PartyRole">
-            <key-map field-name="partyId"/>
-            <key-map field-name="roleTypeId"/>
-        </relation>
     </extend-entity>
     <extend-entity entity-name="Visitor">
         <field name="partyId" type="id"></field>
-        <relation type="one" fk-name="VISITOR_PARTY" rel-entity-name="Party">
-            <key-map field-name="partyId"/>
-        </relation>
     </extend-entity>
     <extend-entity entity-name="UserLogin">
         <field name="partyId" type="id"></field>
diff --git a/applications/party/script/org/ofbiz/party/test/PartyTests.xml b/applications/party/script/org/ofbiz/party/test/PartyTests.xml
index 0fa4667..404fb93 100644
--- a/applications/party/script/org/ofbiz/party/test/PartyTests.xml
+++ b/applications/party/script/org/ofbiz/party/test/PartyTests.xml
@@ -149,6 +149,47 @@
         <check-errors/>
     </simple-method>
 
+    <simple-method method-name="testEnsurePartyRole" short-description="A test to ensure the association between a party and a role" login-required="false">
+        <set field="partyId" value="DemoCustomer"/>
+        <set field="roleTypeId" value="SUPPLIER"/>
+        <set field="serviceCtx.partyId" from-field="partyId"/>
+        <set field="serviceCtx.roleTypeId" from-field="roleTypeId"/>
+        <entity-one entity-name="UserLogin" value-field="userLogin">
+            <field-map field-name="userLoginId" value="system"/>
+        </entity-one>
+        <entity-one entity-name="PartyRole" value-field="partyRole"/>
+        <assert>
+            <not><if-empty field="partyRole"/></not>
+            <if-compare-field field="partyRole.partyId" operator="equals" to-field="partyId"/>
+            <if-compare-field field="partyRole.roleTypeId" operator="equals" to-field="roleTypeId"/>
+        </assert>
+        <check-errors/>
+        <set field="serviceCtx.userLogin" from-field="userLogin"/>
+        <call-service service-name="ensurePartyRole" in-map-name="serviceCtx"/>
+        <entity-one entity-name="PartyRole" value-field="partyRole"/>
+        <assert>
+            <not><if-empty field="partyRole"/></not>
+            <if-compare-field field="partyRole.partyId" operator="equals" to-field="partyId"/>
+            <if-compare-field field="partyRole.roleTypeId" operator="equals" to-field="roleTypeId"/>
+        </assert>
+        <check-errors/>
+        <set field="roleTypeId" value="EMPLOYEE"/>
+        <set field="serviceCtx.roleTypeId" from-field="roleTypeId"/>
+        <entity-one entity-name="PartyRole" value-field="partyRole"/>
+        <assert>
+            <if-empty field="partyRole"/>
+        </assert>
+        <check-errors/>
+        <call-service service-name="ensurePartyRole" in-map-name="serviceCtx"/>
+        <entity-one entity-name="PartyRole" value-field="partyRole"/>
+        <assert>
+            <not><if-empty field="partyRole"/></not>
+            <if-compare-field field="partyRole.partyId" operator="equals" to-field="partyId"/>
+            <if-compare-field field="partyRole.roleTypeId" operator="equals" to-field="roleTypeId"/>
+        </assert>
+        <check-errors/>
+    </simple-method>
+
     <simple-method method-name="testCreateNewCommEvent" short-description="test to create a new communication event" login-required="false">
         <set field="createNewCommEventMap.communicationEventTypeId" value="EMAIL_COMMUNICATION"/>
         <set field="createNewCommEventMap.statusId" value="COM_ENTERED"/>
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/communication/FindCommEventContactMechs.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/communication/FindCommEventContactMechs.groovy
index 04bcde6..e358bbb 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/communication/FindCommEventContactMechs.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/communication/FindCommEventContactMechs.groovy
@@ -32,12 +32,10 @@
 
 if (parameters.communicationEventTypeId) {
    if ("EMAIL_COMMUNICATION".equals(parameters.communicationEventTypeId)) {
-      userEmailAddresses = delegator.findByAnd("PartyContactWithPurpose", [contactMechTypeId : "EMAIL_ADDRESS" , partyId : partyIdFrom], null, false);
-      userEmailAddresses = EntityUtil.filterByDate(userEmailAddresses, UtilDateTime.nowTimestamp(), "contactFromDate", "contactThruDate", true);
+      userEmailAddresses = from("PartyContactWithPurpose").where("contactMechTypeId", "EMAIL_ADDRESS" , "partyId", partyIdFrom).filterByDate(UtilDateTime.nowTimestamp(), "contactFromDate", "contactThruDate").queryList();
       context.userEmailAddresses = userEmailAddresses;
 
-      targetEmailAddresses = delegator.findByAnd("PartyContactWithPurpose", [contactMechTypeId : "EMAIL_ADDRESS", partyId : partyIdTo], null, false);
-      targetEmailAddresses = EntityUtil.filterByDate(targetEmailAddresses, UtilDateTime.nowTimestamp(), "contactFromDate", "contactThruDate", true);
+      targetEmailAddresses = from("PartyContactWithPurpose").where("contactMechTypeId", "EMAIL_ADDRESS", "partyId", partyIdTo).filterByDate(UtilDateTime.nowTimestamp(), "contactFromDate", "contactThruDate").queryList();
       context.targetEmailAddresses = targetEmailAddresses;
    }
 }
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/communication/GetMyCommunicationEventRole.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/communication/GetMyCommunicationEventRole.groovy
index 4750b5b..cda6d8d 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/communication/GetMyCommunicationEventRole.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/communication/GetMyCommunicationEventRole.groovy
@@ -22,11 +22,9 @@
 import org.ofbiz.base.component.ComponentConfig;
 
 if (parameters.communicationEventId) {
-    context.communicationEventRole = delegator.findOne("CommunicationEventRole",
-           ["communicationEventId" : parameters.communicationEventId,
-            "partyId" : parameters.partyId,
-            "roleTypeId" : parameters.roleTypeId
-           ], false);
+    context.communicationEventRole = from("CommunicationEventRole")
+                                        .where("communicationEventId", parameters.communicationEventId, "partyId", parameters.partyId, "roleTypeId", parameters.roleTypeId)
+                                        .queryOne();
 
     context.projectMgrExists = ComponentConfig.componentExists("projectmgr");
 }
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/communication/ListCommunications.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/communication/ListCommunications.groovy
index a475624..9144061 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/communication/ListCommunications.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/communication/ListCommunications.groovy
@@ -25,7 +25,7 @@
 partyId = parameters.partyId;
 context.partyId = partyId;
 
-party = delegator.findOne("Party", [partyId : partyId], false);
+party = from("Party").where("partyId", partyId).queryOne();
 context.party = party;
 
 // get the sort field
@@ -44,7 +44,7 @@
 expr = EntityCondition.makeCondition("partyIdFrom", EntityOperator.EQUALS, "partyId");
 eventExprs.add(expr);
 ecl = EntityCondition.makeCondition(eventExprs, EntityOperator.OR);
-events = delegator.findList("CommunicationEvent", ecl, null, [sortField], null, false);
+events = from("CommunicationEvent").where(ecl).orderBy(sortField).queryList();
 
 context.eventList = events;
 context.eventListSize = events.size();
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/communication/getPartyEmailFromCommEventInfo.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/communication/getPartyEmailFromCommEventInfo.groovy
index 3dea0a6..05bbb35 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/communication/getPartyEmailFromCommEventInfo.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/communication/getPartyEmailFromCommEventInfo.groovy
@@ -21,7 +21,7 @@
 import org.ofbiz.entity.util.EntityUtil;
 import javolution.util.FastList;
 
-communicationEvent = delegator.findOne("CommunicationEvent", [communicationEventId : parameters.communicationEventId], true);
+communicationEvent = from("CommunicationEvent").where("communicationEventId", parameters.communicationEventId).cache(true).queryOne();
 
 if (!communicationEvent.note) return;
 nameString = "Sent from: ";
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/communication/recentVisitor.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/communication/recentVisitor.groovy
index 08b346c..27525c6 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/communication/recentVisitor.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/communication/recentVisitor.groovy
@@ -17,12 +17,19 @@
  * under the License.
  */
 
-import org.ofbiz.entity.*
 import org.ofbiz.entity.condition.*;
 import org.ofbiz.entity.util.*
 import org.ofbiz.base.util.*;
 
 lastDate = UtilDateTime.addDaysToTimestamp(UtilDateTime.nowTimestamp(), -21); // should be there the last 3 weeks.
-searchCondition = EntityCondition.makeCondition("fromDate", EntityOperator.GREATER_THAN, lastDate);
-options = new EntityFindOptions(false, 0, 0,, true);
-context.recentParties = delegator.findList("PartyNameVisitView", searchCondition, (Set)["partyId", "firstName", "middleName", "lastName", "groupName"], null, options, true);
+visits = select('partyId')
+             .from('Visit')
+             .where(EntityCondition.makeCondition("fromDate", EntityOperator.GREATER_THAN, lastDate))
+             .distinct()
+             .queryList()
+partyIds = EntityUtil.getFieldListFromEntityList(visits, 'partyId', false)
+context.recentParties = select("partyId", "firstName", "middleName", "lastName", "groupName")
+                            .from("PartyNameView")
+                            .where(EntityCondition.makeCondition('partyId', EntityOperator.IN, partyIds))
+                            .distinct()
+                            .queryList();
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/party/EditContactMech.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/party/EditContactMech.groovy
index d9af03a..3fce3a9 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/party/EditContactMech.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/party/EditContactMech.groovy
@@ -32,7 +32,7 @@
 
 cmNewPurposeTypeId = parameters.contactMechPurposeTypeId;
 if (cmNewPurposeTypeId) {
-    contactMechPurposeType = delegator.findOne("ContactMechPurposeType", [contactMechPurposeTypeId : cmNewPurposeTypeId], false);
+    contactMechPurposeType = from("ContactMechPurposeType").where("contactMechPurposeTypeId", cmNewPurposeTypeId).queryOne();
     if (contactMechPurposeType) {
         context.contactMechPurposeType = contactMechPurposeType;
     } else {
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/party/EditShoppingList.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/party/EditShoppingList.groovy
index 48de7ca..9b29d29 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/party/EditShoppingList.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/party/EditShoppingList.groovy
@@ -32,7 +32,7 @@
 
 partyId = parameters.partyId ?:request.getAttribute("partyId");
 
-party = delegator.findOne("Party", [partyId : partyId], false);
+party = from("Party").where("partyId", partyId).queryOne();
 context.party = party;
 if (party) {
     context.lookupPerson = party.getRelatedOne("Person", false);
@@ -43,18 +43,18 @@
 
 //get the party for listid if it exists
 if (!partyId && shoppingListId) {
-    partyId = delegator.findOne("ShoppingList", [shoppingListId : shoppingListId], false).partyId;
+    partyId = from("ShoppingList").where("shoppingListId", shoppingListId).queryOne().partyId;
 }
 context.partyId = partyId;
 
 // get the top level shopping lists for the party
-allShoppingLists = delegator.findByAnd("ShoppingList", [partyId : partyId], ["listName"], false);
+allShoppingLists = from("ShoppingList").where("partyId", partyId).queryList();
 shoppingLists = EntityUtil.filterByAnd(allShoppingLists, [parentShoppingListId : null]);
 context.allShoppingLists = allShoppingLists;
 context.shoppingLists = shoppingLists;
 
 // get all shoppingListTypes
-shoppingListTypes = delegator.findList("ShoppingListType", null, null, ["description"], null, true);
+shoppingListTypes = from("ShoppingListType").orderBy("description").cache(true).queryList();
 context.shoppingListTypes = shoppingListTypes;
 
 // no passed shopping list id default to first list
@@ -67,7 +67,7 @@
 
 // if we passed a shoppingListId get the shopping list info
 if (shoppingListId) {
-    shoppingList = delegator.findOne("ShoppingList", [shoppingListId : shoppingListId], false);
+    shoppingList = from("ShoppingList").where("shoppingListId", shoppingListId).queryOne();
     context.shoppingList = shoppingList;
     context.shoppingListId = shoppingListId;
 
@@ -83,8 +83,7 @@
                 product = shoppingListItem.getRelatedOne("Product", true);
 
                 // DEJ20050704 not sure about calculating price here, will have some bogus data when not in a store webapp
-                calcPriceInMap = [product : product, quantity : shoppingListItem.quantity , currencyUomId : currencyUomId, userLogin : userLogin, productStoreId : shoppingList.productStoreId];
-                calcPriceOutMap = dispatcher.runSync("calculateProductPrice", calcPriceInMap);
+                calcPriceOutMap = runService('calculateProductPrice', [product : product, quantity : shoppingListItem.quantity , currencyUomId : currencyUomId, userLogin : userLogin, productStoreId : shoppingList.productStoreId]);
                 price = calcPriceOutMap.price;
                 totalPrice = price * shoppingListItem.getDouble("quantity");
                 shoppingListItemTotal += totalPrice;
@@ -124,7 +123,7 @@
         context.shoppingListType = shoppingListType;
 
         // get the child shopping lists of the current list for the logged in user
-        childShoppingLists = delegator.findByAnd("ShoppingList", [partyId : partyId, parentShoppingListId : shoppingListId], ["listName"], true);
+        childShoppingLists = from("ShoppingList").where("partyId", partyId, "parentShoppingListId", shoppingListId).orderBy("listName").cache(true).queryList();
         // now get prices for each child shopping list...
         if (childShoppingLists) {
             childShoppingListDatas = new ArrayList(childShoppingLists.size());
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/party/FindLookUp.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/party/FindLookUp.groovy
index a6bf8b5..a1ba1bc 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/party/FindLookUp.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/party/FindLookUp.groovy
@@ -19,17 +19,18 @@
 
 import org.ofbiz.base.util.*;
 import org.ofbiz.entity.condition.*;
+import org.ofbiz.entity.util.EntityUtilProperties;
 
 if (context.noConditionFind == null) {
     context.noConditionFind = parameters.noConditionFind;
 }
 if (context.noConditionFind == null) {
-    context.noConditionFind = UtilProperties.getPropertyValue("widget", "widget.defaultNoConditionFind");
+    context.noConditionFind = EntityUtilProperties.getPropertyValue("widget", "widget.defaultNoConditionFind", delegator);
 }
 if (context.filterByDate == null) {
     context.filterByDate = parameters.filterByDate;
 }
-prepareResult = dispatcher.runSync("prepareFind", [entityName : context.entityName,
+prepareResult = runService('prepareFind', [entityName : context.entityName,
                                                    orderBy : context.orderBy,
                                                    inputFields : parameters,
                                                    filterByDate : context.filterByDate,
@@ -49,7 +50,7 @@
     entityConditionList = statusPartyDisable;
 }
 
-executeResult = dispatcher.runSync("executeFind", [entityName : context.entityName,
+executeResult = runService('executeFind', [entityName : context.entityName,
                                                    orderByList : prepareResult.orderByList,
                                                    entityConditionList : entityConditionList,
                                                    noConditionFind :context.noConditionFind
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/party/FindMatches.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/party/FindMatches.groovy
index 8e5dae7..fa724e1 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/party/FindMatches.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/party/FindMatches.groovy
@@ -33,7 +33,7 @@
     postalCode = parameters.postalCode ?: null;
 
     if (state) {
-        context.currentStateGeo = delegator.findOne("Geo", [geoId : state], false);
+        context.currentStateGeo = from("Geo").where("geoId", state).queryOne();
     }
 
     if (!firstName || !lastName || !address1 || !city || !postalCode) {
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/party/GetCurrentCart.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/party/GetCurrentCart.groovy
index 8f8a1a7..48e357a 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/party/GetCurrentCart.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/party/GetCurrentCart.groovy
@@ -21,8 +21,7 @@
 
 partyId = partyId ?: parameters.partyId;
 
-savedCart = EntityUtil.getFirst(delegator.findByAnd("ShoppingList", [partyId : partyId,
-        shoppingListTypeId : "SLT_SPEC_PURP" , listName : "auto-save"], null, false));
+savedCart = from("ShoppingList").where("partyId", partyId, "shoppingListTypeId", "SLT_SPEC_PURP" , "listName", "auto-save").queryFirst();
 
 if (savedCart) {
       context.savedCartListId = savedCart.shoppingListId;
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/party/GetLoyaltyPoints.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/party/GetLoyaltyPoints.groovy
index bc6d642..844a90f 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/party/GetLoyaltyPoints.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/party/GetLoyaltyPoints.groovy
@@ -23,13 +23,12 @@
 
 if (partyId) {
     // get the system user
-    system = delegator.findOne("UserLogin", [userLoginId : "system"], false);
+    system = from("UserLogin").where("userLoginId", "system").queryOne();
 
     monthsToInclude = 12;
 
-    Map serviceIn = UtilMisc.toMap("partyId", partyId, "roleTypeId", "PLACING_CUSTOMER", "orderTypeId", "SALES_ORDER",
-            "statusId", "ORDER_COMPLETED", "monthsToInclude", monthsToInclude, "userLogin", system);
-    Map result = dispatcher.runSync("getOrderedSummaryInformation", serviceIn);
+    Map result = runService('getOrderedSummaryInformation', ["partyId": partyId, "roleTypeId": "PLACING_CUSTOMER", "orderTypeId": "SALES_ORDER",
+            "statusId": "ORDER_COMPLETED", "monthsToInclude": monthsToInclude, "userLogin": system]);
 
     context.monthsToInclude = monthsToInclude;
     context.totalSubRemainingAmount = result.totalSubRemainingAmount;
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/party/GetMyCompany.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/party/GetMyCompany.groovy
index a803c62..aaac8b5 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/party/GetMyCompany.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/party/GetMyCompany.groovy
@@ -18,10 +18,7 @@
  */
 
 if (userLogin) {
-    companies = delegator.findByAnd("PartyRelationship",
-            [partyIdTo: userLogin.partyId,
-             roleTypeIdTo: "CONTACT",
-             roleTypeIdFrom: "ACCOUNT"], null, false);
+    companies = from("PartyRelationship").where(partyIdTo: userLogin.partyId, roleTypeIdTo: "CONTACT", roleTypeIdFrom: "ACCOUNT").queryList();
     if (companies) {
         company = companies[0];
         context.myCompanyId = company.partyIdFrom;
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/party/GetPaymentMethods.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/party/GetPaymentMethods.groovy
index 9a1973e..e71323b 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/party/GetPaymentMethods.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/party/GetPaymentMethods.groovy
@@ -27,7 +27,7 @@
 currencyUomId = null;
 billingAccounts = [];
 if (partyId) {
-    billingAccountAndRoles = delegator.findByAnd("BillingAccountAndRole", [partyId : partyId]);
+    billingAccountAndRoles = from("BillingAccountAndRole").where("partyId", partyId).queryList();
     if (billingAccountAndRoles) currencyUomId = billingAccountAndRoles.first().accountCurrencyUomId;
     if (currencyUomId) billingAccounts = BillingAccountWorker.makePartyBillingAccountList(userLogin, currencyUomId, partyId, delegator, dispatcher);
 }
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/party/PartyFinancialHistory.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/party/PartyFinancialHistory.groovy
index 0988378..d2b6f73 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/party/PartyFinancialHistory.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/party/PartyFinancialHistory.groovy
@@ -35,7 +35,6 @@
 if (!actualCurrencyUomId) {
     actualCurrencyUomId = context.defaultOrganizationPartyCurrencyUomId;
 }
-findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
 //get total/unapplied/applied invoices separated by sales/purch amount:
 totalInvSaApplied = BigDecimal.ZERO;
 totalInvSaNotApplied = BigDecimal.ZERO;
@@ -59,7 +58,7 @@
             ],EntityOperator.OR)
         ],EntityOperator.AND);
 
-invIterator = delegator.find("InvoiceAndType", invExprs, null, null, null, findOpts);
+invIterator = from("InvoiceAndType").where(invExprs).cursorScrollInsensitive().distinct().queryIterator();
 
 while (invoice = invIterator.next()) {
     if ("PURCHASE_INVOICE".equals(invoice.parentTypeId)) {
@@ -99,7 +98,7 @@
             ], EntityOperator.OR)
         ], EntityOperator.AND);
 
-payIterator = delegator.find("PaymentAndType", payExprs, null, null, null, findOpts);
+payIterator = from("PaymentAndType").where(payExprs).cursorScrollInsensitive().distinct().queryIterator();
 
 while (payment = payIterator.next()) {
     if ("DISBURSEMENT".equals(payment.parentTypeId) || "TAX_PAYMENT".equals(payment.parentTypeId)) {
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/party/PartyGeoLocation.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/party/PartyGeoLocation.groovy
index 96efa0a..e88fdc4 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/party/PartyGeoLocation.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/party/PartyGeoLocation.groovy
@@ -27,7 +27,7 @@
 userLoginId = parameters.userlogin_id ?: parameters.userLoginId;
 
 if (!partyId && userLoginId) {
-    thisUserLogin = delegator.findOne("UserLogin", [userLoginId : userLoginId], false);
+    thisUserLogin = from("UserLogin").where("userLoginId", userLoginId).queryOne();
     if (thisUserLogin) {
         partyId = thisUserLogin.partyId;
     }
@@ -38,7 +38,7 @@
 if (!geoPointId) {
     latestGeoPoint = GeoWorker.findLatestGeoPoint(delegator, "PartyAndGeoPoint", "partyId", partyId, null, null);
 } else {
-    latestGeoPoint = delegator.findOne("GeoPoint", [geoPointId : geoPointId], false);
+    latestGeoPoint = from("GeoPoint").where("geoPointId", geoPointId).queryOne();
 }
 if (latestGeoPoint) {
     context.latestGeoPoint = latestGeoPoint;
@@ -53,7 +53,7 @@
         context.geoChart = geoChart;
     }
     if (latestGeoPoint && latestGeoPoint.elevationUomId) {
-        elevationUom = delegator.findOne("Uom", [uomId : latestGeoPoint.elevationUomId], false);
+        elevationUom = from("Uom").where("uomId", latestGeoPoint.elevationUomId).queryOne();
         context.elevationUomAbbr = elevationUom.abbreviation;
     }
 }
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/party/SetRoleVars.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/party/SetRoleVars.groovy
index 63be355..422fa0b 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/party/SetRoleVars.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/party/SetRoleVars.groovy
@@ -19,28 +19,28 @@
  import org.ofbiz.entity.*;
  import org.ofbiz.entity.util.EntityUtil;
 
- roleTypeAndParty = delegator.findByAnd("RoleTypeAndParty", ['partyId': parameters.partyId, 'roleTypeId': 'ACCOUNT'], null, false);
+ roleTypeAndParty = from("RoleTypeAndParty").where("partyId", parameters.partyId, "roleTypeId", "ACCOUNT").queryList();
  if (roleTypeAndParty) {
      context.accountDescription = roleTypeAndParty[0].description;
  }
 
- roleTypeAndParty = delegator.findByAnd("RoleTypeAndParty", ['partyId': parameters.partyId, 'roleTypeId': 'CONTACT'], null, false);
+ roleTypeAndParty = from("RoleTypeAndParty").where("partyId", parameters.partyId, "roleTypeId", "CONTACT").queryList();
  if (roleTypeAndParty) {
      context.contactDescription = roleTypeAndParty.get(0).description;
  }
- roleTypeAndParty = delegator.findByAnd("RoleTypeAndParty", ['partyId': parameters.partyId, 'roleTypeId': 'LEAD'], null, false);
+ roleTypeAndParty = from("RoleTypeAndParty").where("partyId", parameters.partyId, "roleTypeId", "LEAD").queryList();
  if (roleTypeAndParty) {
      context.leadDescription = roleTypeAndParty.get(0).description;
-     partyRelationships = EntityUtil.filterByDate(delegator.findByAnd("PartyRelationship", ["partyIdTo": parameters.partyId, "roleTypeIdFrom": "ACCOUNT_LEAD", "roleTypeIdTo": "LEAD", "partyRelationshipTypeId": "EMPLOYMENT"], null, false));
+     partyRelationships = from("PartyRelationship").where("partyIdTo", parameters.partyId, "roleTypeIdFrom", "ACCOUNT_LEAD", "roleTypeIdTo", "LEAD", "partyRelationshipTypeId", "EMPLOYMENT").filterByDate().queryList();
      if (partyRelationships) {
          context.partyGroupId = partyRelationships.get(0).partyIdFrom;
          context.partyId = parameters.partyId;
      }
  }
- roleTypeAndParty = delegator.findByAnd("RoleTypeAndParty", ['partyId': parameters.partyId, 'roleTypeId': 'ACCOUNT_LEAD'], null, false);
+ roleTypeAndParty = from("RoleTypeAndParty").where("partyId", parameters.partyId, "roleTypeId", "ACCOUNT_LEAD").queryList();
  if (roleTypeAndParty) {
      context.leadDescription = roleTypeAndParty.get(0).description;
-     partyRelationships = EntityUtil.filterByDate(delegator.findByAnd("PartyRelationship", ["partyIdFrom": parameters.partyId, "roleTypeIdFrom": "ACCOUNT_LEAD", "roleTypeIdTo": "LEAD", "partyRelationshipTypeId": "EMPLOYMENT"], null, false));
+     partyRelationships = from("PartyRelationship").where("partyIdFrom", parameters.partyId, "roleTypeIdFrom", "ACCOUNT_LEAD", "roleTypeIdTo", "LEAD", "partyRelationshipTypeId", "EMPLOYMENT").filterByDate().queryList();
      if (partyRelationships) {
          context.partyGroupId = parameters.partyId;
          context.partyId = partyRelationships.get(0).partyIdTo;
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/party/UnAppliedInvoicesForParty.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/party/UnAppliedInvoicesForParty.groovy
index 0de3a60..cd6ae8d 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/party/UnAppliedInvoicesForParty.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/party/UnAppliedInvoicesForParty.groovy
@@ -31,7 +31,6 @@
 if (actualCurrency == null) {
     actualCurrency = true;
 }
-findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
 
 invExprs =
     EntityCondition.makeCondition([
@@ -50,7 +49,7 @@
             ],EntityOperator.OR)
         ],EntityOperator.AND);
 
-invIterator = delegator.find("InvoiceAndType", invExprs, null, null, null, findOpts);
+invIterator = from("InvoiceAndType").where(invExprs).cursorScrollInsensitive().distinct().queryIterator();
 invoiceList = [];
 while (invoice = invIterator.next()) {
     unAppliedAmount = InvoiceWorker.getInvoiceNotApplied(invoice, actualCurrency).setScale(2,BigDecimal.ROUND_HALF_UP);
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/party/UnAppliedPaymentsForParty.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/party/UnAppliedPaymentsForParty.groovy
index 8e37c32..3972793 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/party/UnAppliedPaymentsForParty.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/party/UnAppliedPaymentsForParty.groovy
@@ -50,7 +50,7 @@
         ], EntityOperator.AND);
 
 paymentList = [];
-payIterator = delegator.find("PaymentAndType", payExprs, null, null, null, findOpts);
+payIterator = from("PaymentAndType").where(payExprs).cursorScrollInsensitive().distinct().queryIterator();
 
 while (payment = payIterator.next()) {
     unAppliedAmount = PaymentWorker.getPaymentNotApplied(payment, actualCurrency).setScale(2,BigDecimal.ROUND_HALF_UP);
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/party/ViewProfile.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/party/ViewProfile.groovy
index 62a59f9..6f9fd5f 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/party/ViewProfile.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/party/ViewProfile.groovy
@@ -23,7 +23,7 @@
 userLoginId = parameters.userlogin_id ?: parameters.userLoginId;
 
 if (!partyId && userLoginId) {
-    thisUserLogin = delegator.findOne("UserLogin", [userLoginId : userLoginId], false);
+    thisUserLogin = from("UserLogin").where("userLoginId", userLoginId).queryOne();
     if (thisUserLogin) {
         partyId = thisUserLogin.partyId;
         parameters.partyId = partyId;
@@ -32,5 +32,5 @@
 
 context.showOld = "true".equals(parameters.SHOW_OLD);
 context.partyId = partyId;
-context.party = delegator.findOne("Party", [partyId : partyId], false);
+context.party = from("Party").where("partyId", partyId).queryOne();
 context.nowStr = UtilDateTime.nowTimestamp().toString();
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/visit/ShowVisits.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/visit/ShowVisits.groovy
index d149b73..f6a092e 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/visit/ShowVisits.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/visit/ShowVisits.groovy
@@ -52,12 +52,12 @@
     highIndex = viewIndex * viewSize;
 
     if (partyId) {
-        visitListIt = delegator.find("Visit", EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, partyId), null, null, sortList, new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, -1, highIndex, true));
+        visitListIt = from("Visit").where("partyId", partyId).orderBy(sortList).cursorScrollInsensitive().maxRows(highIndex).distinct().queryIterator();
     } else if (showAll.equalsIgnoreCase("true")) {
-        visitListIt = delegator.find("Visit", null, null, null, sortList, new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, -1, highIndex, true));
+        visitListIt = from("Visit").orderBy(sortList).cursorScrollInsensitive().maxRows(highIndex).distinct().queryIterator();
     } else {
         // show active visits
-        visitListIt = delegator.find("Visit", EntityCondition.makeCondition("thruDate", EntityOperator.EQUALS, null), null, null, sortList, new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, -1, highIndex, true));
+        visitListIt = from("Visit").where("thruDate", null).orderBy(sortList).cursorScrollInsensitive().maxRows(highIndex).distinct().queryIterator();
     }
 
     // get the partial list for this page
diff --git a/applications/party/webapp/partymgr/WEB-INF/actions/visit/VisitDetails.groovy b/applications/party/webapp/partymgr/WEB-INF/actions/visit/VisitDetails.groovy
index 2fa4566..e174475 100644
--- a/applications/party/webapp/partymgr/WEB-INF/actions/visit/VisitDetails.groovy
+++ b/applications/party/webapp/partymgr/WEB-INF/actions/visit/VisitDetails.groovy
@@ -23,9 +23,9 @@
 visit = null;
 serverHits = null;
 if (visitId) {
-    visit = delegator.findOne("Visit", [visitId : visitId], false);
+    visit = from("Visit").where("visitId", visitId).queryOne();
     if (visit) {
-        serverHits = delegator.findByAnd("ServerHit", [visitId : visitId], ["-hitStartDateTime"], false);
+        serverHits = from("ServerHit").where("visitId", visitId).orderBy("-hitStartDateTime").queryList();
     }
 }
 
diff --git a/applications/party/widget/partymgr/CommunicationEventForms.xml b/applications/party/widget/partymgr/CommunicationEventForms.xml
index 6d3a9cb..543198d 100644
--- a/applications/party/widget/partymgr/CommunicationEventForms.xml
+++ b/applications/party/widget/partymgr/CommunicationEventForms.xml
@@ -789,7 +789,7 @@
         <field name="communicationEventId"><display/></field>
         <field name="contentId"><display/></field>
         <field name="contentTypeId"><hidden/></field>
-        <field name="dataResourceId"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><display/></field>
         <field name="contentName"><text/></field>
         <field name="fromDate"><display/></field>
         <field name="thruDate"><date-time/></field>
diff --git a/applications/party/widget/partymgr/PartyForms.xml b/applications/party/widget/partymgr/PartyForms.xml
index 90090bd..cae4a8b 100644
--- a/applications/party/widget/partymgr/PartyForms.xml
+++ b/applications/party/widget/partymgr/PartyForms.xml
@@ -586,7 +586,7 @@
         </field>
         <!-- note sure if these two are necessray, but they are kind of confusing in this context:
         <field name="ownerContentId"><lookup target-form-name="LookupContent"/></field>
-        <field name="dataResourceId"><lookup target-form-name="LookupDataResource"/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><lookup target-form-name="LookupDataResource"/></field>
         -->
         <field name="contentTypeId">
             <drop-down allow-empty="false" no-current-selected-key="DOCUMENT">
diff --git a/applications/product/config/ProductUiLabels.xml b/applications/product/config/ProductUiLabels.xml
index 9f19687..1c7c469 100644
--- a/applications/product/config/ProductUiLabels.xml
+++ b/applications/product/config/ProductUiLabels.xml
@@ -3632,7 +3632,7 @@
         <value xml:lang="zh_TW">取消數量</value>
     </property>
     <property key="FormFieldTitle_canclAutmExtTime">
-        <value xml:lang="en">The time period (before the end of the thrudate) after which the automatic extension of the subscription will be executed</value>
+        <value xml:lang="en">Time period (before the end of the thrudate) for automatic extension of the subscription</value>
         <value xml:lang="fr">Durée durant laquelle l'abonnement sera automatiquement étendu (avant la date de fin)</value>
         <value xml:lang="it">Il periodo di tempo (prima della data di termine) dopo che l'estensione automatica dell'abbonamento verrà eseguita</value>
         <value xml:lang="ja">(終了日前に)申込を自動継続する期間</value>
@@ -13616,7 +13616,7 @@
         <value xml:lang="zh_TW">型錄管理</value>
     </property>
     <property key="ProductCatalogEmptyWarning">
-        <value xml:lang="en">If you don't populate a Catalog with Categories, it will not shown in the Browse Catalogs/Categories tree</value>
+        <value xml:lang="en">If you don't populate a Catalog with Categories, it will not be shown in the Browse Catalogs/Categories tree</value>
         <value xml:lang="fr">Si vous ne créez pas de catégories pour un catalogue, il n'apparaitra pas dans l'arbre des Catalogues/catégories</value>
         <value xml:lang="it">Se un catalogo non viene valorizzato con delle categorie, questo non verrà mostrato nell'albero Sfoglia cataloghi/categorie</value>
         <value xml:lang="ja">カタログがカテゴリに属していない場合、カタログ/カテゴリツリーは表示されません</value>
diff --git a/applications/product/entitydef/entitymodel.xml b/applications/product/entitydef/entitymodel.xml
index 5961bd2..b4d0579 100644
--- a/applications/product/entitydef/entitymodel.xml
+++ b/applications/product/entitydef/entitymodel.xml
@@ -2159,9 +2159,6 @@
       <prim-key field="visitId"/>
       <prim-key field="productId"/>
       <prim-key field="productStoreId"/>
-      <relation type="one" fk-name="INV_ITEM_TR_VIS" rel-entity-name="Visit">
-        <key-map field-name="visitId"/>
-      </relation>
       <relation type="one" fk-name="INV_ITEM_TR_PROD" rel-entity-name="Product">
         <key-map field-name="productId"/>
       </relation>
@@ -3244,9 +3241,6 @@
       <field name="secondsTotal" type="floating-point"></field>
       <field name="searchDate" type="date-time"></field>
       <prim-key field="productSearchResultId"/>
-      <relation type="one" fk-name="PROD_SCHRES_VST" rel-entity-name="Visit">
-        <key-map field-name="visitId"/>
-      </relation>
     </entity>
     <entity entity-name="ProductType"
             package-name="org.ofbiz.product.product"
diff --git a/applications/product/entitydef/entitymodel_old.xml b/applications/product/entitydef/entitymodel_old.xml
index d5c9f8c..029967f 100644
--- a/applications/product/entitydef/entitymodel_old.xml
+++ b/applications/product/entitydef/entitymodel_old.xml
@@ -85,9 +85,6 @@
       <field name="removeStems" type="indicator"></field>
       <field name="numResults" type="numeric"></field>
       <prim-key field="productKeywordResultId"/>
-      <relation type="one" fk-name="PROD_KWDRES_VST" rel-entity-name="Visit">
-        <key-map field-name="visitId"/>
-      </relation>
       <relation type="one-nofk" rel-entity-name="ProductCategory">
         <key-map field-name="productCategoryId"/>
       </relation>
diff --git a/applications/product/script/org/ofbiz/shipment/issuance/IssuanceServices.xml b/applications/product/script/org/ofbiz/shipment/issuance/IssuanceServices.xml
index a7ec68a..e2cca24 100644
--- a/applications/product/script/org/ofbiz/shipment/issuance/IssuanceServices.xml
+++ b/applications/product/script/org/ofbiz/shipment/issuance/IssuanceServices.xml
@@ -270,6 +270,30 @@
         </calculate>
         <call-service service-name="createInventoryItemDetail" in-map-name="createDetailMap"/>
         <clear-field field="createDetailMap"/>
+        <entity-and list="oisgirs" entity-name="OrderItemShipGrpInvRes">
+            <field-map field-name="orderId" from-field="orderItemShipGrpInvRes.orderId"/>
+            <field-map field-name="orderItemSeqId" from-field="orderItemShipGrpInvRes.orderItemSeqId"/>
+        </entity-and>
+        <!-- Need to Cancel and re-reserve oisgir to fix OFBIZ-5364 issue, while there are multiple ship groups for an order item associated with same inventory and you are issuing items from one ship group to another, then quantityNotAvailable will be incorrect if we do not cancel and reserve all oisgir of order item  -->
+        <iterate entry="oisgir" list="oisgirs">
+            <set field="cancelOrderItemShipGrpInvResMap.orderId" from-field="oisgir.orderId"/>
+            <set field="cancelOrderItemShipGrpInvResMap.orderItemSeqId" from-field="oisgir.orderItemSeqId"/>
+            <set field="cancelOrderItemShipGrpInvResMap.shipGroupSeqId" from-field="oisgir.shipGroupSeqId"/>
+            <set field="cancelOrderItemShipGrpInvResMap.inventoryItemId" from-field="oisgir.inventoryItemId"/>
+            <set field="cancelOrderItemShipGrpInvResMap.cancelQuantity" from-field="oisgir.quantity"/>
+            <call-service service-name="cancelOrderItemShipGrpInvRes" in-map-name="cancelOrderItemShipGrpInvResMap"/>
+        </iterate>
+        <!-- Re-reserve cancelled oisgirs again so that shipped quantity will be subtract from oisgir.quantity and oisgir.quantityNotAvailable will be calculated accordingly -->
+        <iterate entry="oisgir" list="oisgirs">
+            <set field="reserveProductInventoryByFacilityMap.quantity" from-field="oisgir.quantity"/>
+            <set field="reserveProductInventoryByFacilityMap.facilityId" from-field="orderHeader.originFacilityId"/>
+            <set field="reserveProductInventoryByFacilityMap.orderId" from-field="oisgir.orderId"/>
+            <set field="reserveProductInventoryByFacilityMap.orderItemSeqId" from-field="oisgir.orderItemSeqId"/>
+            <set field="reserveProductInventoryByFacilityMap.productId" from-field="orderItem.productId"/>
+            <set field="reserveProductInventoryByFacilityMap.shipGroupSeqId" from-field="oisgir.shipGroupSeqId"/>
+            <set field="reserveProductInventoryByFacilityMap.requireInventory" value="N"/><!-- requireInventory should be N to create backordered oisgir if ATP is negative -->
+            <call-service service-name="reserveProductInventoryByFacility" in-map-name="reserveProductInventoryByFacilityMap" />
+        </iterate>
     </simple-method>
 
     <!-- some inline methods for the issuance process -->
diff --git a/applications/product/src/org/ofbiz/product/product/ProductWorker.java b/applications/product/src/org/ofbiz/product/product/ProductWorker.java
index ab7345b..9f7d2a1 100644
--- a/applications/product/src/org/ofbiz/product/product/ProductWorker.java
+++ b/applications/product/src/org/ofbiz/product/product/ProductWorker.java
@@ -1119,6 +1119,7 @@
                 // copy the supplier
                 List<GenericValue> supplierProducts = EntityQuery.use(delegator).from("SupplierProduct").where("productId", productId).cache(true).queryList();
                 for (GenericValue supplierProduct: supplierProducts) {
+                    supplierProduct = (GenericValue) supplierProduct.clone();
                     supplierProduct.set("productId",  product.getString("productId"));
                     supplierProduct.create();
                 }
@@ -1126,6 +1127,7 @@
                 // copy the content
                 List<GenericValue> productContents = EntityQuery.use(delegator).from("ProductContent").where("productId", productId).cache(true).queryList();
                 for (GenericValue productContent: productContents) {
+                    productContent = (GenericValue) productContent.clone();
                     productContent.set("productId",  product.getString("productId"));
                     productContent.create();
                 }
diff --git a/applications/product/src/org/ofbiz/shipment/shipment/ShipmentServices.java b/applications/product/src/org/ofbiz/shipment/shipment/ShipmentServices.java
index 7a96f96..61fd909 100644
--- a/applications/product/src/org/ofbiz/shipment/shipment/ShipmentServices.java
+++ b/applications/product/src/org/ofbiz/shipment/shipment/ShipmentServices.java
@@ -432,22 +432,26 @@
         if (shippableItemInfo != null) {
             for (Map<String, Object> itemMap: shippableItemInfo) {
                 // add the item sizes
-                BigDecimal itemSize = (BigDecimal) itemMap.get("size");
-                if (itemSize != null) {
-                    shippableItemSizes.add(itemSize);
+                if (itemMap.containsKey("size")) {
+                    BigDecimal itemSize = (BigDecimal) itemMap.get("size");
+                    if (itemSize != null) {
+                        shippableItemSizes.add(itemSize);
+                    }
                 }
 
                 // add the feature quantities
                 BigDecimal quantity = (BigDecimal) itemMap.get("quantity");
-                Set<String> featureSet = UtilGenerics.checkSet(itemMap.get("featureSet"));
-                if (UtilValidate.isNotEmpty(featureSet)) {
-                    for (String featureId: featureSet) {
-                        BigDecimal featureQuantity = shippableFeatureMap.get(featureId);
-                        if (featureQuantity == null) {
-                            featureQuantity = BigDecimal.ZERO;
+                if (itemMap.containsKey("featureSet")) {
+                    Set<String> featureSet = UtilGenerics.checkSet(itemMap.get("featureSet"));
+                    if (UtilValidate.isNotEmpty(featureSet)) {
+                        for (String featureId: featureSet) {
+                            BigDecimal featureQuantity = shippableFeatureMap.get(featureId);
+                            if (featureQuantity == null) {
+                                featureQuantity = BigDecimal.ZERO;
+                            }
+                            featureQuantity = featureQuantity.add(quantity);
+                            shippableFeatureMap.put(featureId, featureQuantity);
                         }
-                        featureQuantity = featureQuantity.add(quantity);
-                        shippableFeatureMap.put(featureId, featureQuantity);
                     }
                 }
 
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/FastLoadCache.groovy b/applications/product/webapp/catalog/WEB-INF/actions/FastLoadCache.groovy
index 7f0f0c3..dab89b1 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/FastLoadCache.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/FastLoadCache.groovy
@@ -26,7 +26,7 @@
 messageList.add("Loading Categories...");
 UtilTimer ctimer = new UtilTimer();
 messageList.add(ctimer.timerString("Before category find"));
-categories = delegator.find("ProductCategory", null, null, null, null, null);
+categories = from("ProductCategory").queryIterator();
 messageList.add(ctimer.timerString("Before load all categories into cache"));
 
 category = null;
@@ -45,7 +45,7 @@
 messageList.add("Loading Products...");
 UtilTimer ptimer = new UtilTimer();
 messageList.add(ptimer.timerString("Before product find"));
-products = delegator.find("Product", null, null, null, null, null);
+products = from("Product").queryIterator();
 messageList.add(ptimer.timerString("Before load all products into cache"));
 product = null;
 long numProducts = 0;
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/category/CategoryTree.groovy b/applications/product/webapp/catalog/WEB-INF/actions/category/CategoryTree.groovy
index 750d073..693d901 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/category/CategoryTree.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/category/CategoryTree.groovy
@@ -47,7 +47,7 @@
 
 completedTree =  [];
 // Get the Catalogs
-prodCatalogs = delegator.findList("ProdCatalog", null, null, null, null, false);
+prodCatalogs = from("ProdCatalog").queryList();
 if (prodCatalogs) {
     prodCatalogs.each { prodCatalog ->
         prodCatalogMap = [:];
@@ -55,7 +55,7 @@
         prodCatalogMap.categoryName = prodCatalog.getString("catalogName");
         prodCatalogMap.isCatalog = true;
         prodCatalogMap.isCategoryType = false;
-        prodCatalogCategories = EntityUtil.filterByDate(delegator.findByAnd("ProdCatalogCategory", ["prodCatalogId" : prodCatalog.prodCatalogId], null, false));
+        prodCatalogCategories = from("ProdCatalogCategory").where("prodCatalogId", prodCatalog.prodCatalogId).filterByDate().queryList();
         if (prodCatalogCategories) {
             prodCatalogMap.child = separateRootType(prodCatalogCategories);
         }
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/category/CreateProductInCategoryCheckExisting.groovy b/applications/product/webapp/catalog/WEB-INF/actions/category/CreateProductInCategoryCheckExisting.groovy
index 15ab9f3..d210621 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/category/CreateProductInCategoryCheckExisting.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/category/CreateProductInCategoryCheckExisting.groovy
@@ -36,14 +36,14 @@
 // get the product for each ID
 products = new ArrayList(productIds.size());
 productIds.each { productId ->
-    product = delegator.findOne("Product", UtilMisc.toMap("productId", productId), true);
+    product = from("Product").where("productId", productId).cache(true).queryOne();
     products.add(product);
 }
 
 productFeatureAndTypeDatas = new ArrayList(featureIdByType.size());
 featureIdByType.each { featureIdByTypeEntry ->
-    productFeatureType = delegator.findOne("ProductFeatureType", UtilMisc.toMap("productFeatureTypeId", featureIdByTypeEntry.key), true);
-    productFeature = delegator.findOne("ProductFeature", UtilMisc.toMap("productFeatureId", featureIdByTypeEntry.value), true);
+    productFeatureType = from("ProductFeatureType").where("productFeatureTypeId", featureIdByTypeEntry.key).cache(true).queryOne();
+    productFeature = from("ProductFeature").where("productFeatureId", featureIdByTypeEntry.value).cache(true).queryOne();
     productFeatureAndTypeData = [:];
     productFeatureAndTypeData.productFeatureType = productFeatureType;
     productFeatureAndTypeData.productFeature = productFeature;
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategory.groovy b/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategory.groovy
index b6a4169..73df0f1 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategory.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategory.groovy
@@ -30,7 +30,7 @@
 if (productCategory) {
     primaryParentCategory = productCategory.getRelatedOne("PrimaryParentProductCategory", false);
 } else if (primParentCatIdParam) {
-    primaryParentCategory = delegator.findOne("ProductCategory", [productCategoryId : primParentCatIdParam], false);
+    primaryParentCategory = from("ProductCategory").where("productCategoryId", primParentCatIdParam).queryOne();
 }
 context.primaryParentCategory = primaryParentCategory;
 
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategoryContentContent.groovy b/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategoryContentContent.groovy
index 21f9428..29f303f 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategoryContentContent.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategoryContentContent.groovy
@@ -38,7 +38,7 @@
     context.contentFormTitle = "${uiLabelMap.ProductUpdateSEOContentCategory}";
 }
 if ("RELATED_URL".equals(prodCatContentTypeId)) {
-    contentList = delegator.findByAnd("ContentDataResourceView", UtilMisc.toMap("contentId", contentId), null, false);
+    contentList = from("ContentDataResourceView").where("contentId", contentId).queryList();
     if (contentList) {
         context.contentId = contentList.get(0).contentId;
         context.dataResourceId = contentList.get(0).dataResourceId;
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategoryProducts.groovy b/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategoryProducts.groovy
index 3d9bc50..8b727b6 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategoryProducts.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategoryProducts.groovy
@@ -34,7 +34,7 @@
 paramInMap.viewSizeString = parameters.get("VIEW_SIZE");
 
 // Returns: viewIndex, viewSize, lowIndex, highIndex, listSize, productCategory, productCategoryMembers
-outMap = dispatcher.runSync("getProductCategoryAndLimitedMembers", paramInMap);
+outMap = runService('getProductCategoryAndLimitedMembers', paramInMap);
 context.viewIndex = outMap.viewIndex;
 context.viewSize = outMap.viewSize;
 context.lowIndex = outMap.lowIndex;
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategorySEO.groovy b/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategorySEO.groovy
index 1d490ff..60a54cc 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategorySEO.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/category/EditCategorySEO.groovy
@@ -19,21 +19,21 @@
 
 productCategoryId = parameters.productCategoryId;
 if (productCategoryId) {
-    productCategoryContents  = delegator.findByAnd("ProductCategoryContent", ["productCategoryId" : productCategoryId], null, false);
+    productCategoryContents  = from("ProductCategoryContent").where("productCategoryId", productCategoryId).queryList();
     productCategoryContents.each{ productCategoryContent->
         if (productCategoryContent.prodCatContentTypeId == "PAGE_TITLE") {
-            contentTitle  = delegator.findOne("Content", ["contentId" : productCategoryContent.contentId], false);
-            dataTextTitle  = delegator.findOne("ElectronicText", ["dataResourceId" : contentTitle.dataResourceId], false);
+            contentTitle  = from("Content").where("contentId", productCategoryContent.contentId).queryOne();
+            dataTextTitle  = from("ElectronicText").where("dataResourceId", contentTitle.dataResourceId).queryOne();
             context.title = dataTextTitle.textData;
         }
         if (productCategoryContent.prodCatContentTypeId == "META_KEYWORD") {
-            contentMetaKeyword  = delegator.findOne("Content", ["contentId" : productCategoryContent.contentId], false);
-            dataTextMetaKeyword  = delegator.findOne("ElectronicText", ["dataResourceId" : contentMetaKeyword.dataResourceId], false);
+            contentMetaKeyword  = from("Content").where("contentId", productCategoryContent.contentId).queryOne();
+            dataTextMetaKeyword  = from("ElectronicText").where("dataResourceId", contentMetaKeyword.dataResourceId).queryOne();
             context.metaKeyword = dataTextMetaKeyword.textData;
         }
         if (productCategoryContent.prodCatContentTypeId == "META_DESCRIPTION") {
-            contentMetaDescription  = delegator.findOne("Content", ["contentId" : productCategoryContent.contentId], false);
-            dataTextMetaDescription  = delegator.findOne("ElectronicText", ["dataResourceId" : contentMetaDescription.dataResourceId], false);
+            contentMetaDescription  = from("Content").where("contentId", productCategoryContent.contentId).queryOne();
+            dataTextMetaDescription  = from("ElectronicText").where("dataResourceId", contentMetaDescription.dataResourceId).queryOne();
             context.metaDescription = dataTextMetaDescription.textData;
         }
     }
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 322cef3..0370d1e 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/config/EditProductConfigItemContentContent.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/config/EditProductConfigItemContentContent.groovy
@@ -28,7 +28,7 @@
 
 description = request.getParameter("description") ?: null;
 
-productContent = delegator.findOne("ProdConfItemContent", [contentId : contentId, configItemId : configItemId, confItemContentTypeId : confItemContentTypeId, fromDate : fromDate], false);
+productContent = from("ProdConfItemContent").where("contentId", contentId, "configItemId", configItemId, "confItemContentTypeId", confItemContentTypeId, "fromDate", fromDate).queryOne();
 if (!productContent) {
     productContent = [:];
     productContent.configItemId = configItemId;
@@ -45,7 +45,7 @@
 
 context.contentId = contentId;
 if (contentId) {
-    content = delegator.findOne("Content", [contentId : contentId], false);
+    content = from("Content").where("contentId", contentId).queryOne();
     context.content = content;
 } else {
     content = [:];
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/feature/EditFeatureCategoryFeatures.groovy b/applications/product/webapp/catalog/WEB-INF/actions/feature/EditFeatureCategoryFeatures.groovy
index c0ab311..c1b8ac7 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/feature/EditFeatureCategoryFeatures.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/feature/EditFeatureCategoryFeatures.groovy
@@ -35,18 +35,18 @@
 productFeatureCategoryId = parameters.get("productFeatureCategoryId");
 context.productFeatureCategoryId = productFeatureCategoryId;
 
-context.curProductFeatureCategory = delegator.findOne("ProductFeatureCategory", [productFeatureCategoryId : productFeatureCategoryId], false);
+context.curProductFeatureCategory = from("ProductFeatureCategory").where("productFeatureCategoryId", productFeatureCategoryId).queryOne();
 
-context.productFeatureTypes = delegator.findList("ProductFeatureType", null, null, ['description'], null, false);
+context.productFeatureTypes = from("ProductFeatureType").orderBy("description").queryList();
 
-context.productFeatureCategories = delegator.findList("ProductFeatureCategory", null, null, ['description'], null, false);
+context.productFeatureCategories = from("ProductFeatureCategory").orderBy("description").queryList();
 
 //we only need these if we will be showing the apply feature to category forms
 if (productId) {
-    context.productFeatureApplTypes = delegator.findList("ProductFeatureApplType", null, null, ['description'], null, false);
+    context.productFeatureApplTypes = from("ProductFeatureApplType").orderBy("description").queryList();
 }
 
-productFeaturesSize = delegator.findCountByCondition("ProductFeature", EntityCondition.makeCondition("productFeatureCategoryId", EntityOperator.EQUALS, productFeatureCategoryId), null, null);
+productFeaturesSize = from("ProductFeature").where("productFeatureCategoryId", productFeatureCategoryId).queryCount();
 
 highIndex = 0;
 lowIndex = 0;
@@ -66,17 +66,17 @@
 context.lowIndex = lowIndex;
 context.highIndex = highIndex;
 
-whereCondition = EntityCondition.makeCondition([productFeatureCategoryId : productFeatureCategoryId], EntityOperator.AND);
-EntityFindOptions efo = new EntityFindOptions();
-efo.setDistinct(true);
-efo.setResultSetType(EntityFindOptions.TYPE_SCROLL_INSENSITIVE);
-efo.setMaxRows(highIndex);
-
 boolean beganTransaction = false;
 try {
     beganTransaction = TransactionUtil.begin();
 
-    productFeaturesEli = delegator.find("ProductFeature", whereCondition, null, null, ['productFeatureTypeId', 'defaultSequenceNum', 'description'], efo);
+    productFeaturesEli = from("ProductFeature")
+                            .where("productFeatureCategoryId", productFeatureCategoryId)
+                            .orderBy("productFeatureTypeId", "defaultSequenceNum", "description")
+                            .distinct()
+                            .cursorScrollInsensitive()
+                            .maxRows(highIndex)
+                            .queryIterator();
     productFeatures = productFeaturesEli.getPartialList(lowIndex + 1, highIndex - lowIndex);
     productFeaturesEli.close();
 } catch (GenericEntityException e) {
@@ -103,7 +103,7 @@
 productFeatureApplIter = null;
 while (productFeatureIter) {
     productFeature = productFeatureIter.next();
-    productFeatureAppls = delegator.findList("ProductFeatureAppl", EntityCondition.makeCondition([productId : productId, productFeatureId : productFeature.productFeatureId]), null, null, null, false);
+    productFeatureAppls = from("ProductFeatureAppl").where("productId", productId, "productFeatureId", productFeature.productFeatureId).queryList();
     productFeatureApplIter = productFeatureAppls.iterator();
     while (productFeatureApplIter) {
         productFeatureAppl = productFeatureApplIter.next();
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/feature/EditFeatureGroups.groovy b/applications/product/webapp/catalog/WEB-INF/actions/feature/EditFeatureGroups.groovy
index 3c1f658..2044a5c 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/feature/EditFeatureGroups.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/feature/EditFeatureGroups.groovy
@@ -19,4 +19,4 @@
 
 context.hasPermission = security.hasEntityPermission("CATALOG", "_VIEW", session)
 
-context.productFeatureGroups = delegator.findList("ProductFeatureGroup", null, null, null, null, false);
+context.productFeatureGroups = from("ProductFeatureGroup").queryList();
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/feature/QuickAddProductFeatures.groovy b/applications/product/webapp/catalog/WEB-INF/actions/feature/QuickAddProductFeatures.groovy
index eaa310c..bb6fb94 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/feature/QuickAddProductFeatures.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/feature/QuickAddProductFeatures.groovy
@@ -17,6 +17,6 @@
  * under the License.
  */
 
-context.productFeatureTypes = delegator.findList("ProductFeatureType", null, null, ['description'], null, true);
+context.productFeatureTypes = from("ProductFeatureType").orderBy("description").cache(true).queryList();
 
-context.featureCategory = delegator.findOne("ProductFeatureCategory", [productFeatureCategoryId : parameters.productFeatureCategoryId], false);
+context.featureCategory = from("ProductFeatureCategory").where("productFeatureCategoryId", parameters.productFeatureCategoryId).queryOne();
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/find/advancedsearchoptions.groovy b/applications/product/webapp/catalog/WEB-INF/actions/find/advancedsearchoptions.groovy
index e600e72..c7d4c7a 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/find/advancedsearchoptions.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/find/advancedsearchoptions.groovy
@@ -28,7 +28,7 @@
     currentCatalogId = CatalogWorker.getCurrentCatalogId(request);
     searchCategoryId = CatalogWorker.getCatalogSearchCategoryId(request, currentCatalogId);
 }
-searchCategory = delegator.findOne("ProductCategory", [productCategoryId : searchCategoryId], false);
+searchCategory = from("ProductCategory").where("productCategoryId", searchCategoryId).queryOne();
 
 if (searchCategoryId) {
     productFeaturesByTypeMap = ParametricSearch.makeCategoryFeatureLists(searchCategoryId, delegator, 2000);
@@ -46,10 +46,10 @@
 searchSortOrderString = ProductSearchSession.searchGetSortOrderString(false, request);
 
 // get suppliers in system
-supplerPartyRoleAndPartyDetails = delegator.findList("PartyRoleAndPartyDetail", EntityCondition.makeCondition([roleTypeId : 'SUPPLIER']), null, ['groupName', 'firstName'], null, false);
+supplerPartyRoleAndPartyDetails = from("PartyRoleAndPartyDetail").where(roleTypeId : "SUPPLIER").orderBy("groupName", "firstName").queryList();
 
 // get the GoodIdentification types
-goodIdentificationTypes = delegator.findList("GoodIdentificationType", null, null, ['description'], null, false);
+goodIdentificationTypes = from("GoodIdentificationType").orderBy("description").queryList();
 
 context.searchCategoryId = searchCategoryId;
 context.searchCategory = searchCategory;
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/find/keywordsearch.groovy b/applications/product/webapp/catalog/WEB-INF/actions/find/keywordsearch.groovy
index 8f15813..7a0c482 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/find/keywordsearch.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/find/keywordsearch.groovy
@@ -28,12 +28,12 @@
 prodCatalogId = CatalogWorker.getCurrentCatalogId(request);
 result = ProductSearchSession.getProductSearchResult(request, delegator, prodCatalogId);
 
-applicationTypes = delegator.findList("ProductFeatureApplType", null, null, ['description'], null, false);
+applicationTypes = from("ProductFeatureApplType").orderBy("description").queryList();
 
 expr = EntityCondition.makeCondition(EntityCondition.makeCondition("showInSelect", EntityOperator.EQUALS, null),
                                      EntityOperator.OR,
                                      EntityCondition.makeCondition("showInSelect", EntityOperator.NOT_EQUAL, "N"));
-productCategories = delegator.findList("ProductCategory", expr, null, ['description'], null, false);
+productCategories = from("ProductCategory").where(expr).orderBy("description").queryList();
 
 context.applicationTypes = applicationTypes;
 context.productCategories = productCategories;
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/find/miniproductlist.groovy b/applications/product/webapp/catalog/WEB-INF/actions/find/miniproductlist.groovy
index 4f3fc76..6e90eba 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/find/miniproductlist.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/find/miniproductlist.groovy
@@ -42,7 +42,7 @@
     paramInMap.checkViewAllow = false;
 
     // Returns: viewIndex, viewSize, lowIndex, highIndex, listSize, productCategory, productCategoryMembers
-    outMap = dispatcher.runSync("getProductCategoryAndLimitedMembers", paramInMap);
+    outMap = runService('getProductCategoryAndLimitedMembers', paramInMap);
     context.viewIndex = outMap.viewIndex;
     context.viewSize = outMap.viewSize;
     context.lowIndex = outMap.lowIndex;
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/find/sidecatalogs.groovy b/applications/product/webapp/catalog/WEB-INF/actions/find/sidecatalogs.groovy
index 95c79bb..7b07b3f 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/find/sidecatalogs.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/find/sidecatalogs.groovy
@@ -32,7 +32,7 @@
 
 //prodCatalogs
 if (isOpen) {
-    prodCatalogs = delegator.findList("ProdCatalog", null, null, null, null, false);
+    prodCatalogs = from("ProdCatalog").queryList();
     context.prodCatalogs = prodCatalogs;
 }
 
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/find/sidedeepcategory.groovy b/applications/product/webapp/catalog/WEB-INF/actions/find/sidedeepcategory.groovy
index d815c0f..95b75ba 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/find/sidedeepcategory.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/find/sidedeepcategory.groovy
@@ -41,7 +41,7 @@
 currentTopCategory = null;
 if (isOpen) {
     CategoryWorker.getRelatedCategories(request, "topLevelList", currentTopCategoryId, false);
-    currentTopCategory = delegator.findOne("ProductCategory", [productCategoryId : currentTopCategoryId], true);
+    currentTopCategory = from("ProductCategory").where("productCategoryId", currentTopCategoryId).cache(true).queryOne();
     context.topLevelList = request.getAttribute("topLevelList");
 }
 curCategoryId = UtilFormatOut.checkNull(requestParameters.productCategoryId);
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/ImageGallery.groovy b/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/ImageGallery.groovy
index 2b5458b..72e2823 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/ImageGallery.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/ImageGallery.groovy
@@ -28,15 +28,14 @@
 import org.ofbiz.entity.util.*;
 
 productImageList = [];
-productContentAndInfoImageManamentList = delegator.findByAnd("ProductContentAndInfo", ["productId": productId, productContentTypeId : "IMAGE", "statusId" : "IM_APPROVED"], ["sequenceNum"], false);
+productContentAndInfoImageManamentList = from("ProductContentAndInfo").where("productId", productId, "productContentTypeId", "IMAGE", "statusId", "IM_APPROVED").orderBy("sequenceNum").queryList();
 if(productContentAndInfoImageManamentList) {
     productContentAndInfoImageManamentList.each { productContentAndInfoImageManament ->
-        contentAssocThumbList = delegator.findByAnd("ContentAssoc", [contentId : productContentAndInfoImageManament.contentId, contentAssocTypeId : "IMAGE_THUMBNAIL"], null, false);
-        contentAssocThumb = EntityUtil.getFirst(contentAssocThumbList);
+        contentAssocThumb = from("ContentAssoc").where("contentId", productContentAndInfoImageManament.contentId, "contentAssocTypeId", "IMAGE_THUMBNAIL").queryFirst();
         if(contentAssocThumb) {
-            imageContentThumb = delegator.findOne("Content", [contentId : contentAssocThumb.contentIdTo], false);
+            imageContentThumb = from("Content").where("contentId", contentAssocThumb.contentIdTo).queryOne();
             if(imageContentThumb) {
-                productImageThumb = delegator.findOne("ContentDataResourceView", [contentId : imageContentThumb.contentId, drDataResourceId : imageContentThumb.dataResourceId], false);
+                productImageThumb = from("ContentDataResourceView").where("contentId", imageContentThumb.contentId, "drDataResourceId", imageContentThumb.dataResourceId).queryOne();
                 productImageMap = [:];
                 productImageMap.contentId = productContentAndInfoImageManament.contentId;
                 productImageMap.dataResourceId = productContentAndInfoImageManament.dataResourceId;
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/ImageRecentlyApproved.groovy b/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/ImageRecentlyApproved.groovy
index 6191668..2b681de 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/ImageRecentlyApproved.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/ImageRecentlyApproved.groovy
@@ -45,15 +45,11 @@
     exprs.add(EntityCondition.makeCondition("statusId",EntityOperator.EQUALS, "IM_APPROVED"))
     exprs.add(EntityCondition.makeCondition("purchaseFromDate", EntityOperator.GREATER_THAN_EQUAL_TO, timeStampDate1))
     exprs.add(EntityCondition.makeCondition("purchaseFromDate", EntityOperator.LESS_THAN, timeStampDate2))
-    def fieldsToSelect = UtilMisc.toSet("productId")
-    def findOptions = new EntityFindOptions()
-    findOptions.setDistinct(true)
     // query result
-    def productContentAndInfoList = delegator.findList("ProductContentAndInfo", EntityCondition.makeCondition(exprs, EntityOperator.AND), fieldsToSelect, null, findOptions, false)
+    def productContentAndInfoList = select("productId").from("ProductContentAndInfo").where(exprs).distinct().queryList();
     
     // finding time
-    def orderBy = UtilMisc.toList("productId")
-    def timeList = delegator.findList("ProductContentAndInfo", EntityCondition.makeCondition(exprs, EntityOperator.AND), null, orderBy, null, false)
+    def timeList = from("ProductContentAndInfo").where(exprs).orderBy("productId").queryList();
     def groupByTimeList =  timeList.groupBy{it.productId}
     def tempTimeList = []
     groupByTimeList.each() {
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/ImageUpload.groovy b/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/ImageUpload.groovy
index 3c72de6..2bb9a0f 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/ImageUpload.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/ImageUpload.groovy
@@ -143,4 +143,4 @@
     }
 }
 
-context.productFeatures = delegator.findList("ProductFeature", EntityCondition.makeCondition([productFeatureTypeId : "SIZE", productFeatureCategoryId : "IMAGE"]), null, null, null, false);
+context.productFeatures = from("ProductFeature").where("productFeatureTypeId", "SIZE", "productFeatureCategoryId", "IMAGE").queryList();
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/SetDefaultImage.groovy b/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/SetDefaultImage.groovy
index 8f93b8e..d52b01a 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/SetDefaultImage.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/SetDefaultImage.groovy
@@ -38,7 +38,7 @@
 String fileType = "original";
 String productId = request.getParameter("productId");
 
-productContentList = delegator.findByAnd("ProductContentAndInfo", UtilMisc.toMap("productId", productId, "productContentTypeId", "DEFAULT_IMAGE"), null, false);
+productContentList = from("ProductContentAndInfo").where("productId", productId, "productContentTypeId", "DEFAULT_IMAGE").queryList();
 if (productContentList) {
     dataResourceName = productContentList.get(0).drDataResourceName
 }
@@ -60,7 +60,7 @@
 
 // Start ProductContent stuff
 if (productId) {
-    product = delegator.findOne("Product",["productId" : productId], false);
+    product = from("Product").where("productId", productId).queryOne();
     context.productId = productId;
 }
 
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/seoLocales.groovy b/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/seoLocales.groovy
index 944f6af..83bac11 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/seoLocales.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/seoLocales.groovy
@@ -32,7 +32,7 @@
 def productTextData;
 contentAssocs.each { contentAssoc ->
 
-content = delegator.findOne("Content",[contentId : contentAssoc.contentIdTo], false);
+content = from("Content").where("contentId", contentAssoc.contentIdTo).queryOne();
 localeString = content.localeString;
 
     if (serverLocal == "au") {
@@ -58,7 +58,7 @@
     }
     
     if (localeString == nameLocal) {
-            electronicText = delegator.findOne("ElectronicText",[dataResourceId : content.dataResourceId], false);
+            electronicText = from("ElectronicText").where("dataResourceId", content.dataResourceId).queryOne();
             productTextData = electronicText.textData;
     }
 
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/sortSequenceNum.groovy b/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/sortSequenceNum.groovy
index 48155af..296d23d 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/sortSequenceNum.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/imagemanagement/sortSequenceNum.groovy
@@ -20,12 +20,12 @@
 import org.ofbiz.entity.*
 import org.ofbiz.base.util.*
 
-allSequenceNums = delegator.findByAnd("ProductContent", ["productId":parameters.productId, "productContentTypeId":"IMAGE"], ["sequenceNum"], false)
-nullSequenceNums = delegator.findByAnd("ProductContent", ["productId":parameters.productId, "productContentTypeId":"IMAGE", "sequenceNum":null], null, false)
+allSequenceNums = from("ProductContent").where("productId", parameters.productId, "productContentTypeId", "IMAGE").queryList();
+nullSequenceNums = from("ProductContent").where("productId", parameters.productId, "productContentTypeId", "IMAGE", "sequenceNum", null).queryList();
 productContents = allSequenceNums - nullSequenceNums
 def duplicate = 0
 if(parameters.sequenceNum){
-    findExisted = delegator.findByAnd("ProductContent", ["productId":parameters.productId, "productContentTypeId":"IMAGE", "sequenceNum":(Long)parameters.sequenceNum], null, false)
+    findExisted = from("ProductContent").where("productId", parameters.productId, "productContentTypeId", "IMAGE", "sequenceNum", (Long)parameters.sequenceNum).queryList();
     duplicate = findExisted.size()
 }
 if(duplicate > 1){
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/lookup/LookupVariantProduct.groovy b/applications/product/webapp/catalog/WEB-INF/actions/lookup/LookupVariantProduct.groovy
index b6f4e39..f1ba139 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/lookup/LookupVariantProduct.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/lookup/LookupVariantProduct.groovy
@@ -22,9 +22,9 @@
 productId = request.getParameter("productId");
 productVariantId = productId + "_";
 productFeatureIds = "";
-product = delegator.findOne("Product", [productId : productId], false);
+product = from("Product").where("productId", productId).queryOne();
 
-result = dispatcher.runSync("getProductFeaturesByType", [productId : productId, productFeatureApplTypeId : "SELECTABLE_FEATURE"]);
+result = runService('getProductFeaturesByType', [productId : productId, productFeatureApplTypeId : "SELECTABLE_FEATURE"]);
 featureTypes = result.productFeatureTypes;
 featuresByTypes = result.productFeaturesByType;
 searchFeatures = [];
@@ -39,7 +39,7 @@
         if (selectedFeatureTypeValue) {
             featureTypeAndValues.selectedFeatureId = selectedFeatureTypeValue;
             selectedFeatureTypeValues.add(selectedFeatureTypeValue);
-            feature = delegator.findOne("ProductFeature", [productFeatureId : selectedFeatureTypeValue], true);
+            feature = from("ProductFeature").where("productFeatureId", selectedFeatureTypeValue).cache(true).queryOne();
             productVariantId += feature.getString("idCode") ?: "";
             productFeatureIds += "|" + selectedFeatureTypeValue;
         }
@@ -48,7 +48,7 @@
 
 variants = [];
 //if (selectedFeatureTypeValues) {
-    result = dispatcher.runSync("getAllExistingVariants", [productId : productId, productFeatureAppls : selectedFeatureTypeValues]);
+    result = runService('getAllExistingVariants', [productId : productId, productFeatureAppls : selectedFeatureTypeValues]);
     variants = result.variantProductIds;
 //}
 
@@ -56,7 +56,7 @@
 productFeatureIdsPar = request.getParameter("productFeatureIds");
 productVariantIdPar = request.getParameter("productVariantId");
 if (productVariantIdPar && productFeatureIdsPar) {
-    result = dispatcher.runSync("quickAddVariant", [productId : productId, productFeatureIds : productFeatureIdsPar, productVariantId : productVariantIdPar]);
+    result = runService('quickAddVariant', [productId : productId, productFeatureIds : productFeatureIdsPar, productVariantId : productVariantIdPar]);
 }
 
 context.product = product;
@@ -66,7 +66,7 @@
 // also need the variant products themselves
 variantProducts = [];
 variants.each { variantId ->
-    variantProducts.add(delegator.findOne("Product", [productId : variantId], true));
+    variantProducts.add(from("Product").where("productId", variantId).cache(true).queryOne());
 }
 context.variantProducts = variantProducts;
 
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/price/EditProductPriceRules.groovy b/applications/product/webapp/catalog/WEB-INF/actions/price/EditProductPriceRules.groovy
index e1ca3c4..d840afb 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/price/EditProductPriceRules.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/price/EditProductPriceRules.groovy
@@ -21,9 +21,9 @@
 import org.ofbiz.entity.util.EntityUtil;
 import org.ofbiz.base.util.UtilMisc;
 
-context.inputParamEnums = delegator.findList("Enumeration", EntityCondition.makeCondition([enumTypeId : 'PROD_PRICE_IN_PARAM']), null, ['sequenceId'], null, true);
-context.condOperEnums = delegator.findList("Enumeration", EntityCondition.makeCondition([enumTypeId : 'PROD_PRICE_COND']), null, ['sequenceId'], null, true);
-context.productPriceActionTypes = delegator.findList("ProductPriceActionType", null, null, ['description'], null, true);
+context.inputParamEnums = from("Enumeration").where("enumTypeId", "PROD_PRICE_IN_PARAM").orderBy("sequenceId").cache(true).queryList();
+context.condOperEnums = from("Enumeration").where("enumTypeId", "PROD_PRICE_COND").orderBy("sequenceId").cache(true).queryList();
+context.productPriceActionTypes = from("ProductPriceActionType").orderBy("description").cache(true).queryList();
 
 String priceRuleId = request.getParameter("productPriceRuleId");
 
@@ -33,7 +33,7 @@
 
 if (priceRuleId) {
     productPriceRules = [];
-    productPriceRules.add(delegator.findOne("ProductPriceRule", [productPriceRuleId : priceRuleId], false));
+    productPriceRules.add(from("ProductPriceRule").where("productPriceRuleId", priceRuleId).queryOne());
     productPriceConds = productPriceRules[0].getRelated("ProductPriceCond", null, ["productPriceCondSeqId"], true);
     productPriceActions = productPriceRules[0].getRelated("ProductPriceAction", null, ["productPriceActionSeqId"], true);
     
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/price/EditProductPriceRules_old.groovy b/applications/product/webapp/catalog/WEB-INF/actions/price/EditProductPriceRules_old.groovy
index c2e9fb1..54936f7 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/price/EditProductPriceRules_old.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/price/EditProductPriceRules_old.groovy
@@ -21,11 +21,11 @@
 
 String priceRuleId = request.getParameter("productPriceRuleId");
 if (priceRuleId) {
-    context.productPriceRule = delegator.findOne("ProductPriceRule", [productPriceRuleId : priceRuleId], false);
+    context.productPriceRule = from("ProductPriceRule").where("productPriceRuleId", priceRuleId).queryOne();
 }
 
-context.inputParamEnums = delegator.findList("Enumeration", EntityCondition.makeCondition([enumTypeId : 'PROD_PRICE_IN_PARAM']), null, ['sequenceId'], null, true);
+context.inputParamEnums = from("Enumeration").where("enumTypeId", 'PROD_PRICE_IN_PARAM').orderBy("sequenceId").cache(true).queryList();
 
-context.condOperEnums = delegator.findList("Enumeration", EntityCondition.makeCondition([enumTypeId : 'PROD_PRICE_COND']), null, ['sequenceId'], null, true);
+context.condOperEnums = from("Enumeration").where("enumTypeId", "PROD_PRICE_COND").orderBy("sequenceId").cache(true).queryList();
 
-context.productPriceActionTypes = delegator.findList("ProductPriceActionType", null, null, ['description'], null, true);
+context.productPriceActionTypes = from("ProductPriceActionType").orderBy("description").cache(true).queryList();
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/product/ApplyFeaturesFromCategory.groovy b/applications/product/webapp/catalog/WEB-INF/actions/product/ApplyFeaturesFromCategory.groovy
index f514cf0..59e638b 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/product/ApplyFeaturesFromCategory.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/product/ApplyFeaturesFromCategory.groovy
@@ -32,18 +32,18 @@
 
 context.selFeatureApplTypeId = request.getParameter("productFeatureApplTypeId");
 
-context.curProductFeatureCategory = delegator.findOne("ProductFeatureCategory", [productFeatureCategoryId : productFeatureCategoryId], false);
+context.curProductFeatureCategory = from("ProductFeatureCategory").where("productFeatureCategoryId", productFeatureCategoryId).queryOne();
 
-context.productFeatureTypes = delegator.findList("ProductFeatureType", null, null, ['description'], null, false);
+context.productFeatureTypes = from("ProductFeatureType").orderBy("description").queryList();
 
-context.productFeatureCategories = delegator.findList("ProductFeatureCategory", null, null, ['description'], null, false);
+context.productFeatureCategories = from("ProductFeatureCategory").orderBy("description").queryList();
 
 //we only need these if we will be showing the apply feature to category forms
 if (productId) {
-    context.productFeatureApplTypes = delegator.findList("ProductFeatureApplType", null, null, ['description'], null, false);
+    context.productFeatureApplTypes = from("ProductFeatureApplType").orderBy("description").queryList();
 }
 
-productFeaturesSize = delegator.findCountByCondition("ProductFeature", EntityCondition.makeCondition("productFeatureCategoryId", EntityOperator.EQUALS, productFeatureCategoryId), null, null);
+productFeaturesSize = from("ProductFeature").where("productFeatureCategoryId", productFeatureCategoryId).queryCount();
 
 highIndex = 0;
 lowIndex = 0;
@@ -64,17 +64,17 @@
 context.lowIndex = lowIndex;
 context.highIndex = highIndex;
 
-whereCondition = EntityCondition.makeCondition([productFeatureCategoryId : productFeatureCategoryId], EntityOperator.AND);
-EntityFindOptions efo = new EntityFindOptions();
-efo.setDistinct(true);
-efo.setResultSetType(EntityFindOptions.TYPE_SCROLL_INSENSITIVE);
-efo.setMaxRows(highIndex);
-
 boolean beganTransaction = false;
 try {
     beganTransaction = TransactionUtil.begin();
 
-    productFeaturesEli = delegator.find("ProductFeature", whereCondition, null, null, ['productFeatureTypeId', 'defaultSequenceNum', 'description'], efo);
+    productFeaturesEli = from("ProductFeature")
+        .where("productFeatureCategoryId", productFeatureCategoryId)
+        .orderBy("productFeatureTypeId", "defaultSequenceNum", "description")
+        .distinct()
+        .cursorScrollInsensitive()
+        .maxRows(highIndex)
+        .queryIterator();
     productFeatures = productFeaturesEli.getPartialList(lowIndex + 1, highIndex - lowIndex);
     productFeaturesEli.close();
 } catch (GenericEntityException e) {
@@ -101,7 +101,7 @@
 productFeatureApplIter = null;
 while (productFeatureIter) {
     productFeature = productFeatureIter.next();
-    productFeatureAppls = delegator.findList("ProductFeatureAppl", EntityCondition.makeCondition([productId : productId, productFeatureId : productFeature.productFeatureId]), null, null, null, false);
+    productFeatureAppls = from("ProductFeatureAppl").where("productId", productId, "productFeatureId", productFeature.productFeatureId).queryList();
     productFeatureApplIter = productFeatureAppls.iterator();
     while (productFeatureApplIter) {
         productFeatureAppl = productFeatureApplIter.next();
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/product/ApplyFeaturesFromGroup.groovy b/applications/product/webapp/catalog/WEB-INF/actions/product/ApplyFeaturesFromGroup.groovy
index 0936e50..5eb5df0 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/product/ApplyFeaturesFromGroup.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/product/ApplyFeaturesFromGroup.groovy
@@ -26,7 +26,7 @@
 
 productFeatureGroupId = parameters.get("productFeatureGroupId");
 if (productFeatureGroupId) {
-    productFeatureGroup = delegator.findOne("ProductFeatureGroup", [productFeatureGroupId : productFeatureGroupId], false);
+    productFeatureGroup = from("ProductFeatureGroup").where("productFeatureGroupId", productFeatureGroupId).queryOne();
     productFeatures = [];
     productFeatureGroupAppls = productFeatureGroup.getRelated("ProductFeatureGroupAppl", null, ['sequenceNum'], false);
     for (pFGAi = productFeatureGroupAppls.iterator(); pFGAi;) {
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/product/BestProducts.groovy b/applications/product/webapp/catalog/WEB-INF/actions/product/BestProducts.groovy
index 96663cd..ad5b55e 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/product/BestProducts.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/product/BestProducts.groovy
@@ -28,14 +28,10 @@
 exprList.add(EntityCondition.makeCondition("orderDate", EntityOperator.LESS_THAN_EQUAL_TO, UtilDateTime.getDayEnd(filterDate)));
 exprList.add(EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER"));
 
-orderHeaderList = delegator.findList("OrderHeader", EntityCondition.makeCondition(exprList, EntityOperator.AND), null, null, null, false);
+orderHeaderList = from("OrderHeader").where(exprList).queryList();
 
 orderHeaderList.each { orderHeader ->
-    exprList = [];
-    exprList.add(EntityCondition.makeCondition("orderId", EntityOperator.EQUALS, orderHeader.orderId));
-    exprList.add(EntityCondition.makeCondition("orderItemTypeId", EntityOperator.EQUALS, "PRODUCT_ORDER_ITEM"));
-    exprList.add(EntityCondition.makeCondition("isPromo", EntityOperator.EQUALS, "N"));
-    orderItemList = delegator.findList("OrderItem", EntityCondition.makeCondition(exprList, EntityOperator.AND), null, null, null, false);
+    orderItemList = from("OrderItem").where("orderId", orderHeader.orderId, "orderItemTypeId", "PRODUCT_ORDER_ITEM", "isPromo", "N").queryList();
     
     orderItemList.each { orderItem ->
         orderItemDetail = [:];
@@ -58,7 +54,7 @@
         
         if (inListFlag == false) {
             orderItemDetail.productId = orderItem.productId;
-            product = delegator.findOne("Product", [productId : orderItem.productId], false);
+            product = from("Product").where("productId", orderItem.productId).queryOne()
             contentWrapper = new ProductContentWrapper(product, request);
             orderItemDetail.productName = contentWrapper.get("PRODUCT_NAME");
             orderItemDetail.amount = amount;
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductAssoc.groovy b/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductAssoc.groovy
index c488ff2..4ae1b5f 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductAssoc.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductAssoc.groovy
@@ -57,12 +57,12 @@
     context.fromDate = fromDate;
 }
 
-product = delegator.findOne("Product", [productId : productId], false);
+product = from("Product").where("productId", productId).queryOne();
 if (product) {
     context.product = product;
 }
 
-productAssoc = delegator.findOne("ProductAssoc", [productId : productId, productIdTo : productIdTo, productAssocTypeId : productAssocTypeId, fromDate : fromDate], false);
+productAssoc = from("ProductAssoc").where("productId", productId, "productIdTo", productIdTo, "productAssocTypeId", productAssocTypeId, "fromDate", fromDate).queryOne();
 if (productAssoc) {
     context.productAssoc = productAssoc;
 }
@@ -78,7 +78,7 @@
 context.useValues = useValues;
 context.isCreate = true;
 
-assocTypes = delegator.findList("ProductAssocType", null, null, ['description'], null, false);
+assocTypes = from("ProductAssocType").orderBy("description").queryList();
 context.assocTypes = assocTypes;
 
 if (product) {
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductContentContent.groovy b/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductContentContent.groovy
index c58f5d9..dd0a83e 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductContentContent.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductContentContent.groovy
@@ -43,7 +43,7 @@
     description = null;
 }
 
-productContent = delegator.findOne("ProductContent", [contentId : contentId, productId : productId, productContentTypeId : productContentTypeId, fromDate : fromDate], false);
+productContent = from("ProductContent").where("contentId", contentId, "productId", productId, "productContentTypeId", productContentTypeId, "fromDate", fromDate).queryOne();
 if (!productContent) {
     productContent = [:];
     productContent.productId = productId;
@@ -66,7 +66,7 @@
 content = [:];
 context.contentId = contentId;
 if (contentId) {
-    content = delegator.findOne("Content", [contentId : contentId], false);
+    content = from("Content").where("contentId", contentId).queryOne();
     context.content = content;
 } else {
     if (description) {
@@ -84,8 +84,7 @@
             emailData.subject = subject.textData;
             emailData.subjectDataResourceId = subject.dataResourceId;
         }
-        serviceCtx = [userLogin : userLogin, contentId : contentId, mapKeys : ['plainBody', 'htmlBody']];
-        result = dispatcher.runSync("findAssocContent", serviceCtx);
+        result = runService('findAssocContent', [userLogin : userLogin, contentId : contentId, mapKeys : ['plainBody', 'htmlBody']]);
         contentAssocs = result.get("contentAssocs");
         if (contentAssocs) {
             contentAssocs.each { contentAssoc ->
@@ -135,7 +134,7 @@
     context.textData = textData;
 }
 if (productContentTypeId) {
-    productContentType = delegator.findOne("ProductContentType", [productContentTypeId : productContentTypeId], false);
+    productContentType = from("ProductContentType").where("productContentTypeId", productContentTypeId).queryOne();
     if (productContentType && "DIGITAL_DOWNLOAD".equals(productContentType.parentTypeId)) {
         context.contentFormName = "EditProductContentDownload";
     }
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductFeatures.groovy b/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductFeatures.groovy
index 7c9114c..3478d33 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductFeatures.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductFeatures.groovy
@@ -19,14 +19,12 @@
 
 import org.ofbiz.entity.condition.*;
 
-context.productFeatureAndAppls = delegator.findList('ProductFeatureAndAppl',
-        EntityCondition.makeCondition([productId : productId]), null,
-        ['sequenceNum', 'productFeatureApplTypeId', 'productFeatureTypeId', 'description'], null, false);
+context.productFeatureAndAppls = from("ProductFeatureAndAppl").where("productId", productId).orderBy("sequenceNum", "productFeatureApplTypeId", "productFeatureTypeId", "description").queryList();
 
-context.productFeatureCategories = delegator.findList('ProductFeatureCategory', null, null, ['description'], null, false);
+context.productFeatureCategories = from("ProductFeatureCategory").orderBy("description").queryList();
 
-context.productFeatureApplTypes = delegator.findList('ProductFeatureApplType', null, null, ['description'], null, true);
+context.productFeatureApplTypes = from("ProductFeatureApplType").orderBy("description").cache(true).queryList();
 
-context.productFeatureGroups = delegator.findList('ProductFeatureGroup', null, null, ['description'], null, false);
+context.productFeatureGroups = from("ProductFeatureGroup").orderBy("description").queryList();
 
-context.productFeatureTypes = delegator.findList('ProductFeatureType', null, null, ['description'], null, true);
+context.productFeatureTypes = from("ProductFeatureType").orderBy("description").queryList();
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductInventoryItems.groovy b/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductInventoryItems.groovy
index b07ff73..7017a25 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductInventoryItems.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductInventoryItems.groovy
@@ -27,11 +27,11 @@
     //If product is virtual gather summary data from variants
     if (product.isVirtual && "Y".equals(product.isVirtual)) {
         //Get the virtual product feature types
-        result = dispatcher.runSync("getProductFeaturesByType", [productId : productId, productFeatureApplTypeId : 'SELECTABLE_FEATURE']);
+        result = runService('getProductFeaturesByType', [productId : productId, productFeatureApplTypeId : 'SELECTABLE_FEATURE']);
         featureTypeIds = result.productFeatureTypes;
     
         //Get the variants
-        result = dispatcher.runSync("getAllProductVariants", [productId : productId]);
+        result = runService('getAllProductVariants', [productId : productId]);
         variants = result.assocProducts;
         variantIterator = variants.iterator();
         variantInventorySummaries = [];
@@ -39,7 +39,7 @@
             variant = variantIterator.next();
     
             //create a map of each variant id and inventory summary (all facilities)
-            inventoryAvailable = dispatcher.runSync("getProductInventoryAvailable", [productId : variant.productIdTo]);
+            inventoryAvailable = runService('getProductInventoryAvailable', [productId : variant.productIdTo]);
     
             variantInventorySummary = [productId : variant.productIdTo,
                                        availableToPromiseTotal : inventoryAvailable.availableToPromiseTotal,
@@ -49,7 +49,7 @@
             featureTypeIdsIterator = featureTypeIds.iterator();
             while (featureTypeIdsIterator) {
                 featureTypeId = featureTypeIdsIterator.next();
-                result = dispatcher.runSync("getProductFeatures", [productId : variant.productIdTo, type : 'STANDARD_FEATURE', distinct : featureTypeId]);
+                result = runService('getProductFeatures', [productId : variant.productIdTo, type : 'STANDARD_FEATURE', distinct : featureTypeId]);
                 variantFeatures = result.productFeatures;
                 if (variantFeatures) {
                     //there should only be one result in this collection
@@ -67,9 +67,9 @@
         // The warehouse list is selected
         showAllFacilities = parameters.showAllFacilities;
         if (showAllFacilities && "Y".equals(showAllFacilities)) {
-            facilityList = delegator.findList("Facility", null, null, null, null, false);
+            facilityList = from("Facility").queryList();
         } else {
-            facilityList = delegator.findList("ProductFacility", EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId), null, null, null, false);
+            facilityList = from("ProductFacility").where("productId", productId).queryList();
         }
         facilityIterator = facilityList.iterator();
         dispatcher = request.getAttribute("dispatcher");
@@ -80,7 +80,7 @@
         // are obtained (calling the "getInventoryAvailableByFacility" service)
         while (facilityIterator) {
             facility = facilityIterator.next();
-            resultOutput = dispatcher.runSync("getInventoryAvailableByFacility", [productId : productId, facilityId : facility.facilityId]);
+            resultOutput = runService('getInventoryAvailableByFacility', [productId : productId, facilityId : facility.facilityId]);
     
             quantitySummary = [:];
             quantitySummary.facilityId = facility.facilityId;
@@ -89,7 +89,7 @@
     
             // if the product is a MARKETING_PKG_AUTO/PICK, then also get the quantity which can be produced from components
             if (isMarketingPackage) {
-                resultOutput = dispatcher.runSync("getMktgPackagesAvailable", [productId : productId, facilityId : facility.facilityId]);
+                resultOutput = runService('getMktgPackagesAvailable', [productId : productId, facilityId : facility.facilityId]);
                 quantitySummary.mktgPkgQOH = resultOutput.quantityOnHandTotal;
                 quantitySummary.mktgPkgATP = resultOutput.availableToPromiseTotal;
             }
@@ -97,9 +97,7 @@
             quantitySummaryByFacility.put(facility.facilityId, quantitySummary);
         }
         
-        productInventoryItems = delegator.findByAnd("InventoryItem",
-                [productId : productId],
-                ['facilityId', '-datetimeReceived', '-inventoryItemId'], false);
+        productInventoryItems = from("InventoryItem").where("productId", productId).orderBy("facilityId", "-datetimeReceived", "-inventoryItemId").queryList();
     
         // TODO: get all incoming shipments not yet arrived coming into each facility that this product is in, use a view entity with ShipmentAndItem
         findIncomingShipmentsConds = [];
@@ -119,7 +117,7 @@
         findIncomingShipmentsConds.add(EntityCondition.makeCondition(findIncomingShipmentsStatusConds, EntityOperator.AND));
     
         findIncomingShipmentsStatusCondition = EntityCondition.makeCondition(findIncomingShipmentsConds, EntityOperator.AND);
-        incomingShipmentAndItems = delegator.findList("ShipmentAndItem", findIncomingShipmentsStatusCondition, null, ['-estimatedArrivalDate'], null, false);
+        incomingShipmentAndItems = from("ShipmentAndItem").where(findIncomingShipmentsStatusCondition).orderBy("-estimatedArrivalDate").queryList();
         incomingShipmentAndItemIter = incomingShipmentAndItems.iterator();
         while (incomingShipmentAndItemIter) {
             incomingShipmentAndItem = incomingShipmentAndItemIter.next();
@@ -143,7 +141,7 @@
     
         // --------------------
         // Production Runs
-        resultOutput = dispatcher.runSync("getProductManufacturingSummaryByFacility",
+        resultOutput = runService('getProductManufacturingSummaryByFacility',
                        [productId : productId, userLogin : userLogin]);
         // incoming products
         manufacturingInQuantitySummaryByFacility = resultOutput.summaryInByFacility;
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductQuickAdmin.groovy b/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductQuickAdmin.groovy
index 2f976c0..0180a09 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductQuickAdmin.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductQuickAdmin.groovy
@@ -26,9 +26,9 @@
 
 context.nowTimestampString = UtilDateTime.nowTimestamp().toString();
 
-context.assocTypes = delegator.findList("ProductAssocType", null, null, null, null, false);
+context.assocTypes = from("ProductAssocType").queryList();
 
-context.featureTypes = delegator.findList("ProductFeatureType", null, null, null, null, false);
+context.featureTypes = from("ProductFeatureType").queryList();
 
 // add/remove feature types
 addedFeatureTypes = (HashMap) session.getAttribute("addedFeatureTypes");
@@ -47,7 +47,7 @@
 addFeatureTypeIdIter = addFeatureTypeIdList.iterator();
 while (addFeatureTypeIdIter) {
     String curFeatureTypeId = addFeatureTypeIdIter.next();
-    GenericValue featureType = delegator.findOne("ProductFeatureType", [productFeatureTypeId : curFeatureTypeId], false);
+    GenericValue featureType = from("ProductFeatureType").where("productFeatureTypeId", curFeatureTypeId).queryOne();
     if ((featureType) && !addedFeatureTypes.containsKey(curFeatureTypeId)) {
         addedFeatureTypes.put(curFeatureTypeId, featureType);
     }
@@ -56,7 +56,7 @@
 String[] removeFeatureTypeId = request.getParameterValues("removeFeatureTypeId");
 if (removeFeatureTypeId) {
     for (int i = 0; i < removeFeatureTypeId.length; i++) {
-        GenericValue featureType = delegator.findOne("ProductFeatureType", [productFeatureTypeId : addFeatureTypeId[i]], false);
+        GenericValue featureType = from("ProductFeatureType").where("productFeatureTypeId", addFeatureTypeId[i]).queryOne();
         if ((featureType) && addedFeatureTypes.containsKey(removeFeatureTypeId[i])) {
             addedFeatureTypes.remove(removeFeatureTypeId[i]);
             featuresByType.remove(removeFeatureTypeId[i]);
@@ -84,7 +84,7 @@
     context.productId = productId;
 }
 
-product = delegator.findOne("Product", [productId : productId], false);
+product = from("Product").where("productId", productId).queryOne();
 assocProducts = [];
 featureFloz = [:];
 featureMl = [:];
@@ -108,9 +108,8 @@
     context.product = product;
 
     // get categories
-    allCategories = delegator.findList("ProductCategory",
-            EntityCondition.makeCondition(EntityCondition.makeCondition("showInSelect", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("showInSelect", EntityOperator.NOT_EQUAL, "N")),
-            null, ['description'], null, false);
+    allCategories = from("ProductCategory").where(EntityCondition.makeCondition(EntityCondition.makeCondition("showInSelect", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("showInSelect", EntityOperator.NOT_EQUAL, "N")))
+        .orderBy("description").queryList();
 
     categoryMembers = product.getRelated("ProductCategoryMember", null, null, false);
     categoryMembers = EntityUtil.filterByDate(categoryMembers);
@@ -308,7 +307,7 @@
 context.allCategoryId = allCategoryId;
 
 // show the publish or unpublish section
-prodCatMembs = delegator.findList("ProductCategoryMember", EntityCondition.makeCondition([productCategoryId : allCategoryId, productId : productId]), null, null, null, false);
+prodCatMembs = from("ProductCategoryMember").where("productCategoryId", allCategoryId, "productId", productId).queryList();
 //don't filter by date, show all categories: prodCatMembs = EntityUtil.filterByDate(prodCatMembs);
 
 String showPublish = "false";
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductSEO.groovy b/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductSEO.groovy
index 11da080..b25a60f 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductSEO.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/product/EditProductSEO.groovy
@@ -19,21 +19,21 @@
 
 productId = parameters.productId;
 if (productId) {
-    productContents  = delegator.findByAnd("ProductContent", ["productId" : productId], null, false);
+    productContents  = from("ProductContent").where("productId", productId).queryList();
     productContents.each{ productContent->
         if (productContent.productContentTypeId == "PAGE_TITLE") {
-            contentTitle  = delegator.findOne("Content", ["contentId" : productContent.contentId], false);
-            dataTextTitle  = delegator.findOne("ElectronicText", ["dataResourceId" : contentTitle.dataResourceId], false);
+            contentTitle  = from("Content").where("contentId", productContent.contentId).queryOne();
+            dataTextTitle  = from("ElectronicText").where("dataResourceId", contentTitle.dataResourceId).queryOne();
             context.title = dataTextTitle.textData;
         }
         if (productContent.productContentTypeId == "META_KEYWORD") {
-            contentMetaKeyword  = delegator.findOne("Content", ["contentId" : productContent.contentId], false);
-            dataTextMetaKeyword  = delegator.findOne("ElectronicText", ["dataResourceId" : contentMetaKeyword.dataResourceId], false);
+            contentMetaKeyword  = from("Content").where("contentId", productContent.contentId).queryOne();
+            dataTextMetaKeyword  = from("ElectronicText").where("dataResourceId", contentMetaKeyword.dataResourceId).queryOne();
             context.metaKeyword = dataTextMetaKeyword.textData;
         }
         if (productContent.productContentTypeId == "META_DESCRIPTION") {
-            contentMetaDescription  = delegator.findOne("Content", ["contentId" : productContent.contentId], false);
-            dataTextMetaDescription  = delegator.findOne("ElectronicText", ["dataResourceId" : contentMetaDescription.dataResourceId], false);
+            contentMetaDescription  = from("Content").where("contentId", productContent.contentId).queryOne();
+            dataTextMetaDescription  = from("ElectronicText").where("dataResourceId", contentMetaDescription.dataResourceId).queryOne();
             context.metaDescription = dataTextMetaDescription.textData;
         }
     }
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/product/QuickAddVariants.groovy b/applications/product/webapp/catalog/WEB-INF/actions/product/QuickAddVariants.groovy
index 67d00b4..49187e1 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/product/QuickAddVariants.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/product/QuickAddVariants.groovy
@@ -17,8 +17,8 @@
  * under the License.
  */
 
-result = dispatcher.runSync("getProductFeaturesByType", [productId : productId, productFeatureApplTypeId : 'SELECTABLE_FEATURE']);
+result = runService('getProductFeaturesByType', [productId : productId, productFeatureApplTypeId : 'SELECTABLE_FEATURE']);
 context.featureTypes = result.productFeatureTypes;
 
-result = dispatcher.runSync("getVariantCombinations", [productId : productId]);
+result = runService('getVariantCombinations', [productId : productId]);
 context.featureCombinationInfos = result.featureCombinations;
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/promo/EditProductPromoCode.groovy b/applications/product/webapp/catalog/WEB-INF/actions/promo/EditProductPromoCode.groovy
index 7f9bf1d..4034163 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/promo/EditProductPromoCode.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/promo/EditProductPromoCode.groovy
@@ -21,7 +21,7 @@
 if (!productPromoCodeId) {
     productPromoCodeId = request.getAttribute("productPromoCodeId");
 }
-productPromoCode = delegator.findOne("ProductPromoCode", [productPromoCodeId : productPromoCodeId], false);
+productPromoCode = from("ProductPromoCode").where("productPromoCodeId", productPromoCodeId).queryOne();
 
 productPromoId = null;
 if (productPromoCode) {
@@ -32,7 +32,7 @@
 
 productPromo = null;
 if (productPromoId) {
-    productPromo = delegator.findOne("ProductPromo", [productPromoId : productPromoId], false);
+    productPromo = from("ProductPromo").where("productPromoId", productPromoId).queryOne();
 }
 
 productPromoCodeEmails = null;
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/store/EditProductStorePaySetup.groovy b/applications/product/webapp/catalog/WEB-INF/actions/store/EditProductStorePaySetup.groovy
index 46ea067..98abfc1 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/store/EditProductStorePaySetup.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/store/EditProductStorePaySetup.groovy
@@ -83,5 +83,5 @@
 if (paymentServiceTypeEnumId == "PRDS_PAY_EXTERNAL") {
     context.paymentCustomMethods = null;
 } else {
-    context.paymentCustomMethods = delegator.findList("CustomMethod", customMethodsCond, null, ["description"], null, false);
+    context.paymentCustomMethods = from("CustomMethod").where(customMethodsCond).orderBy("description").queryList();
 }
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/store/EditProductStoreSurveys.groovy b/applications/product/webapp/catalog/WEB-INF/actions/store/EditProductStoreSurveys.groovy
index 8a1fbe7..98c82c4 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/store/EditProductStoreSurveys.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/store/EditProductStoreSurveys.groovy
@@ -25,17 +25,17 @@
 
 productStoreId = request.getParameter("productStoreId");
 if (productStoreId) {
-    productStore = delegator.findOne("ProductStore", [productStoreId : productStoreId], false);
+    productStore = from("ProductStore").where("productStoreId", productStoreId).queryOne();
     context.productStoreId = productStoreId;
     context.productStore = productStore;
 }
 
-context.productStoreSurveys = EntityUtil.filterByDate(delegator.findList("ProductStoreSurveyAppl", EntityCondition.makeCondition([productStoreId : productStoreId]), null, null, null, false));
+context.productStoreSurveys = from("ProductStoreSurveyAppl").where("productStoreId", productStoreId).filterByDate().queryList();
 
-context.surveys = delegator.findList("Survey", null, null, ['description'], null, false);
+context.surveys = from("Survey").orderBy("description").queryOne();
 
-context.surveyApplTypes = delegator.findList("SurveyApplType", null, null, ['description'], null, false);
+context.surveyApplTypes = from("SurveyApplType").orderBy("description").queryFirst();
 
-context.productCategories = delegator.findList("ProductCategory", null, null, ['description'], null, false);
+context.productCategories = from("ProductCategory").orderBy("description").queryList();
 
 context.nowTimestampString = UtilDateTime.nowTimestamp().toString();
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/thesaurus/EditKeywordThesaurus.groovy b/applications/product/webapp/catalog/WEB-INF/actions/thesaurus/EditKeywordThesaurus.groovy
index daf11d9..a995b53 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/thesaurus/EditKeywordThesaurus.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/thesaurus/EditKeywordThesaurus.groovy
@@ -19,9 +19,9 @@
 
 import org.ofbiz.entity.condition.*
 
-relationshipEnums = delegator.findList("Enumeration", EntityCondition.makeCondition([enumTypeId : 'KW_THES_REL']), null, ['sequenceId'], null, true);
+relationshipEnums = from("Enumeration").where("enumTypeId", "KW_THES_REL").orderBy("sequenceId").cache(true).queryList();
 
-keywordThesauruses = delegator.findList("KeywordThesaurus", null, null, ['enteredKeyword'], null, false);
+keywordThesauruses = from("KeywordThesaurus").orderBy("enteredKeyword").queryList();
 
 //if no param sent in make firstLetter 'a' else use firstLetter passed in
 firstLetterString = request.getParameter("firstLetter");
diff --git a/applications/product/webapp/facility/WEB-INF/actions/facility/ComputeProductSellThroughData.groovy b/applications/product/webapp/facility/WEB-INF/actions/facility/ComputeProductSellThroughData.groovy
index 9f92d78..b3723eb 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/facility/ComputeProductSellThroughData.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/facility/ComputeProductSellThroughData.groovy
@@ -28,9 +28,9 @@
         fromDate = Timestamp.valueOf(parameters.fromDateSellThrough);
         thruDate = Timestamp.valueOf(parameters.thruDateSellThrough);
     } catch(Exception e) {}
-    inventoryCountResult = dispatcher.runSync("countProductInventoryOnHand", [productId : productId, facilityId : facilityId, inventoryCountDate : fromDate, userLogin : userLogin]);
+    inventoryCountResult = runService('countProductInventoryOnHand', [productId : productId, facilityId : facilityId, inventoryCountDate : fromDate, userLogin : userLogin]);
     if (inventoryCountResult.quantityOnHandTotal && inventoryCountResult.quantityOnHandTotal > 0) {
-        inventoryShippedForSalesResult = dispatcher.runSync("countProductInventoryShippedForSales", [productId : productId, facilityId : facilityId, fromDate : fromDate, thruDate : thruDate, userLogin : userLogin]);
+        inventoryShippedForSalesResult = runService('countProductInventoryShippedForSales', [productId : productId, facilityId : facilityId, fromDate : fromDate, thruDate : thruDate, userLogin : userLogin]);
         context.sellThroughInitialInventory = inventoryCountResult.quantityOnHandTotal;
         context.sellThroughInventorySold = inventoryShippedForSalesResult.quantityOnHandTotal;
         context.sellThroughPercentage = new BigDecimal(inventoryShippedForSalesResult.quantityOnHandTotal / inventoryCountResult.quantityOnHandTotal * 100, new java.math.MathContext(2));
diff --git a/applications/product/webapp/facility/WEB-INF/actions/facility/CountFacilityInventoryByProduct.groovy b/applications/product/webapp/facility/WEB-INF/actions/facility/CountFacilityInventoryByProduct.groovy
index 75943b9..5d9bf1d 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/facility/CountFacilityInventoryByProduct.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/facility/CountFacilityInventoryByProduct.groovy
@@ -125,7 +125,6 @@
     }
 
     // set distinct on so we only get one row per product
-    findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
     searchCondition = EntityCondition.makeCondition(conditionMap, EntityOperator.AND);
     notVirtualCondition = EntityCondition.makeCondition(EntityCondition.makeCondition("isVirtual", EntityOperator.EQUALS, null),
                                                         EntityOperator.OR,
@@ -223,8 +222,7 @@
         // get the indexes for the partial list
         lowIndex = ((viewIndex.intValue() * viewSize.intValue()) + 1);
         highIndex = (viewIndex.intValue() + 1) * viewSize.intValue();
-        findOpts.setMaxRows(highIndex);
-        prodsEli = delegator.findListIteratorByCondition(prodView, whereCondition, null, null, orderBy, findOpts);
+        prodsEli = from(prodView).where(whereCondition).orderBy(orderBy).cursorScrollInsensitive().maxRows(highIndex).distinct().queryIterator();
 
         // get the partial list for this page
         prods = prodsEli.getPartialList(lowIndex, highIndex);
@@ -259,15 +257,13 @@
             if (checkTime) {
 
                 // Make a query against the sales usage view entity
-                salesUsageIt = delegator.findListIteratorByCondition(salesUsageViewEntity,
-                        EntityCondition.makeCondition(
-                            [EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, facilityId),
-                             EntityCondition.makeCondition("productId", EntityOperator.EQUALS, oneProd.productId),
-                             EntityCondition.makeCondition("statusId", EntityOperator.IN, ['ORDER_COMPLETED', 'ORDER_APPROVED', 'ORDER_HELD']),
-                             EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER"),
-                             EntityCondition.makeCondition("orderDate", EntityOperator.GREATER_THAN_EQUAL_TO, checkTime)
-                            ],
-                            EntityOperator.AND), null, null, null, null);
+                salesUsageIt = from(salesUsageViewEntity)
+                                    .where(EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, facilityId),
+                                        EntityCondition.makeCondition("productId", EntityOperator.EQUALS, oneProd.productId),
+                                        EntityCondition.makeCondition("statusId", EntityOperator.IN, ['ORDER_COMPLETED', 'ORDER_APPROVED', 'ORDER_HELD']),
+                                        EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER"),
+                                        EntityCondition.makeCondition("orderDate", EntityOperator.GREATER_THAN_EQUAL_TO, checkTime))
+                                    .queryIterator();
 
                 // Sum the sales usage quantities found
                 salesUsageQuantity = 0;
@@ -283,14 +279,12 @@
                 salesUsageIt.close();
 
                 // Make a query against the production usage view entity
-                productionUsageIt = delegator.findListIteratorByCondition(productionUsageViewEntity,
-                        EntityCondition.makeCondition(
-                            [EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, facilityId),
-                             EntityCondition.makeCondition("productId", EntityOperator.EQUALS, oneProd.productId),
-                             EntityCondition.makeCondition("workEffortTypeId", EntityOperator.EQUALS, "PROD_ORDER_TASK"),
-                             EntityCondition.makeCondition("actualCompletionDate", EntityOperator.GREATER_THAN_EQUAL_TO, checkTime)
-                            ],
-                            EntityOperator.AND), null, null, null, null);
+                productionUsageIt = from(productionUsageViewEntity)
+                                    .where(EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, facilityId),
+                                         EntityCondition.makeCondition("productId", EntityOperator.EQUALS, oneProd.productId),
+                                         EntityCondition.makeCondition("workEffortTypeId", EntityOperator.EQUALS, "PROD_ORDER_TASK"),
+                                         EntityCondition.makeCondition("actualCompletionDate", EntityOperator.GREATER_THAN_EQUAL_TO, checkTime))
+                                    .queryIterator();
 
                 // Sum the production usage quantities found
                 productionUsageQuantity = 0;
diff --git a/applications/product/webapp/facility/WEB-INF/actions/facility/EditContactMech.groovy b/applications/product/webapp/facility/WEB-INF/actions/facility/EditContactMech.groovy
index 6186e36..557eba2 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/facility/EditContactMech.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/facility/EditContactMech.groovy
@@ -22,7 +22,7 @@
 facilityId = parameters.facilityId;
 context.facilityId = facilityId;
 
-facility = delegator.findOne("Facility", [facilityId : facilityId], false);
+facility = from("Facility").where("facilityId", facilityId).queryOne();
 context.facility = facility;
 
 mechMap = [:];
@@ -62,7 +62,7 @@
 }
 if (cmNewPurposeTypeId) {
     context.contactMechPurposeTypeId = cmNewPurposeTypeId;
-    contactMechPurposeType = delegator.findOne("ContactMechPurposeType", [contactMechPurposeTypeId : cmNewPurposeTypeId], false);
+    contactMechPurposeType = from("ContactMechPurposeType").where("contactMechPurposeTypeId", cmNewPurposeTypeId).queryOne();
     if (contactMechPurposeType) {
         context.contactMechPurposeType = contactMechPurposeType;
     }
diff --git a/applications/product/webapp/facility/WEB-INF/actions/facility/EditFacility.groovy b/applications/product/webapp/facility/WEB-INF/actions/facility/EditFacility.groovy
index 5279148..af76ea8 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/facility/EditFacility.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/facility/EditFacility.groovy
@@ -23,7 +23,7 @@
 if (!facilityId && request.getAttribute("facilityId")) {
   facilityId = request.getAttribute("facilityId");
 }
-facility = delegator.findOne("Facility", [facilityId : facilityId], false);
+facility = from("Facility").where("facilityId", facilityId).queryOne();
 if (!facility) {
   facility = delegator.makeValue("Facility");
   facilityType = delegator.makeValue("FacilityType");
@@ -35,16 +35,16 @@
 context.facilityId = facilityId;
 
 //Facility types
-facilityTypes = delegator.findList("FacilityType", null, null, null, null, false);
+facilityTypes = from("FacilityType").queryList();
 if (facilityTypes) {
   context.facilityTypes = facilityTypes;
 }
 
 // all possible inventory item types
-context.inventoryItemTypes = delegator.findList("InventoryItemType", null, null, ['description'], null, true);
+context.inventoryItemTypes = from("InventoryItemType").orderBy("description").cache(true).queryList();
 
 // weight unit of measures
-context.weightUomList = delegator.findList("Uom", EntityCondition.makeCondition([uomTypeId : 'WEIGHT_MEASURE']), null, null, null, true);
+context.weightUomList = from("Uom").where("uomTypeId", "WEIGHT_MEASURE").cache(true).queryList();
 
 // area unit of measures
-context.areaUomList = delegator.findList("Uom", EntityCondition.makeCondition([uomTypeId : 'AREA_MEASURE']), null, null, null, true);
+context.areaUomList = from("Uom").where("uomTypeId", "AREA_MEASURE").cache(true).queryList();
diff --git a/applications/product/webapp/facility/WEB-INF/actions/facility/EditFacilityLocation.groovy b/applications/product/webapp/facility/WEB-INF/actions/facility/EditFacilityLocation.groovy
index dff2e84..29e0634 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/facility/EditFacilityLocation.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/facility/EditFacilityLocation.groovy
@@ -33,13 +33,13 @@
 }
 
 if (facilityId && locationSeqId) {
-    facilityLocation = delegator.findOne("FacilityLocation", [facilityId : facilityId, locationSeqId : locationSeqId], false);
+    facilityLocation = from("FacilityLocation").where("facilityId", facilityId, "locationSeqId", locationSeqId).queryOne();
 }
 if (facilityId) {
-    facility = delegator.findOne("Facility", [facilityId : facilityId], false);
+    facility = from("Facility").where("facilityId", facilityId).queryOne();
 }
 
-locationTypeEnums = delegator.findList("Enumeration", EntityCondition.makeCondition([enumTypeId : 'FACLOC_TYPE']), null, null, null, false);
+locationTypeEnums = from("Enumeration").where("enumTypeId", "FACLOC_TYPE").queryList();
 
 // ProductFacilityLocation stuff
 productFacilityLocations = null;
diff --git a/applications/product/webapp/facility/WEB-INF/actions/facility/FacilityLocationGeoLocation.groovy b/applications/product/webapp/facility/WEB-INF/actions/facility/FacilityLocationGeoLocation.groovy
index 115c525..a209179 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/facility/FacilityLocationGeoLocation.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/facility/FacilityLocationGeoLocation.groovy
@@ -42,7 +42,7 @@
         context.geoChart = geoChart;

     }

     if (latestGeoPoint && latestGeoPoint.elevationUomId) {

-        elevationUom = delegator.findOne("Uom", [uomId : latestGeoPoint.elevationUomId], false);

+        elevationUom = from("Uom").where("uomId", latestGeoPoint.elevationUomId).queryOne();

         context.elevationUomAbbr = elevationUom.abbreviation;

     }

 }
diff --git a/applications/product/webapp/facility/WEB-INF/actions/facility/FindFacility.groovy b/applications/product/webapp/facility/WEB-INF/actions/facility/FindFacility.groovy
index 8929924..4d141e0 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/facility/FindFacility.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/facility/FindFacility.groovy
@@ -18,7 +18,7 @@
  */
  import org.ofbiz.base.util.*
 
-findResult = delegator.findList("Facility", null, null, null, null, false);
+findResult = from("Facility").queryList();
 findResultSize = findResult.size();
 if (findResultSize == 1) {
     context.showScreen = "one";
diff --git a/applications/product/webapp/facility/WEB-INF/actions/facility/FindFacilityLocation.groovy b/applications/product/webapp/facility/WEB-INF/actions/facility/FindFacilityLocation.groovy
index 786dd15..bcee0bd 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/facility/FindFacilityLocation.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/facility/FindFacilityLocation.groovy
@@ -32,7 +32,7 @@
 itemId = session.getAttribute("inventoryItemId");
 context.itemId = itemId;
 
-facility = delegator.findOne("Facility", [facilityId : facilityId], false);
+facility = from("Facility").where("facilityId", facilityId).queryOne();
 context.facility = facility;
 
 UtilHttp.parametersToAttributes(request);
@@ -46,7 +46,7 @@
             paramMap.remove(key);
         }
     }
-    foundLocations = delegator.findList("FacilityLocation", EntityCondition.makeCondition(paramMap), null, null, null, false);
+    foundLocations = from("FacilityLocation").where(paramMap).queryList();
     if (foundLocations) {
         context.foundLocations = foundLocations;
     }
diff --git a/applications/product/webapp/facility/WEB-INF/actions/facility/FindFacilityTransfers.groovy b/applications/product/webapp/facility/WEB-INF/actions/facility/FindFacilityTransfers.groovy
index d66f41a..3f982de 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/facility/FindFacilityTransfers.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/facility/FindFacilityTransfers.groovy
@@ -39,8 +39,7 @@
     exprsTo = [EntityCondition.makeCondition("facilityIdTo", EntityOperator.EQUALS, facilityId),
                EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "IXF_REQUESTED")];
 }
-ecl = EntityCondition.makeCondition(exprsTo, EntityOperator.AND);
-toTransfers = delegator.findList("InventoryTransfer", ecl, null, ['sendDate'], null, false);
+toTransfers = from("InventoryTransfer").where(exprsTo).orderBy("sendDate").queryList();
 if (toTransfers) {
     context.toTransfers = toTransfers;
 }
@@ -58,7 +57,7 @@
                  EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "IXF_REQUESTED")];
 }
 ecl = EntityCondition.makeCondition(exprsFrom, EntityOperator.AND);
-fromTransfers = delegator.findList("InventoryTransfer", ecl, null, ['sendDate'], null, false);
+fromTransfers = from("InventoryTransfer").where(exprsFrom).orderBy("sendDate").queryList();
 if (fromTransfers) {
     context.fromTransfers = fromTransfers;
 }
diff --git a/applications/product/webapp/facility/WEB-INF/actions/facility/FindInventoryItemsByLabels.groovy b/applications/product/webapp/facility/WEB-INF/actions/facility/FindInventoryItemsByLabels.groovy
index 0b024c5..b465e9b 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/facility/FindInventoryItemsByLabels.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/facility/FindInventoryItemsByLabels.groovy
@@ -62,10 +62,8 @@
         lowIndex = ((viewIndex * viewSize) + 1);
         highIndex = (viewIndex - 1) * viewSize;
 
-        findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
-        findOpts.setMaxRows(highIndex);
         beganTransaction = TransactionUtil.begin();
-        inventoryItemsEli = delegator.findListIteratorByCondition(inventoryItemAndLabelsView, EntityCondition.makeCondition(andCondition, EntityOperator.AND), null, null, null, findOpts);
+        inventoryItemsEli = from(inventoryItemAndLabelsView).where(andCondition).cursorScrollInsensitive().distinct().maxRows(highIndex).queryIterator();
 
         inventoryItemsSize = inventoryItemsEli.getResultsSizeAfterPartialList();
         context.inventoryItemsSize = inventoryItemsSize;
diff --git a/applications/product/webapp/facility/WEB-INF/actions/facility/ViewContactMechs.groovy b/applications/product/webapp/facility/WEB-INF/actions/facility/ViewContactMechs.groovy
index d774b40..7103a20 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/facility/ViewContactMechs.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/facility/ViewContactMechs.groovy
@@ -23,7 +23,7 @@
 context.nowStr = UtilDateTime.nowTimestamp();
 
 facilityId = parameters.facilityId;
-facility = delegator.findOne("Facility", [facilityId : facilityId], false);
+facility = from("Facility").where("facilityId", facilityId).queryOne();
 facilityType = null;
 if (!facility) {
   context.facility = delegator.makeValue("Facility", null);
diff --git a/applications/product/webapp/facility/WEB-INF/actions/facility/ViewFacilityInventoryByProduct.groovy b/applications/product/webapp/facility/WEB-INF/actions/facility/ViewFacilityInventoryByProduct.groovy
index 105e955..a7e4b4c 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/facility/ViewFacilityInventoryByProduct.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/facility/ViewFacilityInventoryByProduct.groovy
@@ -92,7 +92,6 @@
     }
 
     // set distinct on so we only get one row per product
-    findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
     searchCondition = EntityCondition.makeCondition(conditionMap, EntityOperator.AND);
     notVirtualCondition = EntityCondition.makeCondition(EntityCondition.makeCondition("isVirtual", EntityOperator.EQUALS, null),
                                                          EntityOperator.OR,
@@ -128,7 +127,7 @@
     List prods = null;
     try {
         beganTransaction = TransactionUtil.begin();
-        prodsEli = delegator.findListIteratorByCondition(prodView, whereCondition, null, null, ['productId'], findOpts);
+        prodsEli = from(prodView).where(whereCondition).orderBy("productId").cursorScrollInsensitive().distinct().queryIterator();
         prods = prodsEli.getCompleteList();
         prodsEli.close();
     } catch (GenericEntityException e) {
@@ -173,7 +172,7 @@
         oneInventory.reorderQuantity = oneProd.reorderQuantity;
         oneInventory.daysToShip = oneProd.daysToShip;
 
-        resultMap = dispatcher.runSync("getProductInventoryAndFacilitySummary", [productId : oneProd.productId, minimumStock : minimumStock, facilityId : oneProd.facilityId, checkTime : checkTime, statusId : statusId]);
+        resultMap =runService('getProductInventoryAndFacilitySummary', [productId : oneProd.productId, minimumStock : minimumStock, facilityId : oneProd.facilityId, checkTime : checkTime, statusId : statusId]);
         if (resultMap) {
             oneInventory.totalAvailableToPromise = resultMap.totalAvailableToPromise;
             oneInventory.totalQuantityOnHand = resultMap.totalQuantityOnHand;
diff --git a/applications/product/webapp/facility/WEB-INF/actions/inventory/FindFacilityPhysicalInventory.groovy b/applications/product/webapp/facility/WEB-INF/actions/inventory/FindFacilityPhysicalInventory.groovy
index 0f842d7..4491c87e0 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/inventory/FindFacilityPhysicalInventory.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/inventory/FindFacilityPhysicalInventory.groovy
@@ -38,8 +38,7 @@
 }
 
 if (conditions.size() > 2) {
-    ecl = EntityCondition.makeCondition(conditions, EntityOperator.AND);
-    physicalInventory = delegator.findList("ProductInventoryItem", ecl, null, ['productId'], null, false);
+    physicalInventory = from("ProductInventoryItem").where(conditions).orderBy("productId").queryList();
 
     // also need the overal product QOH and ATP for each product
     atpMap = [:];
@@ -53,7 +52,7 @@
 
     // for each product, call the inventory counting service
     productIds.each { productId ->
-        result = dispatcher.runSync("getInventoryAvailableByFacility", [facilityId : facilityId, productId : productId]);
+        result = runService('getInventoryAvailableByFacility', [facilityId : facilityId, productId : productId]);
         if (!ServiceUtil.isError(result)) {
             atpMap.put(productId, result.availableToPromiseTotal);
             qohMap.put(productId, result.quantityOnHandTotal);
diff --git a/applications/product/webapp/facility/WEB-INF/actions/inventory/InventoryAverageCosts.groovy b/applications/product/webapp/facility/WEB-INF/actions/inventory/InventoryAverageCosts.groovy
index 815a381..1a5a9d0 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/inventory/InventoryAverageCosts.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/inventory/InventoryAverageCosts.groovy
@@ -28,14 +28,14 @@
 facilityId = context.get("facilityId");
 
 EntityCondition whereConditions = EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, facilityId);
-inventoryItems = delegator.findList("InventoryItem", whereConditions, UtilMisc.toSet("productId"), UtilMisc.toList("productId"), null, false);
+inventoryItems = select("productId").from("InventoryItem").where("facilityId", facilityId).orderBy("productId").queryList();
 inventoryItemProducts = EntityUtil.getFieldListFromEntityList(inventoryItems, "productId", true);
 
 inventoryAverageCosts = FastList.newInstance();
 inventoryItemProducts.each { productId ->
-    productFacility = delegator.findOne("ProductFacility", UtilMisc.toMap("productId", productId, "facilityId", facilityId), false);
+    productFacility = from("ProductFacility").where("productId", productId, "facilityId", facilityId).queryOne();
     if (UtilValidate.isNotEmpty(productFacility)) {
-        result = dispatcher.runSync("calculateProductAverageCost", UtilMisc.toMap("productId", productId, "facilityId", facilityId, "userLogin", userLogin));
+        result = runService('calculateProductAverageCost', UtilMisc.toMap("productId": productId, "facilityId": facilityId, "userLogin": userLogin));
         totalQuantityOnHand = result.get("totalQuantityOnHand");
 
         totalInventoryCost = result.get("totalInventoryCost");
diff --git a/applications/product/webapp/facility/WEB-INF/actions/inventory/InventoryItemTotals.groovy b/applications/product/webapp/facility/WEB-INF/actions/inventory/InventoryItemTotals.groovy
index 4088b58..d676863 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/inventory/InventoryItemTotals.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/inventory/InventoryItemTotals.groovy
@@ -37,11 +37,11 @@
     conditionList = EntityCondition.makeCondition(conditions, EntityOperator.OR);
     try {
         beganTransaction = TransactionUtil.begin();
-        invItemListItr = delegator.find("InventoryItem", conditionList, null, null, ['productId'], null);
+        invItemListItr = from("InventoryItem").where(conditionList).orderBy("productId").queryIterator();
         while ((inventoryItem = invItemListItr.next()) != null) {
             productId = inventoryItem.productId;
-            product = delegator.findOne("Product", [productId : productId], false);
-            productFacility = delegator.findOne("ProductFacility", [productId : productId, facilityId : facilityId], false);
+            product = from("Product").where("productId", productId).queryOne();
+            productFacility = from("ProductFacility").where("productId", productId, "facilityId", facilityId).queryOne();
             if (productFacility) {
                 quantityOnHandTotal = inventoryItem.getDouble("quantityOnHandTotal");
                 availableToPromiseTotal = inventoryItem.getDouble("availableToPromiseTotal");
diff --git a/applications/product/webapp/facility/WEB-INF/actions/inventory/LookupInventoryItems.groovy b/applications/product/webapp/facility/WEB-INF/actions/inventory/LookupInventoryItems.groovy
index fda9691..203ce04 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/inventory/LookupInventoryItems.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/inventory/LookupInventoryItems.groovy
@@ -22,16 +22,16 @@
 productId = parameters.productId;
 
 if (orderId && productId) {
-    shipmentReceiptAndItems = delegator.findByAnd("ShipmentReceiptAndItem", [orderId : orderId, productId : productId], null, false);
+    shipmentReceiptAndItems = from("ShipmentReceiptAndItem").where("orderId", orderId, "productId", productId).queryList();
     context.inventoryItemsForPo = shipmentReceiptAndItems;
     context.orderId = orderId;
 }
 
 if (partyId && productId) {
-    orderRoles = delegator.findByAnd("OrderRole", [partyId : partyId, roleTypeId : "BILL_FROM_VENDOR"], null, false);
+    orderRoles = from("OrderRole").where("partyId", partyId, "roleTypeId", "BILL_FROM_VENDOR").queryList();
     inventoryItemsForSupplier = [];
     orderRoles.each { orderRole ->
-        shipmentReceiptAndItems = delegator.findByAnd("ShipmentReceiptAndItem", [productId : productId, orderId : orderRole.orderId], null, false);
+        shipmentReceiptAndItems = from("ShipmentReceiptAndItem").where("productId", productId, "orderId", orderRole.orderId).queryList();
         inventoryItemsForSupplier.addAll(shipmentReceiptAndItems);
     }
     context.inventoryItemsForSupplier = inventoryItemsForSupplier;
@@ -39,9 +39,9 @@
 }
 
 if (productId) {
-    inventoryItems = delegator.findByAnd("InventoryItem", [productId : productId], null, false);
+    inventoryItems = from("InventoryItem").where("productId", productId).queryList();
     context.inventoryItemsForProduct = inventoryItems;
     context.productId = productId;
-    product = delegator.findOne("Product", [productId : productId], false);
+    product = from("Product").where("productId", productId).queryOne();
     context.internalName = product.internalName;
 }
diff --git a/applications/product/webapp/facility/WEB-INF/actions/inventory/PhysicalInventoryVariance.groovy b/applications/product/webapp/facility/WEB-INF/actions/inventory/PhysicalInventoryVariance.groovy
index 897654e..8290fbe 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/inventory/PhysicalInventoryVariance.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/inventory/PhysicalInventoryVariance.groovy
@@ -21,7 +21,7 @@
 
 // get physicalInventoryAndVarianceDatas if this is a NON_SERIAL_INV_ITEM
 if (inventoryItem && "NON_SERIAL_INV_ITEM".equals(inventoryItem.inventoryItemTypeId)) {
-    physicalInventoryAndVariances = delegator.findList("PhysicalInventoryAndVariance", EntityCondition.makeCondition([inventoryItemId : inventoryItemId]), null, ['-physicalInventoryDate', '-physicalInventoryId'], null, false);
+    physicalInventoryAndVariances = from("PhysicalInventoryAndVariance").where("inventoryItemId", inventoryItemId).orderBy("-physicalInventoryDate", "-physicalInventoryId").queryList();
     physicalInventoryAndVarianceDatas = new ArrayList(physicalInventoryAndVariances.size());
     physicalInventoryAndVariances.each { physicalInventoryAndVariance ->
         physicalInventoryAndVarianceData = [:];
diff --git a/applications/product/webapp/facility/WEB-INF/actions/inventory/ReceiveInventory.groovy b/applications/product/webapp/facility/WEB-INF/actions/inventory/ReceiveInventory.groovy
index 1e01847..61683d6 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/inventory/ReceiveInventory.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/inventory/ReceiveInventory.groovy
@@ -34,14 +34,14 @@
 
 facility = null;
 if (facilityId) {
-    facility = delegator.findOne("Facility", [facilityId : facilityId], false);
+    facility = from("Facility").where("facilityId", facilityId).queryOne();
 }
 
 ownerAcctgPref = null;
 if (facility) {
     owner = facility.getRelatedOne("OwnerParty", false);
     if (owner) {
-        result = dispatcher.runSync("getPartyAccountingPreferences", [organizationPartyId : owner.partyId, userLogin : request.getAttribute("userLogin")]);
+        result = runService('getPartyAccountingPreferences', [organizationPartyId : owner.partyId, userLogin : request.getAttribute("userLogin")]);
         if (!ServiceUtil.isError(result) && result.partyAccountingPreference) {
             ownerAcctgPref = result.partyAccountingPreference;
         }
@@ -50,7 +50,7 @@
 
 purchaseOrder = null;
 if (purchaseOrderId) {
-    purchaseOrder = delegator.findOne("OrderHeader", [orderId : purchaseOrderId], false);
+    purchaseOrder = from("OrderHeader").where("orderId", purchaseOrderId).queryOne();
     if (purchaseOrder && !"PURCHASE_ORDER".equals(purchaseOrder.orderTypeId)) {
         purchaseOrder = null;
     }
@@ -58,13 +58,13 @@
 
 product = null;
 if (productId) {
-    product = delegator.findOne("Product", [productId : productId], false);
-    context.supplierPartyIds = EntityUtil.getFieldListFromEntityList(EntityUtil.filterByDate(delegator.findList("SupplierProduct", EntityCondition.makeCondition([productId : productId]), null, ["partyId"], null, false), nowTimestamp, "availableFromDate", "availableThruDate", true), "partyId", true);
+    product = from("Product").where("productId", productId).queryOne();
+    context.supplierPartyIds = EntityUtil.getFieldListFromEntityList(from("SupplierProduct").where("productId", productId).orderBy("partyId").filterByDate(nowTimestamp, "availableFromDate", "availableThruDate").queryList(), "partyId", true);
 }
 
 shipments = null;
 if (purchaseOrder && !shipmentId) {
-    orderShipments = delegator.findList("OrderShipment", EntityCondition.makeCondition([orderId : purchaseOrderId]), null, null, null, false);
+    orderShipments = from("OrderShipment").where("orderId", purchaseOrderId).queryList();
     if (orderShipments) {
         shipments = [] as TreeSet;
         orderShipments.each { orderShipment ->
@@ -77,7 +77,7 @@
         }
     }
     // This is here for backward compatibility: ItemIssuances are no more created for purchase shipments.
-    issuances = delegator.findList("ItemIssuance", EntityCondition.makeCondition([orderId : purchaseOrderId]), null, null, null, false);
+    issuances = from("ItemIssuance").where("orderId", purchaseOrderId).queryList();
     if (issuances) {
         shipments = [] as TreeSet;
         issuances.each { issuance ->
@@ -93,7 +93,7 @@
 
 shipment = null;
 if (shipmentId && !shipmentId.equals("_NA_")) {
-    shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+    shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
 }
 
 shippedQuantities = [:];
@@ -141,7 +141,7 @@
         if (!orderCurrencyUomId.equals(ownerCurrencyUomId)) {
             purchaseOrderItems.each { item ->
             orderCurrencyUnitPriceMap.(item.orderItemSeqId) = item.unitPrice;
-                serviceResults = dispatcher.runSync("convertUom",
+                serviceResults = runService('convertUom',
                         [uomId : orderCurrencyUomId, uomIdTo : ownerCurrencyUomId, originalValue : item.unitPrice]);
                 if (ServiceUtil.isError(serviceResults)) {
                     request.setAttribute("_ERROR_MESSAGE_", ServiceUtil.getErrorMessage(serviceResults));
@@ -188,10 +188,7 @@
         }
         receivedQuantities.put(thisItem.orderItemSeqId, new Double(totalReceived));
         //----------------------
-        salesOrderItemAssocs = delegator.findList("OrderItemAssoc", EntityCondition.makeCondition([orderItemAssocTypeId : 'PURCHASE_ORDER',
-                                                                     toOrderId : thisItem.orderId,
-                                                                     toOrderItemSeqId : thisItem.orderItemSeqId]),
-                                                                     null, null, null, false);
+        salesOrderItemAssocs = from("OrderItemAssoc").where(orderItemAssocTypeId : 'PURCHASE_ORDER', toOrderId : thisItem.orderId, toOrderItemSeqId : thisItem.orderItemSeqId).queryList();
         if (salesOrderItemAssocs) {
             salesOrderItem = EntityUtil.getFirst(salesOrderItemAssocs);
             salesOrderItems.put(thisItem.orderItemSeqId, salesOrderItem);
@@ -201,7 +198,7 @@
 
 receivedItems = null;
 if (purchaseOrder) {
-    receivedItems = delegator.findList("ShipmentReceiptAndItem", EntityCondition.makeCondition([orderId : purchaseOrderId, facilityId : facilityId]), null, null, null, false);
+    receivedItems = from("ShipmentReceiptAndItem").where("orderId", purchaseOrderId, "facilityId", facilityId).queryList();
     context.receivedItems = receivedItems;
 }
 
@@ -212,13 +209,13 @@
 }
 
 // reject reasons
-rejectReasons = delegator.findList("RejectionReason", null, null, null, null, false);
+rejectReasons = from("RejectionReason").queryList();
 
 // inv item types
-inventoryItemTypes = delegator.findList("InventoryItemType", null, null, null, null, false);
+inventoryItemTypes = from("InventoryItemType").queryList();
 
 // facilities
-facilities = delegator.findList("Facility", null, null, null, null, false);
+facilities = from("Facility").queryList();
 
 // default per unit cost for both shipment or individual product
 standardCosts = [:];
@@ -229,7 +226,7 @@
         purchaseOrderItems.each { orderItem ->
             productId = orderItem.productId;
             if (productId) {
-                result = dispatcher.runSync("getProductCost", [productId : productId, currencyUomId : ownerAcctgPref.baseCurrencyUomId,
+                result = runService('getProductCost', [productId : productId, currencyUomId : ownerAcctgPref.baseCurrencyUomId,
                                                                costComponentTypePrefix : 'EST_STD', userLogin : request.getAttribute("userLogin")]);
                 if (!ServiceUtil.isError(result)) {
                     standardCosts.put(productId, result.productCost);
@@ -240,7 +237,7 @@
 
     // get the unit cost of a single product
     if (productId) {
-        result = dispatcher.runSync("getProductCost", [productId : productId, currencyUomId : ownerAcctgPref.baseCurrencyUomId,
+        result = runService('getProductCost', [productId : productId, currencyUomId : ownerAcctgPref.baseCurrencyUomId,
                                                        costComponentTypePrefix : 'EST_STD', userLogin : request.getAttribute("userLogin")]);
         if (!ServiceUtil.isError(result)) {
             standardCosts.put(productId, result.productCost);
diff --git a/applications/product/webapp/facility/WEB-INF/actions/inventory/TransferInventoryItem.groovy b/applications/product/webapp/facility/WEB-INF/actions/inventory/TransferInventoryItem.groovy
index ec870d8..4a4e5d1 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/inventory/TransferInventoryItem.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/inventory/TransferInventoryItem.groovy
@@ -29,7 +29,7 @@
 inventoryTransfer = null;
 
 if (inventoryTransferId) {
-    inventoryTransfer = delegator.findOne("InventoryTransfer", [inventoryTransferId : inventoryTransferId], false);
+    inventoryTransfer = from("InventoryTransfer").where("inventoryTransferId", inventoryTransferId).queryOne();
     if (inventoryTransfer) {
         context.inventoryTransfer = inventoryTransfer;
         if (!facilityId) {
@@ -42,18 +42,18 @@
     }
 }
 
-facility = delegator.findOne("Facility", [facilityId : facilityId], false);
+facility = from("Facility").where("facilityId", facilityId).queryOne();
 context.facilityId = facilityId;
 context.facility = facility;
 context.inventoryItemId = inventoryItemId;
 
 if (facilityId) {
-    facility = delegator.findOne("Facility", [facilityId : facilityId], false);
+    facility = from("Facility").where("facilityId", facilityId).queryOne();
 }
 
 String illegalInventoryItem = null;
 if (inventoryItemId) {
-    inventoryItem = delegator.findOne("InventoryItem", [inventoryItemId : inventoryItemId], false);
+    inventoryItem = from("InventoryItem").where("inventoryItemId", inventoryItemId).queryOne();
     if (facilityId && inventoryItem && inventoryItem.facilityId && !inventoryItem.facilityId.equals(facilityId)) {
         illegalInventoryItem = "Inventory item not found for this facility.";
         inventoryItem = null;
@@ -75,15 +75,15 @@
 }
 
 // facilities
-context.facilities = delegator.findList("Facility", null, null, null, null, false);
+context.facilities = from("Facility").queryList();
 
 // status items
 if (inventoryTransfer && inventoryTransfer.statusId) {
-    statusChange = delegator.findList("StatusValidChange", EntityCondition.makeCondition([statusId : inventoryTransfer.statusId]), null, null, null, false);
+    statusChange = from("StatusValidChange").where("statusId", inventoryTransfer.statusId).queryList();
     if (statusChange) {
         statusItems = [] as ArrayList;
         statusChange.each { curStatusChange ->
-            curStatusItem = delegator.findOne("StatusItem", [statusId : curStatusChange.statusIdTo], false);
+            curStatusItem = from("StatusItem").where("statusId", curStatusChange.statusIdTo).queryOne();
             if (curStatusItem) {
                 statusItems.add(curStatusItem);
             }
@@ -92,7 +92,7 @@
         context.statusItems = statusItems;
     }
 } else {
-    statusItems = delegator.findList("StatusItem", EntityCondition.makeCondition([statusTypeId : 'INVENTORY_XFER_STTS']), null, ['sequenceId'], null, false);
+    statusItems = from("StatusItem").where("statusTypeId", "INVENTORY_XFER_STTS").orderBy("sequenceId").queryList();
     if (statusItems) {
         context.statusItems = statusItems;
     }
diff --git a/applications/product/webapp/facility/WEB-INF/actions/returns/ReceiveReturn.groovy b/applications/product/webapp/facility/WEB-INF/actions/returns/ReceiveReturn.groovy
index 5b31d60..046d110 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/returns/ReceiveReturn.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/returns/ReceiveReturn.groovy
@@ -27,13 +27,13 @@
 
 facility = null;
 if (facilityId) {
-    facility = delegator.findOne("Facility", [facilityId : facilityId], false);
+    facility = from("Facility").where("facilityId", facilityId).queryOne();
 }
 
 returnHeader = null;
 returnItems = null;
 if (returnId) {
-    returnHeader = delegator.findOne("ReturnHeader", [returnId : returnId], false);
+    returnHeader = from("ReturnHeader").where("returnId", returnId).queryOne();
     if (returnHeader) {
         if ("RETURN_ACCEPTED".equals(returnHeader.statusId)) {
             returnItems = returnHeader.getRelated("ReturnItem", null, null, false);
@@ -71,14 +71,14 @@
 }
 
 if (returnHeader) {
-    context.receivedItems = delegator.findList("ShipmentReceipt", EntityCondition.makeCondition("returnId", returnId), null, null, null, false);
+    context.receivedItems = from("ShipmentReceipt").where("returnId", returnId).queryList();
 }
 
 // facilities
-facilities = delegator.findList("Facility", null, null, null, null, false);
+facilities = from("Facility").queryList();
 
 //all possible inventory item types
-inventoryItemTypes = delegator.findList("InventoryItemType", null, null, ['description'], null, true);
+inventoryItemTypes = from("InventoryItemType").orderBy("description").cache(true).queryList();
 
 context.facilityId = facilityId;
 context.facility = facility;
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/AddItemsFromInventory.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/AddItemsFromInventory.groovy
index ed19039..676f90d 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/AddItemsFromInventory.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/AddItemsFromInventory.groovy
@@ -23,7 +23,7 @@
 
 shipmentId = parameters.shipmentId;
 items = [];
-shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
 partyId = shipment.partyIdTo;
 shipmentItems = shipment.getRelated("ShipmentItem", null, null, false);
 shipmentItems.each { shipmentItem ->
@@ -31,7 +31,7 @@
     internalName = shipmentItem.getRelated("Product", null, null, false).internalName;
     EntityCondition cond = EntityCondition.makeCondition([EntityCondition.makeCondition("returnId", shipment.primaryReturnId),
                                    EntityCondition.makeCondition("productId", productId)], EntityOperator.AND);
-    returnItem = EntityUtil.getFirst(delegator.findList("ReturnItem", cond, null, null, null, true));
+    returnItem = from("ReturnItem").where("returnId", shipment.primaryReturnId, "productId", productId).cache(true).queryFirst();
     returnQuantity = Double.valueOf(returnItem.returnQuantity);
 
     shipmentItemQty = Double.valueOf(shipmentItem.quantity);
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/AddItemsFromOrder.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/AddItemsFromOrder.groovy
index 0e85df4..d9967f4 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/AddItemsFromOrder.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/AddItemsFromOrder.groovy
@@ -26,7 +26,7 @@
 shipGroupSeqId = request.getParameter("shipGroupSeqId");
 selectFromShipmentPlan = request.getParameter("selectFromShipmentPlan");
 
-shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
 
 if (shipment) {
     context.originFacility = shipment.getRelatedOne("OriginFacility", false);
@@ -41,7 +41,7 @@
 }
 
 if (orderId && shipment) {
-    orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+    orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
     context.orderHeader = orderHeader;
 
     if (orderHeader) {
@@ -53,7 +53,7 @@
 
         orderItemShipGroup = null;
         if (shipGroupSeqId) {
-            orderItemShipGroup = delegator.findOne("OrderItemShipGroup", [orderId : orderId, shipGroupSeqId : shipGroupSeqId], false);
+            orderItemShipGroup = from("OrderItemShipGroup").where("orderId", orderId, "shipGroupSeqId", shipGroupSeqId).queryOne();
             context.orderItemShipGroup = orderItemShipGroup;
         }
 
@@ -114,7 +114,7 @@
     }
 }
 if (shipment && selectFromShipmentPlan) {
-    shipmentPlans = delegator.findList("OrderShipment", EntityCondition.makeCondition([shipmentId : shipment.shipmentId]), null, ['orderId', 'orderItemSeqId'], null, false);
+    shipmentPlans = from("OrderShipment").where("shipmentId", shipment.shipmentId).orderBy("orderId", "orderItemSeqId").queryList();
     orderItemDatas = [] as LinkedList;
 
     context.isSalesOrder = true;
@@ -124,7 +124,7 @@
 
         orderItemShipGroup = null;
         if (shipGroupSeqId) {
-            orderItemShipGroup = delegator.findOne("OrderItemShipGroup", [orderId : orderItem.orderId, shipGroupSeqId : shipGroupSeqId], false);
+            orderItemShipGroup = from("OrderItemShipGroup").where("orderId", orderItem.orderId, "shipGroupSeqId", shipGroupSeqId).queryOne();
             context.orderItemShipGroup = orderItemShipGroup;
         }
 
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 985fb0c..a6e5372 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipment.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipment.groovy
@@ -21,7 +21,7 @@
 import org.ofbiz.widget.html.HtmlFormWrapper
 
 shipmentId = parameters.shipmentId;
-shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
 
 // orderHeader is needed here to determine type of order and hence types of shipment status
 if (!shipment) {
@@ -29,7 +29,7 @@
 } else {
     primaryOrderId = shipment.primaryOrderId;
 }
-orderHeader = delegator.findOne("OrderHeader", [orderId : primaryOrderId], false);
+orderHeader = from("OrderHeader").where(orderId : primaryOrderId).queryOne();
 
 // the kind of StatusItem to use is based on the type of order
 statusItemTypeId = "SHIPMENT_STATUS";
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentItems.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentItems.groovy
index 39044ee..a65c41e 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentItems.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentItems.groovy
@@ -27,7 +27,7 @@
 
 shipment = null;
 if (shipmentId) {
-    shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+    shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
 }
 
 if (shipment) {
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentPackages.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentPackages.groovy
index 0b3f126..7ec2c7a 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentPackages.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentPackages.groovy
@@ -26,7 +26,7 @@
 
 shipment = null;
 if (shipmentId) {
-    shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+    shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
 }
 
 if (shipment) {
@@ -45,8 +45,8 @@
 
     shipmentItems = shipment.getRelated("ShipmentItem", null, ['shipmentItemSeqId'], false);
     shipmentRouteSegments = shipment.getRelated("ShipmentRouteSegment", null, ['shipmentRouteSegmentId'], false);
-    weightUoms = delegator.findList("Uom", EntityCondition.makeCondition([uomTypeId : 'WEIGHT_MEASURE']), null, ['description'], null, false);
-    boxTypes = delegator.findList("ShipmentBoxType", null, null, null, null, false);
+    weightUoms = from("Uom").where("uomTypeId", "WEIGHT_MEASURE").orderBy("description").queryList();
+    boxTypes = from("ShipmentBoxType").queryList();
 
     context.shipment = shipment;
     context.shipmentPackageDatas = shipmentPackageDatas;
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 ab3567a..d5288c6 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentPlan.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentPlan.groovy
@@ -31,7 +31,7 @@
 
 shipment = null;
 if (shipmentId) {
-    shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+    shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
 }
 
 
@@ -44,9 +44,9 @@
 // **************************************
 if (action && orderId) {
     if (shipGroupSeqId) {
-        orderItemShipGroupAssocs = delegator.findList("OrderItemShipGroupAssoc", EntityCondition.makeCondition([orderId : orderId, shipGroupSeqId : shipGroupSeqId]), null, null, null, false);
+        orderItemShipGroupAssocs = from("OrderItemShipGroupAssoc").where("orderId", orderId, "shipGroupSeqId", shipGroupSeqId).queryList();
     } else {
-        orderItemShipGroupAssocs = delegator.findList("OrderItemShipGroupAssoc", EntityCondition.makeCondition([orderId : orderId]), null, null, null, false);
+        orderItemShipGroupAssocs = from("OrderItemShipGroupAssoc").where("orderId", orderId).queryList();
     }
 }
 
@@ -59,7 +59,7 @@
 shipmentPlansIt = null;
 rows = [] as ArrayList;
 if (shipment) {
-    shipmentPlans = delegator.findList("OrderShipment", EntityCondition.makeCondition([shipmentId : shipment.shipmentId]), null, null, null, false);
+    shipmentPlans = from("OrderShipment").where("shipmentId", shipment.shipmentId).queryList();
 }
 if (shipmentPlans) {
     shipmentPlans.each { shipmentPlan ->
@@ -104,7 +104,7 @@
         // Total quantity planned not issued
         plannedQuantity = 0.0;
         qtyPlannedInShipment = [:];
-        plans = delegator.findList("OrderShipment", EntityCondition.makeCondition([orderId : orderItem.orderId, orderItemSeqId : orderItem.orderItemSeqId]), null, null, null, false);
+        plans = from("OrderShipment").where("orderId", orderItem.orderId, "orderItemSeqId", orderItem.orderItemSeqId).queryList();
         plans.each { plan ->
             if (plan.quantity) {
                 netPlanQty = plan.getDouble("quantity");
@@ -158,7 +158,7 @@
         }
         oneRow.weight = weight;
         if (product.weightUomId) {
-            weightUom = delegator.findOne("Uom", [uomId : product.weightUomId], false);
+            weightUom = from("Uom").where("uomId", product.weightUomId).queryOne();
             oneRow.weightUom = weightUom.abbreviation;
         }
         volume = 0.0;
@@ -173,9 +173,9 @@
         }
         oneRow.volume = volume;
         if (product.heightUomId && product.widthUomId && product.depthUomId) {
-            heightUom = delegator.findOne("Uom",[uomId : product.heightUomId], true);
-            widthUom = delegator.findOne("Uom", [uomId : product.widthUomId], true);
-            depthUom = delegator.findOne("Uom", [uomId : product.depthUomId], true);
+            heightUom = from("Uom").where("uomId", product.heightUomId).cache(true).queryOne();
+            widthUom = from("Uom").where("uomId", product.widthUomId).cache(true).queryOne();
+            depthUom = from("Uom").where("uomId", product.depthUomId).cache(true).queryOne();
             oneRow.volumeUom = heightUom.abbreviation + "x" + widthUom.abbreviation + "x" + depthUom.abbreviation;
         }
         totWeight += weight;
@@ -235,7 +235,7 @@
         } else {
             orderShipmentCondition = EntityCondition.makeCondition([orderId : orderItemShipGroupAssoc.orderId, orderItemSeqId : orderItemShipGroupAssoc.orderItemSeqId]);
         }
-        plans = delegator.findList("OrderShipment", orderShipmentCondition, null, null, null, false);
+        plans = from("OrderShipment").where(orderShipmentCondition).queryList();
         plans.each { plan ->
             if (plan.quantity) {
                 netPlanQty = plan.getDouble("quantity");
@@ -257,7 +257,7 @@
         oneRow.weight = weight;
 
         if (product.weightUomId) {
-            weightUom = delegator.findOne("Uom", [uomId : product.weightUomId], true);
+            weightUom = from("Uom").where("uomId", product.weightUomId).cache(true).queryOne();
             oneRow.weightUom = weightUom.abbreviation;
         }
         volume = 0.0;
@@ -270,9 +270,9 @@
 
         oneRow.volume = volume;
         if (product.heightUomId && product.widthUomId && product.depthUomId) {
-            heightUom = delegator.findOne("Uom", [uomId : product.heightUomId], true);
-            widthUom = delegator.findOne("Uom", [uomId : product.widthUomId], true);
-            depthUom = delegator.findOne("Uom", [uomId : product.depthUomId], true);
+            heightUom = from("Uom").where("uomId", product.heightUomId).cache(true).queryOne();
+            widthUom = from("Uom").where("uomId", product.widthUomId).cache(true).queryOne();
+            depthUom = from("Uom").where("uomId", product.depthUomId).cache(true).queryOne();
             oneRow.volumeUom = heightUom.abbreviation + "x" + widthUom.abbreviation + "x" + depthUom.abbreviation;
         }
         addRows.add(oneRow);
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentRouteSegments.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentRouteSegments.groovy
index abb8bdd..fb36871 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentRouteSegments.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentRouteSegments.groovy
@@ -27,7 +27,7 @@
 
 shipment = null;
 if (shipmentId) {
-    shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+    shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
 }
 
 if (shipment) {
@@ -51,21 +51,21 @@
             shipmentRouteSegmentData.currencyUom = shipmentRouteSegment.getRelatedOne("CurrencyUom", false);
             shipmentRouteSegmentData.billingWeightUom = shipmentRouteSegment.getRelatedOne("BillingWeightUom", false);
             if (shipmentRouteSegment.carrierServiceStatusId) {
-                shipmentRouteSegmentData.carrierServiceStatusValidChangeToDetails = delegator.findList("StatusValidChangeToDetail", EntityCondition.makeCondition([statusId : shipmentRouteSegment.carrierServiceStatusId]), null, ['sequenceId'], null, false);
+                shipmentRouteSegmentData.carrierServiceStatusValidChangeToDetails = from("StatusValidChangeToDetail").where("statusId", shipmentRouteSegment.carrierServiceStatusId).orderBy("sequenceId").queryList();
             } else {
-                shipmentRouteSegmentData.carrierServiceStatusValidChangeToDetails = delegator.findList("StatusValidChangeToDetail", EntityCondition.makeCondition([statusId : 'SHRSCS_NOT_STARTED']), null, ['sequenceId'], null, false);
+                shipmentRouteSegmentData.carrierServiceStatusValidChangeToDetails = from("StatusValidChangeToDetail").where("statusId", "SHRSCS_NOT_STARTED").orderBy("sequenceId").queryList();
             }
             shipmentRouteSegmentDatas.add(shipmentRouteSegmentData);
         }
     }
 
     shipmentPackages = shipment.getRelated("ShipmentPackage", null, ['shipmentPackageSeqId'], false);
-    facilities = delegator.findList("Facility", null, null, ['facilityName'], null, false);
-    shipmentMethodTypes = delegator.findList("ShipmentMethodType", null, null, ['description'], null, false);
-    weightUoms = delegator.findList("Uom", EntityCondition.makeCondition([uomTypeId : 'WEIGHT_MEASURE']), null, null, null, false);
-    currencyUoms = delegator.findList("Uom", EntityCondition.makeCondition([uomTypeId : 'CURRENCY_MEASURE']), null, null, null, false);
+    facilities = from("Facility").orderBy("facilityName").queryList();
+    shipmentMethodTypes = from("ShipmentMethodType").orderBy("description").queryList();
+    weightUoms = from("Uom").where("uomTypeId", "WEIGHT_MEASURE").queryList();
+    currencyUoms = from("Uom").where("uomTypeId", "CURRENCY_MEASURE").queryList();
 
-    carrierPartyRoles = delegator.findList("PartyRole", EntityCondition.makeCondition([roleTypeId : 'CARRIER']), null, null, null, false);
+    carrierPartyRoles = from("PartyRole").where("roleTypeId", "CARRIER").queryList();
     carrierPartyDatas = [] as LinkedList;
     carrierPartyRoles.each { carrierPartyRole ->
         party = carrierPartyRole.getRelatedOne("Party", false);
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/FindShipment.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/FindShipment.groovy
index 93555c4..a2e8f02 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/FindShipment.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/FindShipment.groovy
@@ -59,21 +59,21 @@
     paramListBuffer.append("&shipmentTypeId=");
     paramListBuffer.append(shipmentTypeId);
     findShipmentExprs.add(EntityCondition.makeCondition("shipmentTypeId", EntityOperator.EQUALS, shipmentTypeId));
-    currentShipmentType = delegator.findOne("ShipmentType", [shipmentTypeId : shipmentTypeId], true);
+    currentShipmentType = from("ShipmentType").where("shipmentTypeId", shipmentTypeId).cache(true).queryOne();
     context.currentShipmentType = currentShipmentType;
 }
 if (originFacilityId) {
     paramListBuffer.append("&originFacilityId=");
     paramListBuffer.append(originFacilityId);
     findShipmentExprs.add(EntityCondition.makeCondition("originFacilityId", EntityOperator.EQUALS, originFacilityId));
-    currentOriginFacility = delegator.findOne("Facility", [facilityId : originFacilityId], true);
+    currentOriginFacility = from("Facility").where("facilityId", originFacilityId).cache(true).queryOne();
     context.currentOriginFacility = currentOriginFacility;
 }
 if (destinationFacilityId) {
     paramListBuffer.append("&destinationFacilityId=");
     paramListBuffer.append(destinationFacilityId);
     findShipmentExprs.add(EntityCondition.makeCondition("destinationFacilityId", EntityOperator.EQUALS, destinationFacilityId));
-    currentDestinationFacility = delegator.findOne("Facility", [facilityId : destinationFacilityId], true);
+    currentDestinationFacility = from("Facility").where("facilityId", destinationFacilityId).cache(true).queryOne();
     context.currentDestinationFacility = currentDestinationFacility;
 }
 if (statusId) {
@@ -82,7 +82,7 @@
     if (!orderReturnValue) {
         findShipmentExprs.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, statusId));
     }
-    currentStatus = delegator.findOne("StatusItem", [statusId : statusId], true);
+    currentStatus = from("StatusItem").where("statusId", statusId).cache(true).queryOne();
     context.currentStatus = currentStatus;
 }
 if (minDate && minDate.length() > 8) {
@@ -117,12 +117,10 @@
 if ("Y".equals(lookupFlag)) {
     context.paramList = paramListBuffer.toString();
 
-    findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
     mainCond = null;
     if (findShipmentExprs.size() > 0) {
         mainCond = EntityCondition.makeCondition(findShipmentExprs, EntityOperator.AND);
     }
-    orderBy = ['-estimatedShipDate'];
 
     beganTransaction = false;
     try {
@@ -131,11 +129,10 @@
         // get the indexes for the partial list
         lowIndex = viewIndex * viewSize + 1;
         highIndex = (viewIndex + 1) * viewSize;
-        findOpts.setMaxRows(highIndex);
         
         if (!orderReturnValue) {
             // using list iterator
-            orli = delegator.find("Shipment", mainCond, null, null, orderBy, findOpts);
+            orli = from("Shipment").where(mainCond).orderBy("-estimatedShipDate").cursorScrollInsensitive().distinct().maxRows(highIndex).queryIterator();
     
             shipmentListSize = orli.getResultsSizeAfterPartialList();
             if (highIndex > shipmentListSize) {
@@ -172,7 +169,7 @@
             OrderReturnViewEntity.addAlias("RH", "entryDate");
             OrderReturnViewEntity.addAlias("RH", "returnStatusId", "statusId", null, null, null, null);
             
-            orderReturnIt = delegator.findListIteratorByCondition(OrderReturnViewEntity, returnCond, null, null, null, null);
+            orderReturnIt = from(OrderReturnViewEntity).where(returnCond).queryList();
             shipmentListSize = orderReturnIt.getResultsSizeAfterPartialList();
             
             if (highIndex > shipmentListSize) {
@@ -211,16 +208,16 @@
 
 // =============== Prepare the Option Data for the Find Form =================
 
-context.shipmentTypes = delegator.findList("ShipmentType", null, null, ['description'], null, false);
+context.shipmentTypes = from("ShipmentType").orderBy("description").queryList();
 
-context.facilities = delegator.findList("Facility", null, null, ['facilityName'], null, false);
+context.facilities = from("Facility").orderBy("facilityName").queryList();
 
 // since purchase and sales shipments have different status codes, we'll need to make two separate lists
-context.shipmentStatuses = delegator.findList("StatusItem", EntityCondition.makeCondition([statusTypeId : 'SHIPMENT_STATUS']), null, ['sequenceId'], null, false);
-context.purchaseShipmentStatuses = delegator.findList("StatusItem", EntityCondition.makeCondition([statusTypeId : 'PURCH_SHIP_STATUS']), null, ['sequenceId'], null, false);
+context.shipmentStatuses = from("StatusItem").where("statusTypeId", "SHIPMENT_STATUS").orderBy("sequenceId").queryList();
+context.purchaseShipmentStatuses = from("StatusItem").where("statusTypeId", "PURCH_SHIP_STATUS").orderBy("sequenceId").queryList();
 
 /// Get return status lists
-context.returnStatuses = delegator.findList("StatusItem", EntityCondition.makeCondition([statusTypeId : 'ORDER_RETURN_STTS']), null, ['sequenceId'], null, false);
+context.returnStatuses = from("StatusItem").where("statusTypeId", "ORDER_RETURN_STTS").orderBy("sequenceId").queryList();
 
 // create the fromDate for calendar
 fromCal = Calendar.getInstance();
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/PackOrder.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/PackOrder.groovy
index 09e14e0..1e8188e 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/PackOrder.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/PackOrder.groovy
@@ -26,7 +26,7 @@
 
 facilityId = parameters.facilityId;
 if (facilityId) {
-    facility = delegator.findOne("Facility", [facilityId : facilityId], false);
+    facility = from("Facility").where("facilityId", facilityId).queryOne();
     context.facilityId = facilityId;
     context.facility = facility;
 }
@@ -44,9 +44,9 @@
 invoiceIds = null;
 if (shipmentId) {
     // Get the primaryOrderId from the shipment
-    shipment = delegator.findOne("Shipment",  [shipmentId : shipmentId], false);
+    shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
     if (shipment && shipment.primaryOrderId) {
-        orderItemBillingList = delegator.findList("OrderItemBilling", EntityCondition.makeCondition([orderId : shipment.primaryOrderId]), null, ['invoiceId'], null, false);
+        orderItemBillingList = from("OrderItemBilling").where("orderId", shipment.primaryOrderId).orderBy("invoiceId").queryList();
         invoiceIds = EntityUtil.getFieldListFromEntityList(orderItemBillingList, "invoiceId", true);
         if (invoiceIds) {
             context.invoiceIds = invoiceIds;
@@ -95,7 +95,7 @@
     picklistBinId = packSession.getPicklistBinId();
 }
 if (picklistBinId) {
-    bin = delegator.findOne("PicklistBin", [picklistBinId : picklistBinId], false);
+    bin = from("PicklistBin").where("picklistBinId", picklistBinId).queryOne();
     if (bin) {
         orderId = bin.primaryOrderId;
         shipGroupSeqId = bin.primaryShipGroupSeqId;
@@ -115,7 +115,7 @@
 if (invoiceIds) {
     orderId = null;
 }
-shipment = EntityUtil.getFirst(delegator.findByAnd("Shipment", [primaryOrderId : orderId, statusId : "SHIPMENT_PICKED"], null, false));
+shipment = from("Shipment").where("primaryOrderId", orderId, "statusId", "SHIPMENT_PICKED").queryFirst();
 context.shipment = shipment;
 
 context.packingSession = packSession;
@@ -125,7 +125,7 @@
 
 // grab the order information
 if (orderId) {
-    orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+    orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
     if (orderHeader) {
         OrderReadHelper orh = new OrderReadHelper(orderHeader);
         context.orderId = orderId;
@@ -134,7 +134,7 @@
         orderItemShipGroup = orh.getOrderItemShipGroup(shipGroupSeqId);
         context.orderItemShipGroup = orderItemShipGroup;
         carrierPartyId = orderItemShipGroup.carrierPartyId;
-            carrierShipmentBoxTypes = delegator.findList("CarrierShipmentBoxType", EntityCondition.makeCondition([partyId : carrierPartyId]), null, null, null, false);
+            carrierShipmentBoxTypes = from("CarrierShipmentBoxType").where("partyId", carrierPartyId).queryList();
             if (carrierShipmentBoxTypes) {
             context.carrierShipmentBoxTypes = carrierShipmentBoxTypes;
             }
@@ -146,7 +146,7 @@
                     // Generate the shipment cost estimate for the ship group
                     productStoreId = orh.getProductStoreId();
                     shippableItemInfo = orh.getOrderItemAndShipGroupAssoc(shipGroupSeqId);
-                    shippableItems = delegator.findList("OrderItemAndShipGrpInvResAndItemSum", EntityCondition.makeCondition([orderId : orderId, shipGroupSeqId : shipGroupSeqId]), null, null, null, false);
+                    shippableItems = from("OrderItemAndShipGrpInvResAndItemSum").where("orderId", orderId, "shipGroupSeqId", shipGroupSeqId).queryList();
                     shippableTotal = new Double(orh.getShippableTotal(shipGroupSeqId).doubleValue());
                     shippableWeight = new Double(orh.getShippableWeight(shipGroupSeqId).doubleValue());
                     shippableQuantity = new Double(orh.getShippableQuantity(shipGroupSeqId).doubleValue());
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/PackingSlip.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/PackingSlip.groovy
index cc2a234..199c0aa 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/PackingSlip.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/PackingSlip.groovy
@@ -48,15 +48,16 @@
 }
 
 // Add in the total of all previously shipped items
-previousShipmentIter = delegator.find("Shipment",
-        EntityCondition.makeCondition(
-            UtilMisc.toList(
-                EntityCondition.makeCondition("primaryOrderId", EntityOperator.EQUALS, shipment.getString("primaryOrderId")),
-                EntityCondition.makeCondition("shipmentTypeId", EntityOperator.EQUALS, "SALES_SHIPMENT"),
-                EntityCondition.makeCondition("createdDate", EntityOperator.LESS_THAN_EQUAL_TO,
-                        ObjectType.simpleTypeConvert(shipment.getString("createdDate"), "Timestamp", null, null))
-            ),
-        EntityOperator.AND), null, null, null, null);
+previousShipmentIter = from("Shipment")
+                            .where(EntityCondition.makeCondition(
+                                            UtilMisc.toList(
+                                                EntityCondition.makeCondition("primaryOrderId", EntityOperator.EQUALS, shipment.getString("primaryOrderId")),
+                                                EntityCondition.makeCondition("shipmentTypeId", EntityOperator.EQUALS, "SALES_SHIPMENT"),
+                                                EntityCondition.makeCondition("createdDate", EntityOperator.LESS_THAN_EQUAL_TO,
+                                                    ObjectType.simpleTypeConvert(shipment.getString("createdDate"), "Timestamp", null, null))
+                                            ),
+                                        EntityOperator.AND))
+                            .queryIterator();
 
 while (previousShipmentItem = previousShipmentIter.next()) {
     if (!previousShipmentItem.shipmentId.equals(shipment.shipmentId)) {
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/PrintPickSheets.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/PrintPickSheets.groovy
index cdf3183..c7e8c00 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/PrintPickSheets.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/PrintPickSheets.groovy
@@ -59,13 +59,13 @@
                     orderMap.orderId = orderId;
                     orderMap.orderDate = orderHeader.orderDate;
                     billingOrderContactMechs = [];
-                    billingOrderContactMechs = delegator.findByAnd("OrderContactMech", [orderId : orderId, contactMechPurposeTypeId : "BILLING_LOCATION"], null, false);
+                    billingOrderContactMechs = from("OrderContactMech").where("orderId", orderId, "contactMechPurposeTypeId", "BILLING_LOCATION").queryList();
                     if (billingOrderContactMechs.size() > 0) {
                         billingContactMechId = EntityUtil.getFirst(billingOrderContactMechs).contactMechId;
-                        billingAddress = delegator.findOne("PostalAddress", [contactMechId : billingContactMechId], false);
+                        billingAddress = from("PostalAddress").where("contactMechId", billingContactMechId).queryOne();
                     }
-                    shippingContactMechId = EntityUtil.getFirst(delegator.findByAnd("OrderContactMech", [orderId : orderId, contactMechPurposeTypeId : "SHIPPING_LOCATION"], null, false)).contactMechId;
-                    shippingAddress = delegator.findOne("PostalAddress", [contactMechId : shippingContactMechId], false);
+                    shippingContactMechId = from("OrderContactMech").where("orderId", orderId, "contactMechPurposeTypeId", "SHIPPING_LOCATION").queryFirst().contactMechId;
+                    shippingAddress = from("PostalAddress").where("contactMechId", shippingContactMechId).queryOne();
                     orderItemShipGroups.each { orderItemShipGroup ->
                         if (orderItemShipGroup.orderId == orderId) {
                             orderMap.shipmentMethodType = EntityUtil.getFirst(orderItemShipGroup.getRelated("ShipmentMethodType", null, null, false)).description;
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/QuickShipOrder.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/QuickShipOrder.groovy
index 3502980..e265789 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/QuickShipOrder.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/QuickShipOrder.groovy
@@ -23,14 +23,14 @@
 
 facilityId = parameters.facilityId;
 if (facilityId) {
-    facility = delegator.findOne("Facility", [facilityId : facilityId], false);
+    facility = from("Facility").where("facilityId", facilityId).queryOne();
     context.facilityId = facilityId;
     context.facility = facility;
 }
 
 orderId = parameters.orderId
 if (orderId) {
-    orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+    orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
     if (orderHeader) {
         OrderReadHelper orh = new OrderReadHelper(orderHeader);
         context.orderId = orderId;
@@ -43,7 +43,7 @@
 
 shipmentId = parameters.shipmentId;
 if (shipmentId) {
-    shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+    shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
     if (shipment) {
         // nuke event message - throws off the flow
         request.setAttribute("_EVENT_MESSAGE_", null);
@@ -65,10 +65,10 @@
         context.shipment = shipment;
         context.shipmentId = shipmentId;
 
-        weightUoms = delegator.findList("Uom", EntityCondition.makeCondition(['uomTypeId' : 'WEIGHT_MEASURE']), null, ['description'], null, false);
+        weightUoms = from("Uom").where("uomTypeId", "WEIGHT_MEASURE").orderBy("description").queryList();
         defaultWeightUom = EntityUtilProperties.getPropertyValue("shipment.properties", "shipment.default.weight.uom", delegator);
         if (defaultWeightUom) {
-            defaultWeight = delegator.findOne("Uom", [uomId : defaultWeightUom], false);
+            defaultWeight = from("Uom").where("uomId", defaultWeightUom).queryOne();
             if (defaultWeight) {
                 weightUoms.add(0, defaultWeight);
             }
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/ReceiveInventoryAgainstPurchaseOrder.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/ReceiveInventoryAgainstPurchaseOrder.groovy
index c1d3671..1fd364e 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/ReceiveInventoryAgainstPurchaseOrder.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/ReceiveInventoryAgainstPurchaseOrder.groovy
@@ -43,7 +43,7 @@
     }
 }
 
-shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
 context.shipment = shipment;
 if (!shipment) {
     return;
@@ -72,7 +72,7 @@
     return;
 }
 
-orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
 context.orderHeader = orderHeader;
 if (!orderHeader) {
     return;
@@ -89,7 +89,7 @@
 if (facility) {
     owner = facility.getRelatedOne("OwnerParty", false);
     if (owner) {
-        result = dispatcher.runSync("getPartyAccountingPreferences", [organizationPartyId : owner.partyId, userLogin : request.getAttribute("userLogin")]);
+        result = runService('getPartyAccountingPreferences', [organizationPartyId : owner.partyId, userLogin : request.getAttribute("userLogin")]);
         if (!ServiceUtil.isError(result) && result.partyAccountingPreference) {
             ownerAcctgPref = result.partyAccountingPreference;
         }
@@ -99,7 +99,7 @@
     }
 }
 
-inventoryItemTypes = delegator.findList("InventoryItemType", null, null, null, null, false);
+inventoryItemTypes = from("InventoryItemType").queryList();
 context.inventoryItemTypes = inventoryItemTypes;
 
 // Populate the tracking map with shipment and order IDs
@@ -121,7 +121,7 @@
     product = orderItemAndShipGroupAssoc.getRelatedOne("Product", false);
 
     // Get the order item, since the orderItemAndShipGroupAssoc's quantity field is manipulated in some cases
-    orderItem = delegator.findOne("OrderItem", [orderId : orderId, orderItemSeqId : orderItemAndShipGroupAssoc.orderItemSeqId], false);
+    orderItem = from("OrderItem").where("orderId", orderId, "orderItemSeqId", orderItemAndShipGroupAssoc.orderItemSeqId).queryOne();
     orderItemData = [:];
 
     // Get the item's ordered quantity
@@ -137,7 +137,7 @@
 
     // Get the item quantity received from all shipments via the ShipmentReceipt entity
     totalReceived = 0.0;
-    receipts = delegator.findList("ShipmentReceipt", EntityCondition.makeCondition([orderId : orderId, orderItemSeqId : orderItem.orderItemSeqId]), null, null, null, false);
+    receipts = from("ShipmentReceipt").where("orderId", orderId, "orderItemSeqId", orderItem.orderItemSeqId).queryList();
     fulfilledReservations = [] as ArrayList;
     if (receipts) {
         receipts.each { rec ->
@@ -150,7 +150,7 @@
                 totalReceived += rejected.doubleValue();
             }
             // Get the reservations related to this receipt
-            oisgirs = delegator.findList("OrderItemShipGrpInvRes", EntityCondition.makeCondition([inventoryItemId : rec.inventoryItemId]), null, null, null, false);
+            oisgirs = from("OrderItemShipGrpInvRes").where("inventoryItemId", rec.inventoryItemId).queryList();
             if (oisgirs) {
                 fulfilledReservations.addAll(oisgirs);
             }
@@ -161,7 +161,7 @@
     // Update the unit cost with the converted value, if any
     if (baseCurrencyUomId && orderHeader.currencyUom) {
         if (product) {
-            result = dispatcher.runSync("convertUom", [uomId : orderHeader.currencyUom, uomIdTo : baseCurrencyUomId, originalValue : orderItem.unitPrice]);
+            result = runService('convertUom', [uomId : orderHeader.currencyUom, uomIdTo : baseCurrencyUomId, originalValue : orderItem.unitPrice]);
             if (!ServiceUtil.isError(result)) {
                 orderItem.unitPrice = result.convertedValue;
             }
@@ -172,7 +172,7 @@
     // TODO: limit to a facility? The shipment destination facility is not necessarily the same facility as the inventory
     conditions = [EntityCondition.makeCondition("productId", EntityOperator.EQUALS, product.productId),
                   EntityCondition.makeCondition("availableToPromiseTotal", EntityOperator.LESS_THAN, BigDecimal.ZERO)];
-    negativeInventoryItems = delegator.findList("InventoryItem",  EntityCondition.makeCondition(conditions, EntityOperator.AND), null, null, null, false);
+    negativeInventoryItems = from("InventoryItem").where(conditions).queryList();
     backOrderedQuantity = 0;
     negativeInventoryItems.each { negativeInventoryItem ->
         backOrderedQuantity += negativeInventoryItem.getDouble("availableToPromiseTotal").doubleValue();
@@ -201,7 +201,7 @@
 
     // If the productId as given isn't found in the order, try any goodIdentifications and use the first match
     if (!candidateOrderItems) {
-        goodIdentifications = delegator.findList("GoodIdentification", EntityCondition.makeCondition([idValue : productIdToReceive]), null, null, null, false);
+        goodIdentifications = from("GoodIdentification").where("idValue", productIdToReceive).queryList();
         if (goodIdentifications) {
             giit = goodIdentifications.iterator();
             while (giit.hasNext()) {
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/ReviewOrdersNotPickedOrPacked.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/ReviewOrdersNotPickedOrPacked.groovy
index 0b11929..0f03e7e 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/ReviewOrdersNotPickedOrPacked.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/ReviewOrdersNotPickedOrPacked.groovy
@@ -27,12 +27,11 @@
 condList.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "ORDER_APPROVED"));
 condList.add(EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER"));
 condList.add(EntityCondition.makeCondition("pickSheetPrintedDate", EntityOperator.NOT_EQUAL, null));
-cond = EntityCondition.makeCondition(condList, EntityOperator.AND);
-orderHeaders = delegator.findList("OrderHeader", cond, null, null, null, false);
+orderHeaders = from("OrderHeader").where(condList).queryList();
 orders = [];
 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'/'K:mm a");
-orderHeaders.each { orderHeader ->
-    itemIssuanceList = delegator.findByAnd("ItemIssuance", [orderId : orderHeader.orderId], null, false);
+orderHeaders.each { orderHeader ->k
+    itemIssuanceList = from("ItemIssuance").where("orderId", orderHeader.orderId).queryList();
     if (itemIssuanceList) {
         orders.add([orderId : orderHeader.orderId, pickSheetPrintedDate : dateFormat.format(orderHeader.pickSheetPrintedDate), isVerified : "Y"]);
     } else {
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/ShipmentManifest.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/ShipmentManifest.groovy
index dc90a54..e68fdd6 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/ShipmentManifest.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/ShipmentManifest.groovy
@@ -22,7 +22,7 @@
 import org.ofbiz.content.report.*
 
 shipmentId = request.getParameter("shipmentId");
-shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
 
 if (shipment) {
     shipmentPackageRouteSegs = shipment.getRelated("ShipmentPackageRouteSeg", null, ['shipmentRouteSegmentId', 'shipmentPackageSeqId'], false);
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/VerifyPick.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/VerifyPick.groovy
index 1718adb..51edf40 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/VerifyPick.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/VerifyPick.groovy
@@ -39,7 +39,7 @@
 
 if (shipmentId) {
     context.orderId = null;
-    shipment = delegator.findOne("Shipment",  [shipmentId : shipmentId], false);
+    shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
     if (shipment) {
         shipmentItemBillingList = shipment.getRelated("ShipmentItemBilling", null, null, false);
         invoiceIds = EntityUtil.getFieldListFromEntityList(shipmentItemBillingList, "invoiceId", true);
@@ -52,7 +52,7 @@
 
 facilityId = parameters.facilityId;
 if (facilityId) {
-    facility = delegator.findOne("Facility", [facilityId : facilityId], false);
+    facility = from("Facility").where("facilityId", facilityId).queryOne();
     context.facility = facility;
 }
 verifyPickSession.setFacilityId(facilityId);
@@ -69,7 +69,7 @@
 
 picklistBinId = parameters.picklistBinId;
 if (picklistBinId) {
-    picklistBin = delegator.findOne("PicklistBin", [picklistBinId : picklistBinId], false);
+    picklistBin = from("PicklistBin").where("picklistBinId", picklistBinId).queryOne();
     if (picklistBin) {
         orderId = picklistBin.primaryOrderId;
         shipGroupSeqId = picklistBin.primaryShipGroupSeqId;
@@ -78,7 +78,7 @@
 }
 
 if (orderId && !picklistBinId) {
-    picklistBin = EntityUtil.getFirst(delegator.findByAnd("PicklistBin", [primaryOrderId : orderId], null, false));
+    picklistBin = from("PicklistBin").where("primaryOrderId", orderId).queryFirst();
     if (picklistBin) {
         picklistBinId = picklistBin.picklistBinId;
         verifyPickSession.setPicklistBinId(picklistBinId);
@@ -91,7 +91,7 @@
 context.isOrderStatusApproved = false;
 
 if (orderId) {
-    orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+    orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
     if (orderHeader) {
         OrderReadHelper orh = new OrderReadHelper(orderHeader);
         context.orderId = orderId;
@@ -108,7 +108,7 @@
             if (shipGroupSeqId) {
                 productStoreId = orh.getProductStoreId();
                 context.productStoreId = productStoreId;
-                shipments = delegator.findByAnd("Shipment", [primaryOrderId : orderId, statusId : "SHIPMENT_PICKED"], null, false);
+                shipments = from("Shipment").where("primaryOrderId", orderId, "statusId", "SHIPMENT_PICKED").queryList();
                 if (shipments) {
                     request.setAttribute("_ERROR_MESSAGE_", UtilProperties.getMessage("OrderErrorUiLabels", "OrderErrorAllItemsOfOrderAreAlreadyVerified", [orderId : orderId], locale));
                 }
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/ViewShipment.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/ViewShipment.groovy
index 47df04e..8e94ef4 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/ViewShipment.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/ViewShipment.groovy
@@ -23,7 +23,7 @@
 if (!shipmentId) {
     shipmentId = request.getAttribute("shipmentId");
 }
-shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
+shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
 
 context.shipmentId = shipmentId;
 context.shipment = shipment;
@@ -50,8 +50,7 @@
     if (shipment) {
         if (shipment.primaryOrderId) {
             // allow if userLogin is associated with the primaryOrderId with the SUPPLIER_AGENT roleTypeId
-            orderRoleCheckMap = [orderId : shipment.primaryOrderId, partyId : userLogin.partyId, roleTypeId : 'SUPPLIER_AGENT'];
-            orderRole = delegator.findOne("OrderRole", orderRoleCheckMap, false);
+            orderRole = from("OrderRole").where("orderId", shipment.primaryOrderId, "partyId", userLogin.partyId, "roleTypeId", "SUPPLIER_AGENT").queryOne();
             if (orderRole) {
                 hasPermission = true;
             }
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/WeightPackage.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/WeightPackage.groovy
index be4fea0..8b8bea2 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/WeightPackage.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/WeightPackage.groovy
@@ -44,26 +44,26 @@
 orderId = parameters.orderId;
 shipGroupSeqId = parameters.shipGroupSeqId;
 
-shipment = EntityUtil.getFirst(delegator.findByAnd("Shipment", [primaryOrderId : orderId, statusId : "SHIPMENT_PICKED"], null, false));
+shipment = from("Shipment").where("primaryOrderId", orderId, "statusId", "SHIPMENT_PICKED").queryFirst();
 context.shipment = shipment;
 if (shipment) {
-    invoice = EntityUtil.getFirst(delegator.findByAnd("ShipmentItemBilling", [shipmentId : shipment.shipmentId], null, false));
+    invoice = from("ShipmentItemBilling").where("shipmentId", shipment.shipmentId).queryFirst();
     context.invoice = invoice;
 } else {
     context.invoice = null;
 }
 actualCost = null;
 if (shipment) {
-    shipmentRouteSegment = EntityUtil.getFirst(delegator.findByAnd("ShipmentRouteSegment", [shipmentId : shipment.shipmentId], null, false));
+    shipmentRouteSegment = from("ShipmentRouteSegment").where("shipmentId", shipment.shipmentId).queryFirst();
     actualCost = shipmentRouteSegment.actualCost;
     if (actualCost) {
-        context.shipmentPackages = delegator.findByAnd("ShipmentPackage", [shipmentId : shipment.shipmentId], null, false);
+        context.shipmentPackages = from("ShipmentPackage").where("shipmentId", shipment.shipmentId).queryList();
     }
 }
 
 facilityId = parameters.facilityId;
 if (facilityId) {
-    facility = delegator.findOne("Facility", [facilityId : facilityId], false);
+    facility = from("Facility").where("facilityId", facilityId).queryOne();
     context.facility = facility;
 }
 
@@ -77,7 +77,7 @@
 
 picklistBinId = parameters.picklistBinId;
 if (picklistBinId) {
-    picklistBin = delegator.findOne("PicklistBin", [picklistBinId : picklistBinId], false);
+    picklistBin = from("PicklistBin").where("picklistBinId", picklistBinId).queryOne();
     if (picklistBin) {
         orderId = picklistBin.primaryOrderId;
         shipGroupSeqId = picklistBin.primaryShipGroupSeqId;
@@ -96,9 +96,9 @@
 context.shipmentId = shipmentId;
 if (shipmentId) {
     // Get the primaryOrderId from the shipment
-    shipment = delegator.findOne("Shipment",  [shipmentId : shipmentId], false);
+    shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
     if (shipment && shipment.primaryOrderId) {
-        orderItemBillingList = delegator.findList("OrderItemBilling", EntityCondition.makeCondition([orderId : shipment.primaryOrderId]), null, ['invoiceId'], null, false);
+        orderItemBillingList = from("OrderItemBilling").where("orderId", shipment.primaryOrderId).orderBy("invoiceId").queryList();
         invoiceIds = EntityUtil.getFieldListFromEntityList(orderItemBillingList, "invoiceId", true);
         if (invoiceIds) {
             context.invoiceIds = invoiceIds;
@@ -108,7 +108,7 @@
     if (shipment.statusId && "SHIPMENT_PACKED" == shipment.statusId) {
         orderId = null;
     }
-    shipmentPackageRouteSegs = delegator.findByAnd("ShipmentPackageRouteSeg",  [shipmentId : shipmentId], null, false);
+    shipmentPackageRouteSegs = from("ShipmentPackageRouteSeg").where("shipmentId", shipmentId).queryList();
     shipmentPackageRouteSegList = [];
     shipmentPackageRouteSegs.each { shipmentPackageRouteSeg ->
         if (shipmentPackageRouteSeg.labelImage) {
@@ -127,7 +127,7 @@
 
 carrierPartyId = null;
 if (orderId) {
-    orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+    orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
     if (orderHeader) {
         OrderReadHelper orderReadHelper = new OrderReadHelper(orderHeader);
         GenericValue orderItemShipGroup = orderReadHelper.getOrderItemShipGroup(shipGroupSeqId);
@@ -137,7 +137,7 @@
             if (shipment) {
                 productStoreId = orderReadHelper.getProductStoreId();
                 shippableItemInfo = orderReadHelper.getOrderItemAndShipGroupAssoc(shipGroupSeqId);
-                shippableItems = delegator.findList("OrderItemAndShipGrpInvResAndItemSum", EntityCondition.makeCondition([orderId : orderId, shipGroupSeqId : shipGroupSeqId]), null, null, null, false);
+                shippableItems = from("OrderItemAndShipGrpInvResAndItemSum").where("orderId", orderId, "shipGroupSeqId", shipGroupSeqId).queryList();
                 shippableTotal = orderReadHelper.getShippableTotal(shipGroupSeqId);
                 shippableWeight = orderReadHelper.getShippableWeight(shipGroupSeqId);
                 shippableQuantity = orderReadHelper.getShippableQuantity(shipGroupSeqId);
@@ -173,10 +173,10 @@
 context.picklistBinId = picklistBinId;
 
 if (carrierPartyId) {
-    carrierShipmentBoxTypes =  delegator.findByAnd("CarrierShipmentBoxType", [partyId : carrierPartyId], null, false);
+    carrierShipmentBoxTypes = from("CarrierShipmentBoxType").where("partyId", carrierPartyId).queryList();
     shipmentBoxTypes = [];
     carrierShipmentBoxTypes.each { carrierShipmentBoxType ->
-        shipmentBoxTypes.add(delegator.findOne("ShipmentBoxType", [shipmentBoxTypeId : carrierShipmentBoxType.shipmentBoxTypeId], false));
+        shipmentBoxTypes.add(from("ShipmentBoxType").where("shipmentBoxTypeId", carrierShipmentBoxType.shipmentBoxTypeId).queryOne());
         context.shipmentBoxTypes = shipmentBoxTypes;
     }
 }
diff --git a/applications/product/webapp/facility/WEB-INF/controller.xml b/applications/product/webapp/facility/WEB-INF/controller.xml
index 4174cb6..5c4cf13 100644
--- a/applications/product/webapp/facility/WEB-INF/controller.xml
+++ b/applications/product/webapp/facility/WEB-INF/controller.xml
@@ -1378,7 +1378,7 @@
     <view-map name="PicklistOptions" type="screen" page="component://product/widget/facility/FacilityScreens.xml#PicklistOptions"/>
     <view-map name="PicklistManage" type="screen" page="component://product/widget/facility/FacilityScreens.xml#PicklistManage"/>
     <view-map name="PickMoveStock" type="screen" page="component://product/widget/facility/FacilityScreens.xml#PickMoveStock"/>
-    <view-map name="PickMoveStockSimple" type="screen" page="component://product/widget/facility/FacilityScreens.xml#PickMoveStockSimple"/>
+    <view-map name="PickMoveStockSimple" type="screenfop" page="component://product/widget/facility/FacilityScreens.xml#PickMoveStockSimple.fo" content-type="application/pdf" encoding="none"/>
     <view-map name="PicklistReport.pdf" type="screenfop" page="component://product/widget/facility/FacilityScreens.xml#PicklistReport.fo" content-type="application/pdf" encoding="none"/>
     <view-map name="PrintPickSheets.pdf" type="screenfop" page="component://product/widget/facility/FacilityScreens.xml#PrintPickSheets.fo" content-type="application/pdf" encoding="none"/>
     <view-map name="ReviewOrdersNotPickedOrPacked" type="screen" page="component://product/widget/facility/FacilityScreens.xml#ReviewOrdersNotPickedOrPacked"/>
diff --git a/applications/product/webapp/facility/facility/PickMoveStockSimple.fo.ftl b/applications/product/webapp/facility/facility/PickMoveStockSimple.fo.ftl
new file mode 100644
index 0000000..5fb1998
--- /dev/null
+++ b/applications/product/webapp/facility/facility/PickMoveStockSimple.fo.ftl
@@ -0,0 +1,151 @@
+<#assign rowCount = 0>
+<fo:table table-layout="fixed" border-spacing="3pt">
+  <fo:table-column column-width="0.8in"/>
+  <fo:table-column column-width="0.8in"/>
+  <fo:table-column column-width="1.2in"/>
+  <fo:table-column column-width="0.5in"/>
+  <fo:table-column column-width="0.5in"/>
+  <fo:table-column column-width="1.2in"/>
+  <fo:table-column column-width="0.5in"/>
+  <fo:table-column column-width="0.5in"/>
+  <fo:table-column column-width="1in"/>
+  <fo:table-column column-width="1in"/>
+  <fo:table-header>
+    <fo:table-row>
+      <fo:table-cell>
+        <fo:block font-weight="bold">${uiLabelMap.ProductProductId}</fo:block>
+      </fo:table-cell>
+      <fo:table-cell>
+        <fo:block font-weight="bold">${uiLabelMap.ProductProduct}</fo:block>
+      </fo:table-cell>
+      <fo:table-cell>
+        <fo:block font-weight="bold">${uiLabelMap.ProductFromLocation}</fo:block>
+      </fo:table-cell>
+      <fo:table-cell>
+        <fo:block font-weight="bold">${uiLabelMap.ProductQoh}</fo:block>
+      </fo:table-cell>
+      <fo:table-cell>
+        <fo:block font-weight="bold">${uiLabelMap.ProductAtp}</fo:block>
+      </fo:table-cell>
+      <fo:table-cell>
+        <fo:block font-weight="bold">${uiLabelMap.ProductToLocation}</fo:block>
+      </fo:table-cell>
+      <fo:table-cell>
+        <fo:block font-weight="bold">${uiLabelMap.ProductQoh}</fo:block>
+      </fo:table-cell>
+      <fo:table-cell>
+        <fo:block font-weight="bold">${uiLabelMap.ProductAtp}</fo:block>
+      </fo:table-cell>
+      <fo:table-cell>
+        <fo:block font-weight="bold">${uiLabelMap.ProductMinimumStock}</fo:block>
+      </fo:table-cell>
+      <fo:table-cell>
+        <fo:block font-weight="bold">${uiLabelMap.ProductMoveQuantity}</fo:block>
+      </fo:table-cell>
+    </fo:table-row>
+  </fo:table-header>
+  <fo:table-body>
+  <#if moveByOisgirInfoList?has_content || moveByPflInfoList?has_content>
+      <#assign alt_row = false>
+      <#list moveByOisgirInfoList! as moveByOisgirInfo>
+          <#assign product = moveByOisgirInfo.product>
+          <#assign facilityLocationFrom = moveByOisgirInfo.facilityLocationFrom>
+          <#assign facilityLocationTypeEnumFrom = (facilityLocationFrom.getRelatedOne("TypeEnumeration", true))!>
+          <#assign facilityLocationTo = moveByOisgirInfo.facilityLocationTo>
+          <#assign targetProductFacilityLocation = moveByOisgirInfo.targetProductFacilityLocation>
+          <#assign facilityLocationTypeEnumTo = (facilityLocationTo.getRelatedOne("TypeEnumeration", true))!>
+          <#assign totalQuantity = moveByOisgirInfo.totalQuantity>
+          <fo:table-row>
+          <#-- <tr id="moveInfoId_tableRow_${rowCount}" valign="middle"<#if alt_row> class="alternate-row"</#if>> -->
+              <fo:table-cell>
+                <fo:block>${product.productId}</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${product.internalName!}</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${facilityLocationFrom.areaId!}:${facilityLocationFrom.aisleId!}:${facilityLocationFrom.sectionId!}:${facilityLocationFrom.levelId!}:${facilityLocationFrom.positionId!}<#if facilityLocationTypeEnumFrom?has_content>(${facilityLocationTypeEnumFrom.description})</#if>[${facilityLocationFrom.locationSeqId}]</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${moveByOisgirInfo.quantityOnHandTotalFrom!}</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${moveByOisgirInfo.availableToPromiseTotalFrom!}</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${facilityLocationTo.areaId!}:${facilityLocationTo.aisleId!}:${facilityLocationTo.sectionId!}:${facilityLocationTo.levelId!}:${facilityLocationTo.positionId!}<#if facilityLocationTypeEnumTo?has_content>(${facilityLocationTypeEnumTo.description})</#if>[${facilityLocationTo.locationSeqId}]</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${moveByOisgirInfo.quantityOnHandTotalTo!}</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${moveByOisgirInfo.availableToPromiseTotalTo!}</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${targetProductFacilityLocation.minimumStock!}</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${targetProductFacilityLocation.moveQuantity!}</fo:block>
+              </fo:table-cell>
+          <#-- </tr> -->
+          </fo:table-row>
+          <#assign rowCount = rowCount + 1>
+          <#-- toggle the row color -->
+          <#assign alt_row = !alt_row>
+      </#list>
+      <#list moveByPflInfoList! as moveByPflInfo>
+          <#assign product = moveByPflInfo.product>
+          <#assign facilityLocationFrom = moveByPflInfo.facilityLocationFrom>
+          <#assign facilityLocationTypeEnumFrom = (facilityLocationFrom.getRelatedOne("TypeEnumeration", true))!>
+          <#assign facilityLocationTo = moveByPflInfo.facilityLocationTo>
+          <#assign targetProductFacilityLocation = moveByPflInfo.targetProductFacilityLocation>
+          <#assign facilityLocationTypeEnumTo = (facilityLocationTo.getRelatedOne("TypeEnumeration", true))!>
+          <#assign totalQuantity = moveByPflInfo.totalQuantity>
+          <#-- <tr id="moveInfoId_tableRow_${rowCount}" valign="middle"<#if alt_row> class="alternate-row"</#if>> -->
+          <fo:table-row>
+              <fo:table-cell>
+                <fo:block>${product.productId}</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${product.internalName!}</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${facilityLocationFrom.areaId!}:${facilityLocationFrom.aisleId!}:${facilityLocationFrom.sectionId!}:${facilityLocationFrom.levelId!}:${facilityLocationFrom.positionId!}<#if facilityLocationTypeEnumFrom?has_content>(${facilityLocationTypeEnumFrom.description})</#if>[${facilityLocationFrom.locationSeqId}]</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${moveByPflInfo.quantityOnHandTotalFrom!}</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${moveByPflInfo.availableToPromiseTotalFrom!}</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${facilityLocationTo.areaId!}:${facilityLocationTo.aisleId!}:${facilityLocationTo.sectionId!}:${facilityLocationTo.levelId!}:${facilityLocationTo.positionId!}<#if facilityLocationTypeEnumTo?has_content>(${facilityLocationTypeEnumTo.description})</#if>[${facilityLocationTo.locationSeqId}]</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${moveByPflInfo.quantityOnHandTotalTo!}</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${moveByPflInfo.availableToPromiseTotalTo!}</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${targetProductFacilityLocation.minimumStock!}</fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block>${targetProductFacilityLocation.moveQuantity!}</fo:block>
+              </fo:table-cell>
+          </fo:table-row>
+          <#-- </tr> -->
+          <#assign rowCount = rowCount + 1>
+      </#list>
+  </#if>
+  <#assign messageCount = 0>
+  <#list pflWarningMessageList! as pflWarningMessage>
+      <#assign messageCount = messageCount + 1>
+      <fo:table-row>
+        <fo:table-cell>
+          <fo:block>${messageCount}:${pflWarningMessage}.</fo:block>
+        </fo:table-cell>
+      </fo:table-row>
+  </#list>
+  </fo:table-body>
+</fo:table>
\ No newline at end of file
diff --git a/applications/product/webapp/facility/shipment/PackOrder.ftl b/applications/product/webapp/facility/shipment/PackOrder.ftl
index 45b5ba2..8193b89 100644
--- a/applications/product/webapp/facility/shipment/PackOrder.ftl
+++ b/applications/product/webapp/facility/shipment/PackOrder.ftl
@@ -150,7 +150,7 @@
         </div>
         <div class="screenlet-body">
               <#if orderItemShipGroup?has_content>
-                <#if (orderItemShipGroup.contacMechId)?has_content>
+                <#if (orderItemShipGroup.contactMechId)?has_content>
                   <#assign postalAddress = orderItemShipGroup.getRelatedOne("PostalAddress", false)>
                 </#if>
                 <#assign carrier = orderItemShipGroup.carrierPartyId?default("N/A")>
diff --git a/applications/product/widget/catalog/ImageManagementForms.xml b/applications/product/widget/catalog/ImageManagementForms.xml
index dd25045..b014116 100644
--- a/applications/product/widget/catalog/ImageManagementForms.xml
+++ b/applications/product/widget/catalog/ImageManagementForms.xml
@@ -53,7 +53,7 @@
             </hyperlink>
         </field>
         <field name="contentId"><display/></field>
-        <field name="dataResourceId"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><display/></field>
         <field name="fromDate"><display/></field>
         <field name="statusId" title="${uiLabelMap.CommonStatus}">
             <display-entity entity-name="StatusItem" key-field-name="statusId" description="${description}"/>
@@ -116,7 +116,7 @@
         </field>
         <field name="drDataResourceName" position="2" title="${uiLabelMap.ImageManagementImageName}"><display/></field>
         <field name="contentId" position="2"><display/></field>
-        <field name="dataResourceId" position="2"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" position="2"><display/></field>
         <field name="fromDate" position="2"><display/></field>
         <field name="viewButton" position="2" title="${uiLabelMap.CommonView}" widget-style="buttontext">
             <hyperlink target="${origContentDataResourceViews[0].drObjectInfo}" target-window="_blank" description="${uiLabelMap.CommonView}" also-hidden="false" target-type="content"/>
@@ -156,7 +156,7 @@
         <field name="drObjectInfo" position="2" title="${uiLabelMap.CommonImage}"><image style="cssImgLarge"/></field>
         <field name="drDataResourceName" position="2" title="${uiLabelMap.ImageManagementImageName}"><display/></field>
         <field name="contentId" position="2"><display/></field>
-        <field name="dataResourceId" position="2"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" position="2"><display/></field>
         <field name="fromDate" position="2"><display/></field>
         <field name="viewButton" position="2" title="${uiLabelMap.CommonView}" widget-style="buttontext">
             <hyperlink target="${origContentDataResourceViews[0].drObjectInfo}" target-window="_blank" description="${uiLabelMap.CommonView}" also-hidden="false" target-type="content"/>
@@ -196,7 +196,7 @@
         <field name="drObjectInfo" position="2" title="${uiLabelMap.CommonImage}"><image style="cssImgLarge"/></field>
         <field name="drDataResourceName" position="2" title="${uiLabelMap.ImageManagementImageName}"><display/></field>
         <field name="contentId" position="2"><display/></field>
-        <field name="dataResourceId" position="2"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" position="2"><display/></field>
         <field name="fromDate" position="2"><display/></field>
         <field name="statusId" position="2" title="${uiLabelMap.CommonStatus}">
             <display-entity entity-name="StatusItem" key-field-name="statusId" description="${description}"/>
@@ -250,7 +250,7 @@
         <field name="drObjectInfo" position="2" title="${uiLabelMap.CommonImage}"><image style="cssImgLarge"/></field>
         <field name="drDataResourceName" position="2" title="${uiLabelMap.ImageManagementImageName}"><display/></field>
         <field name="contentId" position="2"><display/></field>
-        <field name="dataResourceId" position="2"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" position="2"><display/></field>
         <field name="fromDate" position="2"><display/></field>
         <field name="thruDate" position="2"><display/></field>
         <field name="statusId" position="2" title="${uiLabelMap.CommonStatus}">
@@ -665,7 +665,7 @@
             <hyperlink also-hidden="false" target-type="plain" description="${drDataResourceName}" target="javascript:set_value('${contentId}')"/>
         </field>
         <field name="contentId"><display/></field>
-        <field name="dataResourceId"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><display/></field>
         <field name="fromDate"><display/></field>
         <field name="statusId" title="${uiLabelMap.CommonStatus}">
             <display-entity entity-name="StatusItem" key-field-name="statusId" description="${description}"/>
@@ -714,7 +714,7 @@
         <field name="drObjectInfo" title="${uiLabelMap.CommonImage}"><image style="cssImgLarge"/></field>
         <field name="drDataResourceName" title="${uiLabelMap.ImageManagementImageName}"><display/></field>
         <field name="contentId"><display/></field>
-        <field name="dataResourceId"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><display/></field>
         <field name="statusId" title="${uiLabelMap.CommonStatus}">
             <display-entity entity-name="StatusItem" key-field-name="statusId" description="${description}"/>
         </field>
@@ -819,7 +819,7 @@
             <hyperlink also-hidden="false" target-type="plain" description="${drDataResourceName}" target="javascript:set_value('${contentId}')"/>
         </field>
         <field name="contentId"><display/></field>
-        <field name="dataResourceId"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><display/></field>
         <field name="createdDate"><display/></field>
         <!--<field name="deleteButton" title="${uiLabelMap.CommonDelete}" widget-style="buttontext">
             <hyperlink target="deleteImageFrame" target-window="_blank" description="${uiLabelMap.CommonDelete}" also-hidden="false">
diff --git a/applications/product/widget/facility/FacilityScreens.xml b/applications/product/widget/facility/FacilityScreens.xml
index 51a2192..d9f9edc 100644
--- a/applications/product/widget/facility/FacilityScreens.xml
+++ b/applications/product/widget/facility/FacilityScreens.xml
@@ -1306,7 +1306,7 @@
             </widgets>
         </section>
     </screen>
-    <screen name="PickMoveStockSimple">
+    <screen name="PickMoveStockSimple.fo">
         <section>
             <actions>
                 <property-map resource="ProductUiLabels" map-name="uiLabelMap" global="true"/>
@@ -1333,7 +1333,7 @@
                 <decorator-screen name="SimpleDecorator" location="component://common/widget/CommonScreens.xml">
                     <decorator-section name="body">
                         <platform-specific>
-                            <html><html-template location="component://product/webapp/facility/facility/PickMoveStock.ftl"/></html>
+                            <xsl-fo><html-template location="component://product/webapp/facility/facility/PickMoveStockSimple.fo.ftl"/></xsl-fo>
                         </platform-specific>
                     </decorator-section>
                 </decorator-screen>
diff --git a/applications/workeffort/entitydef/entitymodel.xml b/applications/workeffort/entitydef/entitymodel.xml
index 11c450d..d8fd8e0 100644
--- a/applications/workeffort/entitydef/entitymodel.xml
+++ b/applications/workeffort/entitydef/entitymodel.xml
@@ -787,9 +787,6 @@
         <field name="secondsTotal" type="floating-point"></field>
         <field name="searchDate" type="date-time"></field>
         <prim-key field="workEffortSearchResultId"/>
-        <relation type="one" fk-name="WEFF_SCHRES_VST" rel-entity-name="Visit">
-            <key-map field-name="visitId"/>
-        </relation>
     </entity>
     <entity entity-name="WorkEffortSkillStandard"
             package-name="org.ofbiz.workeffort.workeffort"
diff --git a/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Days.groovy b/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Days.groovy
index 237b2b9..7770ac5 100644
--- a/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Days.groovy
+++ b/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Days.groovy
@@ -40,7 +40,7 @@
 if (context.entityExprList) {
     serviceCtx.entityExprList = entityExprList;
 }
-Map result = dispatcher.runSync("getWorkEffortEventsByPeriod", serviceCtx);
+Map result = runService('getWorkEffortEventsByPeriod', serviceCtx);
 context.put("periods", result.get("periods"));
 context.put("maxConcurrentEntries", result.get("maxConcurrentEntries"));
 context.put("start", start);
diff --git a/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Month.groovy b/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Month.groovy
index 64cd59d..98b6310 100644
--- a/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Month.groovy
+++ b/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Month.groovy
@@ -62,7 +62,7 @@
 if (context.entityExprList) {
     serviceCtx.entityExprList = entityExprList;
 }
-result = dispatcher.runSync("getWorkEffortEventsByPeriod", serviceCtx);
+result = runService('getWorkEffortEventsByPeriod', serviceCtx);
 context.put("periods",result.get("periods"));
 context.put("maxConcurrentEntries", result.get("maxConcurrentEntries"));
 context.put("start", start);
diff --git a/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Upcoming.groovy b/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Upcoming.groovy
index 60876f0..e1ff131 100644
--- a/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Upcoming.groovy
+++ b/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Upcoming.groovy
@@ -43,7 +43,7 @@
 Map serviceCtx = UtilMisc.toMap("userLogin", userLogin, "start", start, "numPeriods", 7, "periodType", Calendar.DATE);
 serviceCtx.putAll(UtilMisc.toMap("partyId", partyId, "facilityId", facilityId, "fixedAssetId", fixedAssetId, "workEffortTypeId", workEffortTypeId, "calendarType", calendarType, "locale", locale, "timeZone", timeZone));
 
-Map result = dispatcher.runSync("getWorkEffortEventsByPeriod",serviceCtx);
+Map result = runService('getWorkEffortEventsByPeriod',serviceCtx);
 context.put("days", result.get("periods"));
 context.put("start", start);
 context.put("eventsParam", eventsParam);
diff --git a/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Week.groovy b/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Week.groovy
index 61f7790..b0cbf2c 100644
--- a/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Week.groovy
+++ b/applications/workeffort/webapp/workeffort/WEB-INF/actions/calendar/Week.groovy
@@ -41,7 +41,7 @@
 if (context.entityExprList) {
     serviceCtx.entityExprList = entityExprList;
 }
-Map result = dispatcher.runSync("getWorkEffortEventsByPeriod",serviceCtx);
+Map result = runService('getWorkEffortEventsByPeriod',serviceCtx);
 context.put("periods",result.get("periods"));
 context.put("maxConcurrentEntries",result.get("maxConcurrentEntries"));
 context.put("start",start);
diff --git a/applications/workeffort/webapp/workeffort/WEB-INF/actions/content/WorkEffortContentWrapper.groovy b/applications/workeffort/webapp/workeffort/WEB-INF/actions/content/WorkEffortContentWrapper.groovy
index 1782664..ff39b10 100644
--- a/applications/workeffort/webapp/workeffort/WEB-INF/actions/content/WorkEffortContentWrapper.groovy
+++ b/applications/workeffort/webapp/workeffort/WEB-INF/actions/content/WorkEffortContentWrapper.groovy
@@ -24,7 +24,7 @@
 
  workEffort = context.get("workEffort");
  if (workEffort == null && workEffortId != null) {
-    workEffort = delegator.findOne("WorkEffort", UtilMisc.toMap("workEffortId", workEffortId), true);
+    workEffort = from("WorkEffort").where("workEffortId", workEffortId).cache(true).queryOne();
  }
 
  if (workEffort != null) {
diff --git a/applications/workeffort/webapp/workeffort/WEB-INF/actions/find/WorkEffortSearchOptions.groovy b/applications/workeffort/webapp/workeffort/WEB-INF/actions/find/WorkEffortSearchOptions.groovy
index 0b36cb2..803aadb 100644
--- a/applications/workeffort/webapp/workeffort/WEB-INF/actions/find/WorkEffortSearchOptions.groovy
+++ b/applications/workeffort/webapp/workeffort/WEB-INF/actions/find/WorkEffortSearchOptions.groovy
@@ -53,8 +53,8 @@
 
 searchConstraintStrings = WorkEffortSearchSession.searchGetConstraintStrings(false, session, delegator);
 searchSortOrderString = WorkEffortSearchSession.searchGetSortOrderString(false, request);
-workEffortAssocTypes=delegator.findList("WorkEffortAssocType", null, null, null, null, false);
-roleTypes=delegator.findList("RoleType", null, null, null, null, false);
+workEffortAssocTypes = from("WorkEffortAssocType").queryList();
+roleTypes = from("RoleType").queryList();
 
 context.put("searchOperator", searchOperator);
 context.put("searchConstraintStrings", searchConstraintStrings);
diff --git a/applications/workeffort/webapp/workeffort/WEB-INF/actions/request/RequestList.groovy b/applications/workeffort/webapp/workeffort/WEB-INF/actions/request/RequestList.groovy
index c6d6f84..8c9d6d4 100644
--- a/applications/workeffort/webapp/workeffort/WEB-INF/actions/request/RequestList.groovy
+++ b/applications/workeffort/webapp/workeffort/WEB-INF/actions/request/RequestList.groovy
@@ -19,7 +19,6 @@
 
 import org.ofbiz.base.util.UtilMisc;
 
-Map serviceCtx = UtilMisc.toMap("userLogin", userLogin);
-Map requests = dispatcher.runSync("getCustRequestsByRole", serviceCtx);
+Map requests = runService('getCustRequestsByRole', ["userLogin": userLogin]);
 
 context.put("custRequestAndRoles", requests.get("custRequestAndRoles"));
diff --git a/applications/workeffort/widget/CalendarScreens.xml b/applications/workeffort/widget/CalendarScreens.xml
index ad20730..d5a2d14 100644
--- a/applications/workeffort/widget/CalendarScreens.xml
+++ b/applications/workeffort/widget/CalendarScreens.xml
@@ -167,7 +167,7 @@
                                 <if-compare field="isCalOwner" operator="equals" value="true" type="Boolean" />
                             </and>
                             <if-empty field="workEffort" />
-                            <if-has-permission permission="WORKEFFORTMGR" action="ADMIN" />
+                            <if-has-permission permission="WORKEFFORTMGR" action="_ADMIN" />
                         </or>
                     </condition>
                     <actions>
diff --git a/framework/base/config/ESAPI.properties b/framework/base/config/ESAPI.properties
deleted file mode 100644
index 2983d19..0000000
--- a/framework/base/config/ESAPI.properties
+++ /dev/null
@@ -1,148 +0,0 @@
-#####################################################################
-# Based on the default ESAPI.properties file, which is BSD licensed.
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#####################################################################
-
-# Properties file for OWASP Enterprise Security API (ESAPI)
-# You can find more information about ESAPI at http://www.owasp.org/esapi
-
-# Validation
-#
-# The ESAPI validator does many security checks on input, such as canonicalization
-# and whitelist validation. Note that all of these validation rules are applied *after*
-# canonicalization. Double-encoded characters (even with different encodings involved,
-# are never allowed.
-#
-# To use:
-#
-# First set up a pattern below. You can choose any name you want, prefixed by the word
-# "Validation." For example:
-#   Validaton.email=^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$
-#
-# Then you can validate in your code against the pattern like this:
-#   Validator.getInstance().getValidDataFromBrowser( "Email", input );
-#   Validator.getInstance().isValidDataFromBrowser( "Email", input );
-#
-Validator.SafeString=^[\p{L}\p{N}.]{0,1024}$
-Validator.Email=^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$
-Validator.IPAddress=^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
-Validator.URL=^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\:\\'\\/\\\\\\+=&amp;%\\$#_]*)?$
-Validator.CreditCard=^(\\d{4}[- ]?){3}\\d{4}$
-Validator.SSN=^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$
-
-# Validators used by ESAPI
-Validator.AccountName=^[a-zA-Z0-9]{3,20}$
-Validator.SystemCommand=^[a-zA-Z\\-\\/]{0,64}$
-Validator.RoleName=^[a-z]{1,20}$
-Validator.Redirect=^\\/test.*$
-
-# Global HTTP Validation Rules
-# Values with Base64 encoded data (e.g. encrypted state) will need at least [a-zA-Z0-9\/+=]
-Validator.HTTPParameterName=^[a-zA-Z0-9_]{0,32}$
-Validator.HTTPParameterValue=^[a-zA-Z0-9.\\-\\/+=_ ]*$
-Validator.HTTPCookieName=^[a-zA-Z0-9\\-_]{0,32}$
-Validator.HTTPCookieValue=^[a-zA-Z0-9\\-\\/+=_ ]*$
-Validator.HTTPHeaderName=^[a-zA-Z0-9\\-_]{0,32}$
-Validator.HTTPHeaderValue=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$
-
-# Validation of file related input
-Validator.FileName=^[a-zA-Z0-9.\\-_ ]{0,255}$
-Validator.DirectoryName=^[a-zA-Z0-9.-\\_ ]{0,255}$
-
-# File upload configuration
-ValidExtensions=.zip,.pdf,.doc,.docx,.ppt,.pptx,.tar,.gz,.tgz,.rar,.war,.jar,.ear,.xls,.rtf,.properties,.java,.class,.txt,.xml,.jsp,.jsf,.exe,.dll
-MaxUploadFileBytes=500000000
-
-# Content-Type header
-ResponseContentType=text/html; charset=UTF-8
-
-# Logging
-#
-# Logging level, values are ALL, SEVERE, WARNING, INFO, DEBUG?
-LogLevel=ALL
-LogEncodingRequired=false
-
-# Intrusion Detection
-#
-# Each event has a base to which .count, .interval, and .action are added
-# The IntrusionException will fire if we receive "count" events within "interval" seconds
-# The IntrusionDetector is configurable to take the following actions: log, logout, and disable
-#  (multiple actions separated by commas are allowed e.g. event.test.actions=log,disable
-#
-# Custom Events
-# Names must start with "event." as the base
-# Use IntrusionDetector.addEvent( "test" ) in your code to trigger "event.test" here
-#
-event.test.count=2
-event.test.interval=10
-event.test.actions=disable,log
-
-# Exception Events
-# All EnterpriseSecurityExceptions are registered automatically
-# Call IntrusionDetector.getInstance().addException(e) for Exceptions that do not extend EnterpriseSecurityException
-# Use the fully qualified classname of the exception as the base
-
-# any intrusion is an attack
-org.owasp.esapi.errors.IntrusionException.count=1
-org.owasp.esapi.errors.IntrusionException.interval=1
-org.owasp.esapi.errors.IntrusionException.actions=log,disable,logout
-
-# for test purposes
-org.owasp.esapi.errors.IntegrityException.count=10
-org.owasp.esapi.errors.IntegrityException.interval=5
-org.owasp.esapi.errors.IntegrityException.actions=log,disable,logout
-
-# rapid validation errors indicate scans or attacks in progress
-# org.owasp.esapi.errors.ValidationException.count=10
-# org.owasp.esapi.errors.ValidationException.interval=10
-# org.owasp.esapi.errors.ValidationException.actions=log,logout
-
-
-# ================= PROPERTIES NOT CURRENTLY USED IN OFBIZ =================
-# These are not likely to be used, but leaving here commented out for future
-# references, just in case.
-
-# Authentication
-#RememberTokenDuration=14
-#AllowedLoginAttempts=3
-#MaxOldPasswordHashes=13
-#UsernameParameterName=username
-#PasswordParameterName=password
-
-# Encryption
-#MasterPassword=owasp1
-#MasterSalt=testtest
-
-# Algorithms
-# WARNING: Changing these settings will invalidate all user passwords, hashes, and encrypted data
-# WARNING: Reasonable values for these algorithms will be tested and documented in a future release
-#
-#CharacterEncoding=UTF-8
-#HashAlgorithm=SHA-512
-#HashIterations=1024
-##EncryptionAlgorithm=PBEWithMD5AndDES/CBC/PKCS5Padding
-#EncryptionAlgorithm=PBEWithMD5AndDES
-#RandomAlgorithm=SHA1PRNG
-#DigitalSignatureAlgorithm=SHAwithDSA
-
-# sessions jumping between hosts indicates a session hijacking
-#org.owasp.esapi.errors.AuthenticationHostException.count=2
-#org.owasp.esapi.errors.AuthenticationHostException.interval=10
-#org.owasp.esapi.errors.AuthenticationHostException.actions=log,logout
-
diff --git a/framework/base/config/antisamy-esapi.xml b/framework/base/config/antisamy-esapi.xml
deleted file mode 100644
index 8ae91f3..0000000
--- a/framework/base/config/antisamy-esapi.xml
+++ /dev/null
@@ -1,482 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
-Based on the default ESAPI.properties file, which is BSD licensed.
-
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-
-<!--
-W3C rules retrieved from:
-http://www.w3.org/TR/html401/struct/global.html
--->
-
-<!--
-Slashdot allowed tags taken from "Reply" page:
-<b> <i> <p> <br> <a> <ol> <ul> <li> <dl> <dt> <dd> <em> <strong> <tt> <blockquote> <div> <ecode> <quote>
-OFBiz additional allowed tags:
-<span>
--->
-
-<anti-samy-rules xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="antisamy.xsd">
-    <directives>
-        <directive name="omitXmlDeclaration" value="true"/>
-        <directive name="omitDoctypeDeclaration" value="true"/>
-        <directive name="maxInputSize" value="100000"/>
-        <directive name="embedStyleSheets" value="false"/>
-    </directives>
-    <common-regexps>
-        <!--
-        From W3C:
-        This attribute assigns a class name or set of class names to an
-        element. Any number of elements may be assigned the same class
-        name or names. Multiple class names must be separated by white
-        space characters.
-        -->
-
-        <regexp name="htmlTitle" value="[a-zA-Z0-9\s-_',:\[\]!\./\\\(\)]*"/> <!-- force non-empty with a '+' at the end instead of '*' -->
-        <regexp name="onsiteURL" value="([\w\\/\.\?=&amp;;\#-~]+|\#(\w)+)"/>
-        <regexp name="offsiteURL" value="(\s)*((ht|f)tp(s?)://|mailto:)[A-Za-z0-9]+[~a-zA-Z0-9-_\.@#$%&amp;;:,\?=/\+!]*(\s)*"/>
-    </common-regexps>
-
-    <!--
-
-    Tag.name = a, b, div, body, etc.
-    Tag.action = filter: remove tags, but keep content, validate: keep content as long as it passes rules, remove: remove tag and contents
-    Attribute.name = id, class, href, align, width, etc.
-    Attribute.onInvalid = what to do when the attribute is invalid, e.g., remove the tag (removeTag), remove the attribute (removeAttribute), filter the tag (filterTag)
-    Attribute.description = What rules in English you want to tell the users they can have for this attribute. Include helpful things so they'll be able to tune their HTML
-
-     -->
-
-    <!--
-    Some attributes are common to all (or most) HTML tags. There aren't many that qualify for this. You have to make sure there's no
-    collisions between any of these attribute names with attribute names of other tags that are for different purposes.
-    -->
-    <common-attributes>
-        <attribute name="lang" description="The 'lang' attribute tells the browser what language the element's attribute values and content are written in">
-             <regexp-list>
-                 <regexp value="[a-zA-Z]{2,20}"/>
-             </regexp-list>
-         </attribute>
-         <attribute name="title" description="The 'title' attribute provides text that shows up in a 'tooltip' when a user hovers their mouse over the element">
-             <regexp-list>
-                 <regexp name="htmlTitle"/>
-             </regexp-list>
-         </attribute>
-        <attribute name="href" onInvalid="filterTag">
-            <regexp-list>
-                <regexp name="onsiteURL"/>
-                <regexp name="offsiteURL"/>
-            </regexp-list>
-        </attribute>
-        <attribute name="align" description="The 'align' attribute of an HTML element is a direction word, like 'left', 'right' or 'center'">
-            <literal-list>
-                <literal value="center"/>
-                <literal value="left"/>
-                <literal value="right"/>
-                <literal value="justify"/>
-                <literal value="char"/>
-            </literal-list>
-        </attribute>
-    </common-attributes>
-
-    <!--
-    This requires normal updates as browsers continue to diverge from the W3C and each other. As long as the browser wars continue
-    this is going to continue. I'm not sure war is the right word for what's going on. Doesn't somebody have to win a war after
-    a while?
-     -->
-    <global-tag-attributes>
-        <attribute name="title"/>
-        <attribute name="lang"/>
-    </global-tag-attributes>
-    <tag-rules>
-        <!-- Tags related to JavaScript -->
-        <tag name="script" action="remove"/>
-        <tag name="noscript" action="remove"/>
-
-        <!-- Frame & related tags -->
-        <tag name="iframe" action="remove"/>
-        <tag name="frameset" action="remove"/>
-        <tag name="frame" action="remove"/>
-        <tag name="noframes" action="remove"/>
-
-        <!-- All reasonable formatting tags -->
-        <tag name="p" action="validate">
-            <attribute name="align"/>
-        </tag>
-
-        <tag name="div" action="validate"/>
-        <tag name="span" action="validate"/>
-        <tag name="i" action="validate"/>
-        <tag name="b" action="validate"/>
-        <tag name="em" action="validate"/>
-        <tag name="blockquote" action="validate"/>
-        <tag name="tt" action="validate"/>
-
-        <tag name="br" action="truncate"/>
-
-        <!-- Custom Slashdot tags, though we're trimming the idea of having a possible mismatching end tag with the endtag="" attribute -->
-        <tag name="quote" action="validate"/>
-        <tag name="ecode" action="validate"/>
-
-        <!-- Anchor and anchor related tags -->
-        <tag name="a" action="validate">
-            <attribute name="href" onInvalid="filterTag"/>
-            <attribute name="nohref">
-                <literal-list>
-                    <literal value="nohref"/>
-                    <literal value=""/>
-                </literal-list>
-            </attribute>
-            <attribute name="rel">
-                <literal-list>
-                    <literal value="nofollow"/>
-                </literal-list>
-            </attribute>
-        </tag>
-
-        <!-- List tags -->
-        <tag name="ul" action="validate"/>
-        <tag name="ol" action="validate"/>
-        <tag name="li" action="validate"/>
-    </tag-rules>
-
-    <!--  No CSS on Slashdot posts -->
-    <css-rules>
-    </css-rules>
-
-    <html-entities>
-        <entity name="amp" cdata="&amp;"/>
-        <entity name="nbsp" cdata="&amp;#160;"/>
-
-        <entity name="iexcl" cdata="&amp;#161;"/> <!--inverted exclamation mark, U+00A1 ISOnum -->
-        <entity name="cent" cdata="&amp;#162;"/> <!--cent sign, U+00A2 ISOnum -->
-        <entity name="pound" cdata="&amp;#163;"/> <!--pound sign, U+00A3 ISOnum -->
-        <entity name="curren" cdata="&amp;#164;"/> <!--currency sign, U+00A4 ISOnum -->
-        <entity name="yen" cdata="&amp;#165;"/> <!--yen sign = yuan sign, U+00A5 ISOnum -->
-        <entity name="brvbar" cdata="&amp;#166;"/> <!--broken bar = broken vertical bar, U+00A6 ISOnum -->
-        <entity name="sect" cdata="&amp;#167;"/> <!--section sign, U+00A7 ISOnum -->
-        <entity name="uml" cdata="&amp;#168;"/> <!--diaeresis = spacing diaeresis, U+00A8 ISOdia -->
-        <entity name="copy" cdata="&amp;#169;"/> <!--copyright sign, U+00A9 ISOnum -->
-        <entity name="ordf" cdata="&amp;#170;"/> <!--feminine ordinal indicator, U+00AA ISOnum -->
-        <entity name="laquo" cdata="&amp;#171;"/> <!--left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum -->
-        <entity name="not" cdata="&amp;#172;"/> <!--not sign, U+00AC ISOnum -->
-        <entity name="shy" cdata="&amp;#173;"/> <!--soft hyphen = discretionary hyphen,U+00AD ISOnum -->
-        <entity name="reg" cdata="&amp;#174;"/> <!--registered sign = registered trade mark sign, U+00AE ISOnum -->
-        <entity name="macr" cdata="&amp;#175;"/> <!--macron = spacing macron = overline = APL overbar, U+00AF ISOdia -->
-        <entity name="deg" cdata="&amp;#176;"/> <!--degree sign, U+00B0 ISOnum -->
-        <entity name="plusmn" cdata="&amp;#177;"/> <!--plus-minus sign = plus-or-minus sign, U+00B1 ISOnum -->
-        <entity name="sup2" cdata="&amp;#178;"/> <!--superscript two = superscript digit two = squared, U+00B2 ISOnum -->
-        <entity name="sup3" cdata="&amp;#179;"/> <!--superscript three = superscript digit three= cubed, U+00B3 ISOnum -->
-        <entity name="acute" cdata="&amp;#180;"/> <!--acute accent = spacing acute, U+00B4 ISOdia -->
-        <entity name="micro" cdata="&amp;#181;"/> <!--micro sign, U+00B5 ISOnum -->
-        <entity name="para" cdata="&amp;#182;"/> <!--pilcrow sign = paragraph sign, U+00B6 ISOnum -->
-        <entity name="middot" cdata="&amp;#183;"/> <!--middle dot = Georgian comma = Greek middle dot, U+00B7 ISOnum -->
-        <entity name="cedil" cdata="&amp;#184;"/> <!--cedilla = spacing cedilla, U+00B8 ISOdia -->
-        <entity name="sup1" cdata="&amp;#185;"/> <!--superscript one = superscript digit one,U+00B9 ISOnum -->
-        <entity name="ordm" cdata="&amp;#186;"/> <!--masculine ordinal indicator, U+00BA ISOnum -->
-        <entity name="raquo" cdata="&amp;#187;"/> <!--right-pointing double angle quotation mark = right pointing guillemet, U+00BB ISOnum -->
-        <entity name="frac14" cdata="&amp;#188;"/> <!--vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum -->
-        <entity name="frac12" cdata="&amp;#189;"/> <!--vulgar fraction one half = fraction one half, U+00BD ISOnum -->
-        <entity name="frac34" cdata="&amp;#190;"/> <!--vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum -->
-        <entity name="iquest" cdata="&amp;#191;"/> <!--inverted question mark = turned question mark, U+00BF ISOnum -->
-        <entity name="Agrave" cdata="&amp;#192;"/> <!--latin capital letter A with grave = latin capital letter A grave,U+00C0 ISOlat1 -->
-        <entity name="Aacute" cdata="&amp;#193;"/> <!--latin capital letter A with acute,U+00C1 ISOlat1 -->
-        <entity name="Acirc" cdata="&amp;#194;"/> <!--latin capital letter A with circumflex,U+00C2 ISOlat1 -->
-        <entity name="Atilde" cdata="&amp;#195;"/> <!--latin capital letter A with tilde,U+00C3 ISOlat1 -->
-        <entity name="Auml" cdata="&amp;#196;"/> <!--latin capital letter A with diaeresis,U+00C4 ISOlat1 -->
-        <entity name="Aring" cdata="&amp;#197;"/> <!--latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1 -->
-        <entity name="AElig" cdata="&amp;#198;"/> <!--latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1 -->
-        <entity name="Ccedil" cdata="&amp;#199;"/> <!--latin capital letter C with cedilla, U+00C7 ISOlat1 -->
-        <entity name="Egrave" cdata="&amp;#200;"/> <!--latin capital letter E with grave, U+00C8 ISOlat1 -->
-        <entity name="Eacute" cdata="&amp;#201;"/> <!--latin capital letter E with acute,U+00C9 ISOlat1 -->
-        <entity name="Ecirc" cdata="&amp;#202;"/> <!--latin capital letter E with circumflex,U+00CA ISOlat1 -->
-        <entity name="Euml" cdata="&amp;#203;"/> <!--latin capital letter E with diaeresis, U+00CB ISOlat1 -->
-        <entity name="Igrave" cdata="&amp;#204;"/> <!--latin capital letter I with grave, U+00CC ISOlat1 -->
-        <entity name="Iacute" cdata="&amp;#205;"/> <!--latin capital letter I with acute, U+00CD ISOlat1 -->
-        <entity name="Icirc" cdata="&amp;#206;"/> <!--latin capital letter I with circumflex, U+00CE ISOlat1 -->
-        <entity name="Iuml" cdata="&amp;#207;"/> <!--latin capital letter I with diaeresis, U+00CF ISOlat1 -->
-        <entity name="ETH" cdata="&amp;#208;"/> <!--latin capital letter ETH, U+00D0 ISOlat1 -->
-        <entity name="Ntilde" cdata="&amp;#209;"/> <!--latin capital letter N with tilde, U+00D1 ISOlat1 -->
-        <entity name="Ograve" cdata="&amp;#210;"/> <!--latin capital letter O with grave, U+00D2 ISOlat1 -->
-        <entity name="Oacute" cdata="&amp;#211;"/> <!--latin capital letter O with acute, U+00D3 ISOlat1 -->
-        <entity name="Ocirc" cdata="&amp;#212;"/> <!--latin capital letter O with circumflex, U+00D4 ISOlat1 -->
-        <entity name="Otilde" cdata="&amp;#213;"/> <!--latin capital letter O with tilde, U+00D5 ISOlat1 -->
-        <entity name="Ouml" cdata="&amp;#214;"/> <!--latin capital letter O with diaeresis, U+00D6 ISOlat1 -->
-        <entity name="times" cdata="&amp;#215;"/> <!--multiplication sign, U+00D7 ISOnum -->
-        <entity name="Oslash" cdata="&amp;#216;"/> <!--latin capital letter O with stroke = latin capital letter O slash, U+00D8 ISOlat1 -->
-        <entity name="Ugrave" cdata="&amp;#217;"/> <!--latin capital letter U with grave, U+00D9 ISOlat1 -->
-        <entity name="Uacute" cdata="&amp;#218;"/> <!--latin capital letter U with acute, U+00DA ISOlat1 -->
-        <entity name="Ucirc" cdata="&amp;#219;"/> <!--latin capital letter U with circumflex, U+00DB ISOlat1 -->
-        <entity name="Uuml" cdata="&amp;#220;"/> <!--latin capital letter U with diaeresis, U+00DC ISOlat1 -->
-        <entity name="Yacute" cdata="&amp;#221;"/> <!--latin capital letter Y with acute, U+00DD ISOlat1 -->
-        <entity name="THORN" cdata="&amp;#222;"/> <!--latin capital letter THORN, U+00DE ISOlat1 -->
-        <entity name="szlig" cdata="&amp;#223;"/> <!--latin small letter sharp s = ess-zed, U+00DF ISOlat1 -->
-        <entity name="agrave" cdata="&amp;#224;"/> <!--latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1 -->
-        <entity name="aacute" cdata="&amp;#225;"/> <!--latin small letter a with acute, U+00E1 ISOlat1 -->
-        <entity name="acirc" cdata="&amp;#226;"/> <!--latin small letter a with circumflex, U+00E2 ISOlat1 -->
-        <entity name="atilde" cdata="&amp;#227;"/> <!--latin small letter a with tilde, U+00E3 ISOlat1 -->
-        <entity name="auml" cdata="&amp;#228;"/> <!--latin small letter a with diaeresis, U+00E4 ISOlat1 -->
-        <entity name="aring" cdata="&amp;#229;"/> <!--latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1 -->
-        <entity name="aelig" cdata="&amp;#230;"/> <!--latin small letter ae = latin small ligature ae, U+00E6 ISOlat1 -->
-        <entity name="ccedil" cdata="&amp;#231;"/> <!--latin small letter c with cedilla, U+00E7 ISOlat1 -->
-        <entity name="egrave" cdata="&amp;#232;"/> <!--latin small letter e with grave, U+00E8 ISOlat1 -->
-        <entity name="eacute" cdata="&amp;#233;"/> <!--latin small letter e with acute, U+00E9 ISOlat1 -->
-        <entity name="ecirc" cdata="&amp;#234;"/> <!--latin small letter e with circumflex, U+00EA ISOlat1 -->
-        <entity name="euml" cdata="&amp;#235;"/> <!--latin small letter e with diaeresis, U+00EB ISOlat1 -->
-        <entity name="igrave" cdata="&amp;#236;"/> <!--latin small letter i with grave, U+00EC ISOlat1 -->
-        <entity name="iacute" cdata="&amp;#237;"/> <!--latin small letter i with acute, U+00ED ISOlat1 -->
-        <entity name="icirc" cdata="&amp;#238;"/> <!--latin small letter i with circumflex, U+00EE ISOlat1 -->
-        <entity name="iuml" cdata="&amp;#239;"/> <!--latin small letter i with diaeresis, U+00EF ISOlat1 -->
-        <entity name="eth" cdata="&amp;#240;"/> <!--latin small letter eth, U+00F0 ISOlat1 -->
-        <entity name="ntilde" cdata="&amp;#241;"/> <!--latin small letter n with tilde, U+00F1 ISOlat1 -->
-        <entity name="ograve" cdata="&amp;#242;"/> <!--latin small letter o with grave, U+00F2 ISOlat1 -->
-        <entity name="oacute" cdata="&amp;#243;"/> <!--latin small letter o with acute, U+00F3 ISOlat1 -->
-        <entity name="ocirc " cdata="&amp;#244;"/> <!--latin small letter o with circumflex, U+00F4 ISOlat1 -->
-        <entity name="otilde" cdata="&amp;#245;"/> <!--latin small letter o with tilde, U+00F5 ISOlat1 -->
-        <entity name="ouml" cdata="&amp;#246;"/> <!--latin small letter o with diaeresis, U+00F6 ISOlat1 -->
-        <entity name="divide" cdata="&amp;#247;"/> <!--division sign, U+00F7 ISOnum -->
-        <entity name="oslash" cdata="&amp;#248;"/> <!--latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1 -->
-        <entity name="ugrave" cdata="&amp;#249;"/> <!--latin small letter u with grave, U+00F9 ISOlat1 -->
-        <entity name="uacute" cdata="&amp;#250;"/> <!--latin small letter u with acute, U+00FA ISOlat1 -->
-        <entity name="ucirc" cdata="&amp;#251;"/> <!--latin small letter u with circumflex, U+00FB ISOlat1 -->
-        <entity name="uuml" cdata="&amp;#252;"/> <!--latin small letter u with diaeresis, U+00FC ISOlat1 -->
-        <entity name="yacute" cdata="&amp;#253;"/> <!--latin small letter y with acute, U+00FD ISOlat1 -->
-        <entity name="thorn" cdata="&amp;#254;"/> <!--latin small letter thorn, U+00FE ISOlat1 -->
-        <entity name="yuml" cdata="&amp;#255;"/> <!--latin small letter y with diaeresis, U+00FF ISOlat1 -->
-
-        <entity name="fnof" cdata="&amp;#402;"/> <!--latin small f with hook = function = florin, U+0192 ISOtech -->
-
-        <!-- Greek -->
-        <entity name="Alpha" cdata="&amp;#913;"/> <!--greek capital letter alpha, U+0391 -->
-        <entity name="Beta" cdata="&amp;#914;"/> <!--greek capital letter beta, U+0392 -->
-        <entity name="Gamma" cdata="&amp;#915;"/> <!--greek capital letter gamma, U+0393 ISOgrk3 -->
-        <entity name="Delta" cdata="&amp;#916;"/> <!--greek capital letter delta, U+0394 ISOgrk3 -->
-        <entity name="Epsilon" cdata="&amp;#917;"/> <!--greek capital letter epsilon, U+0395 -->
-        <entity name="Zeta" cdata="&amp;#918;"/> <!--greek capital letter zeta, U+0396 -->
-        <entity name="Eta" cdata="&amp;#919;"/> <!--greek capital letter eta, U+0397 -->
-        <entity name="Theta" cdata="&amp;#920;"/> <!--greek capital letter theta, U+0398 ISOgrk3 -->
-        <entity name="Iota" cdata="&amp;#921;"/> <!--greek capital letter iota, U+0399 -->
-        <entity name="Kappa" cdata="&amp;#922;"/> <!--greek capital letter kappa, U+039A -->
-        <entity name="Lambda" cdata="&amp;#923;"/> <!--greek capital letter lambda, U+039B ISOgrk3 -->
-        <entity name="Mu" cdata="&amp;#924;"/> <!--greek capital letter mu, U+039C -->
-        <entity name="Nu" cdata="&amp;#925;"/> <!--greek capital letter nu, U+039D -->
-        <entity name="Xi" cdata="&amp;#926;"/> <!--greek capital letter xi, U+039E ISOgrk3 -->
-        <entity name="Omicron" cdata="&amp;#927;"/> <!--greek capital letter omicron, U+039F -->
-        <entity name="Pi" cdata="&amp;#928;"/> <!--greek capital letter pi, U+03A0 ISOgrk3 -->
-        <entity name="Rho" cdata="&amp;#929;"/> <!--greek capital letter rho, U+03A1 -->
-        <!-- there is no Sigmaf, and no U+03A2 character either -->
-        <entity name="Sigma" cdata="&amp;#931;"/> <!--greek capital letter sigma, U+03A3 ISOgrk3 -->
-        <entity name="Tau" cdata="&amp;#932;"/> <!--greek capital letter tau, U+03A4 -->
-        <entity name="Upsilon" cdata="&amp;#933;"/> <!--greek capital letter upsilon,U+03A5 ISOgrk3 -->
-        <entity name="Phi" cdata="&amp;#934;"/> <!--greek capital letter phi,U+03A6 ISOgrk3 -->
-        <entity name="Chi" cdata="&amp;#935;"/> <!--greek capital letter chi, U+03A7 -->
-        <entity name="Psi" cdata="&amp;#936;"/> <!--greek capital letter psi,U+03A8 ISOgrk3 -->
-        <entity name="Omega" cdata="&amp;#937;"/> <!--greek capital letter omega,U+03A9 ISOgrk3 -->
-
-        <entity name="alpha" cdata="&amp;#945;"/> <!--greek small letter alpha,U+03B1 ISOgrk3 -->
-        <entity name="beta" cdata="&amp;#946;"/> <!--greek small letter beta, U+03B2 ISOgrk3 -->
-        <entity name="gamma" cdata="&amp;#947;"/> <!--greek small letter gamma,U+03B3 ISOgrk3 -->
-        <entity name="delta" cdata="&amp;#948;"/> <!--greek small letter delta,U+03B4 ISOgrk3 -->
-        <entity name="epsilon" cdata="&amp;#949;"/> <!--greek small letter epsilon,U+03B5 ISOgrk3 -->
-        <entity name="zeta" cdata="&amp;#950;"/> <!--greek small letter zeta, U+03B6 ISOgrk3 -->
-        <entity name="eta" cdata="&amp;#951;"/> <!--greek small letter eta, U+03B7 ISOgrk3 -->
-        <entity name="theta" cdata="&amp;#952;"/> <!--greek small letter theta, U+03B8 ISOgrk3 -->
-        <entity name="iota" cdata="&amp;#953;"/> <!--greek small letter iota, U+03B9 ISOgrk3 -->
-        <entity name="kappa" cdata="&amp;#954;"/> <!--greek small letter kappa,U+03BA ISOgrk3 -->
-        <entity name="lambda" cdata="&amp;#955;"/> <!--greek small letter lambda, U+03BB ISOgrk3 -->
-        <entity name="mu" cdata="&amp;#956;"/> <!--greek small letter mu, U+03BC ISOgrk3 -->
-        <entity name="nu" cdata="&amp;#957;"/> <!--greek small letter nu, U+03BD ISOgrk3 -->
-        <entity name="xi" cdata="&amp;#958;"/> <!--greek small letter xi, U+03BE ISOgrk3 -->
-        <entity name="omicron" cdata="&amp;#959;"/> <!--greek small letter omicron, U+03BF NEW -->
-        <entity name="pi" cdata="&amp;#960;"/> <!--greek small letter pi, U+03C0 ISOgrk3 -->
-        <entity name="rho" cdata="&amp;#961;"/> <!--greek small letter rho, U+03C1 ISOgrk3 -->
-        <entity name="sigmaf" cdata="&amp;#962;"/> <!--greek small letter final sigma, U+03C2 ISOgrk3 -->
-        <entity name="sigma" cdata="&amp;#963;"/> <!--greek small letter sigma, U+03C3 ISOgrk3 -->
-        <entity name="tau" cdata="&amp;#964;"/> <!--greek small letter tau, U+03C4 ISOgrk3 -->
-        <entity name="upsilon" cdata="&amp;#965;"/> <!--greek small letter upsilon, U+03C5 ISOgrk3 -->
-        <entity name="phi" cdata="&amp;#966;"/> <!--greek small letter phi, U+03C6 ISOgrk3 -->
-        <entity name="chi" cdata="&amp;#967;"/> <!--greek small letter chi, U+03C7 ISOgrk3 -->
-        <entity name="psi" cdata="&amp;#968;"/> <!--greek small letter psi, U+03C8 ISOgrk3 -->
-        <entity name="omega" cdata="&amp;#969;"/> <!--greek small letter omega, U+03C9 ISOgrk3 -->
-        <entity name="thetasym" cdata="&amp;#977;"/> <!--greek small letter theta symbol, U+03D1 NEW -->
-        <entity name="upsih" cdata="&amp;#978;"/> <!--greek upsilon with hook symbol, U+03D2 NEW -->
-        <entity name="piv" cdata="&amp;#982;"/> <!--greek pi symbol, U+03D6 ISOgrk3 -->
-
-        <!-- General Punctuation -->
-        <entity name="bull" cdata="&amp;#8226;"/> <!--bullet = black small circle, U+2022 ISOpub  -->
-        <!-- bullet is NOT the same as bullet operator, U+2219 -->
-        <entity name="hellip" cdata="&amp;#8230;"/> <!--horizontal ellipsis = three dot leader, U+2026 ISOpub  -->
-        <entity name="prime" cdata="&amp;#8242;"/> <!--prime = minutes = feet, U+2032 ISOtech -->
-        <entity name="Prime" cdata="&amp;#8243;"/> <!--double prime = seconds = inches, U+2033 ISOtech -->
-        <entity name="oline" cdata="&amp;#8254;"/> <!--overline = spacing overscore, U+203E NEW -->
-        <entity name="frasl" cdata="&amp;#8260;"/> <!--fraction slash, U+2044 NEW -->
-
-        <!-- Letterlike Symbols -->
-        <entity name="weierp" cdata="&amp;#8472;"/> <!--script capital P = power set = Weierstrass p, U+2118 ISOamso -->
-        <entity name="image" cdata="&amp;#8465;"/> <!--blackletter capital I = imaginary part, U+2111 ISOamso -->
-        <entity name="real" cdata="&amp;#8476;"/> <!--blackletter capital R = real part symbol, U+211C ISOamso -->
-        <entity name="trade" cdata="&amp;#8482;"/> <!--trade mark sign, U+2122 ISOnum -->
-        <entity name="alefsym" cdata="&amp;#8501;"/> <!--alef symbol = first transfinite cardinal, U+2135 NEW -->
-        <!-- alef symbol is NOT the same as hebrew letter alef,
-             U+05D0 although the same glyph could be used to depict both characters -->
-
-        <!-- Arrows -->
-        <entity name="larr" cdata="&amp;#8592;"/> <!--leftwards arrow, U+2190 ISOnum -->
-        <entity name="uarr" cdata="&amp;#8593;"/> <!--upwards arrow, U+2191 ISOnum-->
-        <entity name="rarr" cdata="&amp;#8594;"/> <!--rightwards arrow, U+2192 ISOnum -->
-        <entity name="darr" cdata="&amp;#8595;"/> <!--downwards arrow, U+2193 ISOnum -->
-        <entity name="harr" cdata="&amp;#8596;"/> <!--left right arrow, U+2194 ISOamsa -->
-        <entity name="crarr" cdata="&amp;#8629;"/> <!--downwards arrow with corner leftwards
-                                             = carriage return, U+21B5 NEW -->
-        <entity name="lArr" cdata="&amp;#8656;"/> <!--leftwards double arrow, U+21D0 ISOtech -->
-
-        <!-- ISO 10646 does not say that lArr is the same as the 'is implied by' arrow
-            but also does not have any other character for that function. So ? lArr can
-            be used for 'is implied by' as ISOtech suggests -->
-
-        <entity name="uArr" cdata="&amp;#8657;"/> <!--upwards double arrow, U+21D1 ISOamsa -->
-        <entity name="rArr" cdata="&amp;#8658;"/> <!--rightwards double arrow, U+21D2 ISOtech -->
-
-        <!-- ISO 10646 does not say this is the 'implies' character but does not have
-             another character with this function so ?
-             rArr can be used for 'implies' as ISOtech suggests -->
-
-        <entity name="dArr" cdata="&amp;#8659;"/> <!--downwards double arrow, U+21D3 ISOamsa -->
-        <entity name="hArr" cdata="&amp;#8660;"/> <!--left right double arrow, U+21D4 ISOamsa -->
-
-        <!-- Mathematical Operators -->
-        <entity name="forall" cdata="&amp;#8704;"/> <!--for all, U+2200 ISOtech -->
-        <entity name="part" cdata="&amp;#8706;"/> <!--partial differential, U+2202 ISOtech  -->
-        <entity name="exist" cdata="&amp;#8707;"/> <!--there exists, U+2203 ISOtech -->
-        <entity name="empty" cdata="&amp;#8709;"/> <!--empty set = null set = diameter,U+2205 ISOamso -->
-        <entity name="nabla" cdata="&amp;#8711;"/> <!--nabla = backward difference, U+2207 ISOtech -->
-        <entity name="isin" cdata="&amp;#8712;"/> <!--element of, U+2208 ISOtech -->
-        <entity name="notin" cdata="&amp;#8713;"/> <!--not an element of, U+2209 ISOtech -->
-        <entity name="ni" cdata="&amp;#8715;"/> <!--contains as member, U+220B ISOtech -->
-
-        <!-- should there be a more memorable name than 'ni'? -->
-        <entity name="prod" cdata="&amp;#8719;"/> <!--n-ary product = product sign, U+220F ISOamsb -->
-
-        <!-- prod is NOT the same character as U+03A0 'greek capital letter pi' though
-             the same glyph might be used for both -->
-
-        <entity name="sum" cdata="&amp;#8721;"/> <!--n-ary sumation, U+2211 ISOamsb -->
-
-        <!-- sum is NOT the same character as U+03A3 'greek capital letter sigma'
-             though the same glyph might be used for both -->
-
-        <entity name="minus" cdata="&amp;#8722;"/> <!--minus sign, U+2212 ISOtech -->
-        <entity name="lowast" cdata="&amp;#8727;"/> <!--asterisk operator, U+2217 ISOtech -->
-        <entity name="radic" cdata="&amp;#8730;"/> <!--square root = radical sign, U+221A ISOtech -->
-        <entity name="prop" cdata="&amp;#8733;"/> <!--proportional to, U+221D ISOtech -->
-        <entity name="infin" cdata="&amp;#8734;"/> <!--infinity, U+221E ISOtech -->
-        <entity name="ang" cdata="&amp;#8736;"/> <!--angle, U+2220 ISOamso -->
-        <entity name="and" cdata="&amp;#8743;"/> <!--logical and = wedge, U+2227 ISOtech -->
-        <entity name="or" cdata="&amp;#8744;"/> <!--logical or = vee, U+2228 ISOtech -->
-        <entity name="cap" cdata="&amp;#8745;"/> <!--intersection = cap, U+2229 ISOtech -->
-        <entity name="cup" cdata="&amp;#8746;"/> <!--union = cup, U+222A ISOtech -->
-        <entity name="int" cdata="&amp;#8747;"/> <!--integral, U+222B ISOtech -->
-        <entity name="there4" cdata="&amp;#8756;"/> <!--therefore, U+2234 ISOtech -->
-        <entity name="sim" cdata="&amp;#8764;"/> <!--tilde operator = varies with = similar to, U+223C ISOtech -->
-
-        <!-- tilde operator is NOT the same character as the tilde, U+007E,
-             although the same glyph might be used to represent both  -->
-
-        <entity name="cong" cdata="&amp;#8773;"/> <!--approximately equal to, U+2245 ISOtech -->
-        <entity name="asymp" cdata="&amp;#8776;"/> <!--almost equal to = asymptotic to, U+2248 ISOamsr -->
-        <entity name="ne" cdata="&amp;#8800;"/> <!--not equal to, U+2260 ISOtech -->
-        <entity name="equiv" cdata="&amp;#8801;"/> <!--identical to, U+2261 ISOtech -->
-        <entity name="le" cdata="&amp;#8804;"/> <!--less-than or equal to, U+2264 ISOtech -->
-        <entity name="ge" cdata="&amp;#8805;"/> <!--greater-than or equal to, U+2265 ISOtech -->
-        <entity name="sub" cdata="&amp;#8834;"/> <!--subset of, U+2282 ISOtech -->
-        <entity name="sup" cdata="&amp;#8835;"/> <!--superset of, U+2283 ISOtech -->
-
-        <!-- note that nsup, 'not a superset of, U+2283' is not covered by the Symbol
-             font encoding and is not included. Should it be, for symmetry?
-             It is in ISOamsn  -->
-
-        <entity name="nsub" cdata="&amp;#8836;"/> <!--not a subset of, U+2284 ISOamsn -->
-        <entity name="sube" cdata="&amp;#8838;"/> <!--subset of or equal to, U+2286 ISOtech -->
-        <entity name="supe" cdata="&amp;#8839;"/> <!--superset of or equal to, U+2287 ISOtech -->
-        <entity name="oplus" cdata="&amp;#8853;"/> <!--circled plus = direct sum, U+2295 ISOamsb -->
-        <entity name="otimes" cdata="&amp;#8855;"/> <!--circled times = vector product, U+2297 ISOamsb -->
-        <entity name="perp" cdata="&amp;#8869;"/> <!--up tack = orthogonal to = perpendicular, U+22A5 ISOtech -->
-        <entity name="sdot" cdata="&amp;#8901;"/> <!--dot operator, U+22C5 ISOamsb -->
-        <!-- dot operator is NOT the same character as U+00B7 middle dot -->
-
-        <!-- Miscellaneous Technical -->
-        <entity name="lceil" cdata="&amp;#8968;"/> <!--left ceiling = apl upstile, U+2308 ISOamsc  -->
-        <entity name="rceil" cdata="&amp;#8969;"/> <!--right ceiling, U+2309 ISOamsc  -->
-        <entity name="lfloor" cdata="&amp;#8970;"/> <!--left floor = apl downstile, U+230A ISOamsc  -->
-        <entity name="rfloor" cdata="&amp;#8971;"/> <!--right floor, U+230B ISOamsc  -->
-        <entity name="lang" cdata="&amp;#9001;"/> <!--left-pointing angle bracket = bra, U+2329 ISOtech -->
-        <!-- lang is NOT the same character as U+003C 'less than'
-             or U+2039 'single left-pointing angle quotation mark' -->
-        <entity name="rang" cdata="&amp;#9002;"/> <!--right-pointing angle bracket = ket, U+232A ISOtech -->
-        <!-- rang is NOT the same character as U+003E 'greater than' or U+203A 'single right-pointing angle quotation mark' -->
-
-        <!-- Geometric Shapes -->
-        <entity name="loz" cdata="&amp;#9674;"/> <!--lozenge, U+25CA ISOpub -->
-
-        <!-- Miscellaneous Symbols -->
-        <entity name="spades" cdata="&amp;#9824;"/> <!--black spade suit, U+2660 ISOpub -->
-        <!-- black here seems to mean filled as opposed to hollow -->
-        <entity name="clubs" cdata="&amp;#9827;"/> <!--black club suit = shamrock, U+2663 ISOpub -->
-        <entity name="hearts" cdata="&amp;#9829;"/> <!--black heart suit = valentine, U+2665 ISOpub -->
-        <entity name="diams" cdata="&amp;#9830;"/> <!--black diamond suit, U+2666 ISOpub -->
-
-        <entity name="quot" cdata="&amp;#34;"/> <!--quotation mark = APL quote, U+0022 ISOnum -->
-        <!-- Latin Extended-A -->
-        <entity name="OElig" cdata="&amp;#338;"/> <!--latin capital ligature OE, U+0152 ISOlat2 -->
-        <entity name="oelig" cdata="&amp;#339;"/> <!--latin small ligature oe, U+0153 ISOlat2 -->
-        <!-- ligature is a misnomer, this is a separate character in some languages -->
-        <entity name="Scaron" cdata="&amp;#352;"/> <!--latin capital letter S with caron, U+0160 ISOlat2 -->
-        <entity name="scaron" cdata="&amp;#353;"/> <!--latin small letter s with caron, U+0161 ISOlat2 -->
-        <entity name="Yuml" cdata="&amp;#376;"/> <!--latin capital letter Y with diaeresis, U+0178 ISOlat2 -->
-
-        <!-- Spacing Modifier Letters -->
-        <entity name="circ" cdata="&amp;#710;"/> <!--modifier letter circumflex accent, U+02C6 ISOpub -->
-        <entity name="tilde" cdata="&amp;#732;"/> <!--small tilde, U+02DC ISOdia -->
-
-        <!-- General Punctuation -->
-        <entity name="ensp" cdata="&amp;#8194;"/> <!--en space, U+2002 ISOpub -->
-        <entity name="emsp" cdata="&amp;#8195;"/> <!--em space, U+2003 ISOpub -->
-        <entity name="thinsp" cdata="&amp;#8201;"/> <!--thin space, U+2009 ISOpub -->
-        <entity name="zwnj" cdata="&amp;#8204;"/> <!--zero width non-joiner, U+200C NEW RFC 2070 -->
-        <entity name="zwj" cdata="&amp;#8205;"/> <!--zero width joiner, U+200D NEW RFC 2070 -->
-        <entity name="lrm" cdata="&amp;#8206;"/> <!--left-to-right mark, U+200E NEW RFC 2070 -->
-        <entity name="rlm" cdata="&amp;#8207;"/> <!--right-to-left mark, U+200F NEW RFC 2070 -->
-        <entity name="ndash" cdata="&amp;#8211;"/> <!--en dash, U+2013 ISOpub -->
-        <entity name="mdash" cdata="&amp;#8212;"/> <!--em dash, U+2014 ISOpub -->
-        <entity name="lsquo" cdata="&amp;#8216;"/> <!--left single quotation mark, U+2018 ISOnum -->
-        <entity name="rsquo" cdata="&amp;#8217;"/> <!--right single quotation mark, U+2019 ISOnum -->
-        <entity name="sbquo" cdata="&amp;#8218;"/> <!--single low-9 quotation mark, U+201A NEW -->
-        <entity name="ldquo" cdata="&amp;#8220;"/> <!--left double quotation mark, U+201C ISOnum -->
-        <entity name="rdquo" cdata="&amp;#8221;"/> <!--right double quotation mark, U+201D ISOnum -->
-        <entity name="bdquo" cdata="&amp;#8222;"/> <!--double low-9 quotation mark, U+201E NEW -->
-        <entity name="dagger" cdata="&amp;#8224;"/> <!--dagger, U+2020 ISOpub -->
-        <entity name="Dagger" cdata="&amp;#8225;"/> <!--double dagger, U+2021 ISOpub -->
-        <entity name="permil" cdata="&amp;#8240;"/> <!--per mille sign, U+2030 ISOtech -->
-        <entity name="lsaquo" cdata="&amp;#8249;"/> <!--single left-pointing angle quotation mark, U+2039 ISO proposed -->
-        <!-- lsaquo is proposed but not yet ISO standardized -->
-        <entity name="rsaquo" cdata="&amp;#8250;"/> <!--single right-pointing angle quotation mark, U+203A ISO proposed -->
-        <!-- rsaquo is proposed but not yet ISO standardized -->
-        <entity name="euro" cdata="&amp;#8364;"/> <!--euro sign, U+20AC NEW -->
-    </html-entities>
-</anti-samy-rules>
diff --git a/framework/base/lib/antisamy-bin.1.2.jar b/framework/base/lib/antisamy-bin.1.2.jar
deleted file mode 100644
index 1189dcb..0000000
--- a/framework/base/lib/antisamy-bin.1.2.jar
+++ /dev/null
Binary files differ
diff --git a/framework/base/lib/esapi-2.1.0.jar b/framework/base/lib/esapi-2.1.0.jar
new file mode 100644
index 0000000..e8f9ddd
--- /dev/null
+++ b/framework/base/lib/esapi-2.1.0.jar
Binary files differ
diff --git a/framework/base/lib/owasp-esapi-full-java-1.4-patched-by-OFBIZ-3135.jar b/framework/base/lib/owasp-esapi-full-java-1.4-patched-by-OFBIZ-3135.jar
deleted file mode 100644
index 81dac0b..0000000
--- a/framework/base/lib/owasp-esapi-full-java-1.4-patched-by-OFBIZ-3135.jar
+++ /dev/null
Binary files differ
diff --git a/framework/base/src/org/ofbiz/base/lang/ComparableRange.java b/framework/base/src/org/ofbiz/base/lang/ComparableRange.java
index 0ce84b9..fbf3414 100644
--- a/framework/base/src/org/ofbiz/base/lang/ComparableRange.java
+++ b/framework/base/src/org/ofbiz/base/lang/ComparableRange.java
@@ -18,9 +18,8 @@
  *******************************************************************************/
 package org.ofbiz.base.lang;
 
-/** An immutable range of values. */
+/** A range of values. */
 @SourceMonitored
-@ThreadSafe
 public class ComparableRange<T extends Comparable<T>> implements Range<T>, Comparable<ComparableRange<T>> {
 
     protected final T start;
diff --git a/framework/base/src/org/ofbiz/base/util/DateRange.java b/framework/base/src/org/ofbiz/base/util/DateRange.java
index 434d13e..f19dcdf 100644
--- a/framework/base/src/org/ofbiz/base/util/DateRange.java
+++ b/framework/base/src/org/ofbiz/base/util/DateRange.java
@@ -30,9 +30,9 @@
 @SuppressWarnings("serial")
 public class DateRange extends ComparableRange<Date> implements Serializable {
     /** A <code>Date</code> instance initialized to the earliest possible date.*/
-    public static final Date MIN_DATE = UtilDateTime.getEarliestDate();
+    public static final Date MIN_DATE = UtilDateTime.unmodifiableDate(UtilDateTime.getEarliestDate());
     /** A <code>Date</code> instance initialized to the latest possible date.*/
-    public static final Date MAX_DATE = UtilDateTime.getLatestDate();
+    public static final Date MAX_DATE = UtilDateTime.unmodifiableDate(UtilDateTime.getLatestDate());
     /** A <code>DateRange</code> instance initialized to the widest possible range of dates.*/
     public static final DateRange FullRange = new DateRange(MIN_DATE, MAX_DATE);
 
@@ -50,7 +50,8 @@
      * @param end If null, defaults to <a href="#MAX_DATE">MAX_DATE</a>
      */
     public DateRange(Date start, Date end) {
-        super(start == null ? MIN_DATE : timestampToDate(start), end == null ? MAX_DATE : timestampToDate(end));
+        super(start == null ? MIN_DATE : UtilDateTime.unmodifiableDate(timestampToDate(start)), end == null ? MAX_DATE
+                : UtilDateTime.unmodifiableDate(timestampToDate(end)));
     }
 
     @Override
diff --git a/framework/base/src/org/ofbiz/base/util/StringUtil.java b/framework/base/src/org/ofbiz/base/util/StringUtil.java
index e34c4e5..bd8c567 100644
--- a/framework/base/src/org/ofbiz/base/util/StringUtil.java
+++ b/framework/base/src/org/ofbiz/base/util/StringUtil.java
@@ -21,7 +21,6 @@
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.net.URLEncoder;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -36,14 +35,6 @@
 import org.apache.commons.codec.DecoderException;
 import org.apache.commons.codec.binary.Hex;
 import org.ofbiz.base.lang.Appender;
-import org.owasp.esapi.ValidationErrorList;
-import org.owasp.esapi.Validator;
-import org.owasp.esapi.codecs.Codec;
-import org.owasp.esapi.codecs.HTMLEntityCodec;
-import org.owasp.esapi.codecs.PercentCodec;
-import org.owasp.esapi.errors.IntrusionException;
-import org.owasp.esapi.reference.DefaultEncoder;
-import org.owasp.esapi.reference.DefaultValidator;
 
 /**
  * Misc String Utility Functions
@@ -56,15 +47,7 @@
     // FIXME: Not thread safe
     protected static final Map<String, Pattern> substitutionPatternMap;
 
-    /** OWASP ESAPI canonicalize strict flag; setting false so we only get warnings about double encoding, etc; can be set to true for exceptions and more security */
-    public static final boolean esapiCanonicalizeStrict = false;
-    public static final DefaultEncoder defaultWebEncoder;
-    public static final Validator defaultWebValidator;
     static {
-        // possible codecs: CSSCodec, HTMLEntityCodec, JavaScriptCodec, MySQLCodec, OracleCodec, PercentCodec, UnixCodec, VBScriptCodec, WindowsCodec
-        List<Codec> codecList = Arrays.asList(new HTMLEntityCodec(), new PercentCodec());
-        defaultWebEncoder = new DefaultEncoder(codecList);
-        defaultWebValidator = new DefaultValidator();
         substitutionPatternMap = new HashMap<String, Pattern>();
         substitutionPatternMap.put("&&", Pattern.compile("@and", Pattern.LITERAL));
         substitutionPatternMap.put("||", Pattern.compile("@or", Pattern.LITERAL));
@@ -74,52 +57,9 @@
         substitutionPatternMap.put(">", Pattern.compile("@gt", Pattern.LITERAL));
     }
 
-    public static final SimpleEncoder htmlEncoder = new HtmlEncoder();
-    public static final SimpleEncoder xmlEncoder = new XmlEncoder();
-    public static final SimpleEncoder stringEncoder = new StringEncoder();
-
     private StringUtil() {
     }
 
-    public static interface SimpleEncoder {
-        public String encode(String original);
-    }
-
-    public static class HtmlEncoder implements SimpleEncoder {
-        public String encode(String original) {
-            return StringUtil.defaultWebEncoder.encodeForHTML(original);
-        }
-    }
-
-    public static class XmlEncoder implements SimpleEncoder {
-        public String encode(String original) {
-            return StringUtil.defaultWebEncoder.encodeForXML(original);
-        }
-    }
-
-    public static class StringEncoder implements SimpleEncoder {
-        public String encode(String original) {
-            if (original != null) {
-                original = original.replace("\"", "\\\"");
-            }
-            return original;
-        }
-    }
-
-    // ================== Begin General Functions ==================
-
-    public static SimpleEncoder getEncoder(String type) {
-        if ("xml".equals(type)) {
-            return StringUtil.xmlEncoder;
-        } else if ("html".equals(type)) {
-            return StringUtil.htmlEncoder;
-        } else if ("string".equals(type)) {
-            return StringUtil.stringEncoder;
-        } else {
-            return null;
-        }
-    }
-
     public static String internString(String value) {
         return value != null ? value.intern() : null;
     }
@@ -595,78 +535,6 @@
     }
 
     /**
-     * Uses a black-list approach for necessary characters for HTML.
-     * Does not allow various characters (after canonicalization), including "<", ">", "&" (if not followed by a space), and "%" (if not followed by a space).
-     *
-     * @param value
-     * @param errorMessageList
-     */
-    public static String checkStringForHtmlStrictNone(String valueName, String value, List<String> errorMessageList) {
-        if (UtilValidate.isEmpty(value)) return value;
-
-        // canonicalize, strict (error on double-encoding)
-        try {
-            value = defaultWebEncoder.canonicalize(value, true);
-        } catch (IntrusionException e) {
-            // NOTE: using different log and user targeted error messages to allow the end-user message to be less technical
-            Debug.logError("Canonicalization (format consistency, character escaping that is mixed or double, etc) error for attribute named [" + valueName + "], String [" + value + "]: " + e.toString(), module);
-            errorMessageList.add("In field [" + valueName + "] found character escaping (mixed or double) that is not allowed or other format consistency error: " + e.toString());
-        }
-
-        // check for "<", ">"
-        if (value.indexOf("<") >= 0 || value.indexOf(">") >= 0) {
-            errorMessageList.add("In field [" + valueName + "] less-than (<) and greater-than (>) symbols are not allowed.");
-        }
-
-        /* NOTE DEJ 20090311: After playing with this more this doesn't seem to be necessary; the canonicalize will convert all such characters into actual text before this check is done, including other illegal chars like &lt; which will canonicalize to < and then get caught
-        // check for & followed a semicolon within 7 characters, no spaces in-between (and perhaps other things sometime?)
-        int curAmpIndex = value.indexOf("&");
-        while (curAmpIndex > -1) {
-            int semicolonIndex = value.indexOf(";", curAmpIndex + 1);
-            int spaceIndex = value.indexOf(" ", curAmpIndex + 1);
-            if (semicolonIndex > -1 && (semicolonIndex - curAmpIndex <= 7) && (spaceIndex < 0 || (spaceIndex > curAmpIndex && spaceIndex < semicolonIndex))) {
-                errorMessageList.add("In field [" + valueName + "] the ampersand (&) symbol is only allowed if not used as an encoded character: no semicolon (;) within 7 spaces or there is a space between.");
-                // once we find one like this we have the message so no need to check for more
-                break;
-            }
-            curAmpIndex = value.indexOf("&", curAmpIndex + 1);
-        }
-         */
-
-        /* NOTE DEJ 20090311: After playing with this more this doesn't seem to be necessary; the canonicalize will convert all such characters into actual text before this check is done, including other illegal chars like %3C which will canonicalize to < and then get caught
-        // check for % followed by 2 hex characters
-        int curPercIndex = value.indexOf("%");
-        while (curPercIndex >= 0) {
-            if (value.length() > (curPercIndex + 3) && UtilValidate.isHexDigit(value.charAt(curPercIndex + 1)) && UtilValidate.isHexDigit(value.charAt(curPercIndex + 2))) {
-                errorMessageList.add("In field [" + valueName + "] the percent (%) symbol is only allowed if followed by a space.");
-                // once we find one like this we have the message so no need to check for more
-                break;
-            }
-            curPercIndex = value.indexOf("%", curPercIndex + 1);
-        }
-         */
-
-        // TODO: anything else to check for that can be used to get HTML or JavaScript going without these characters?
-
-        return value;
-    }
-
-    /**
-     * Uses a white-list approach to check for safe HTML.
-     * Based on the ESAPI validator configured in the antisamy-esapi.xml file.
-     *
-     * @param value
-     * @param errorMessageList
-     * @return String with updated value if needed for safer HTML.
-     */
-    public static String checkStringForHtmlSafeOnly(String valueName, String value, List<String> errorMessageList) {
-        ValidationErrorList vel = new ValidationErrorList();
-        value = defaultWebValidator.getValidSafeHTML(valueName, value, Integer.MAX_VALUE, true, vel);
-        errorMessageList.addAll(UtilGenerics.checkList(vel.errors(), String.class));
-        return value;
-    }
-
-    /**
      * Remove/collapse multiple newline characters
      *
      * @param str string to collapse newlines in
@@ -786,57 +654,4 @@
             return this.theString;
         }
     }
-
-    /**
-     * A simple Map wrapper class that will do HTML encoding. To be used for passing a Map to something that will expand Strings with it as a context, etc.
-     */
-    public static class HtmlEncodingMapWrapper<K> implements Map<K, Object> {
-        public static <K> HtmlEncodingMapWrapper<K> getHtmlEncodingMapWrapper(Map<K, Object> mapToWrap, SimpleEncoder encoder) {
-            if (mapToWrap == null) return null;
-
-            HtmlEncodingMapWrapper<K> mapWrapper = new HtmlEncodingMapWrapper<K>();
-            mapWrapper.setup(mapToWrap, encoder);
-            return mapWrapper;
-        }
-
-        protected Map<K, Object> internalMap = null;
-        protected SimpleEncoder encoder = null;
-        protected HtmlEncodingMapWrapper() { }
-
-        public void setup(Map<K, Object> mapToWrap, SimpleEncoder encoder) {
-            this.internalMap = mapToWrap;
-            this.encoder = encoder;
-        }
-        public void reset() {
-            this.internalMap = null;
-            this.encoder = null;
-        }
-
-        public int size() { return this.internalMap.size(); }
-        public boolean isEmpty() { return this.internalMap.isEmpty(); }
-        public boolean containsKey(Object key) { return this.internalMap.containsKey(key); }
-        public boolean containsValue(Object value) { return this.internalMap.containsValue(value); }
-        public Object get(Object key) {
-            Object theObject = this.internalMap.get(key);
-            if (theObject instanceof String) {
-                if (this.encoder != null) {
-                    return encoder.encode((String) theObject);
-                } else {
-                    return StringUtil.defaultWebEncoder.encodeForHTML((String) theObject);
-                }
-            } else if (theObject instanceof Map<?, ?>) {
-                return HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(UtilGenerics.<K, Object>checkMap(theObject), this.encoder);
-            }
-            return theObject;
-        }
-        public Object put(K key, Object value) { return this.internalMap.put(key, value); }
-        public Object remove(Object key) { return this.internalMap.remove(key); }
-        public void putAll(Map<? extends K, ? extends Object> arg0) { this.internalMap.putAll(arg0); }
-        public void clear() { this.internalMap.clear(); }
-        public Set<K> keySet() { return this.internalMap.keySet(); }
-        public Collection<Object> values() { return this.internalMap.values(); }
-        public Set<Map.Entry<K, Object>> entrySet() { return this.internalMap.entrySet(); }
-        @Override
-        public String toString() { return this.internalMap.toString(); }
-    }
 }
diff --git a/framework/base/src/org/ofbiz/base/util/UtilCodec.java b/framework/base/src/org/ofbiz/base/util/UtilCodec.java
new file mode 100644
index 0000000..caf7a3a
--- /dev/null
+++ b/framework/base/src/org/ofbiz/base/util/UtilCodec.java
@@ -0,0 +1,314 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.base.util;
+
+import org.owasp.esapi.codecs.Codec;
+import org.owasp.esapi.codecs.HTMLEntityCodec;
+import org.owasp.esapi.codecs.PercentCodec;
+import org.owasp.esapi.codecs.XMLEntityCodec;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class UtilCodec {
+    private static final String module = UtilCodec.class.getName();
+    private static final HtmlEncoder htmlEncoder = new HtmlEncoder();
+    private static final XmlEncoder xmlEncoder = new XmlEncoder();
+    private static final StringEncoder stringEncoder = new StringEncoder();
+    private static final UrlCodec urlCodec = new UrlCodec();
+    private static final List<Codec> codecs;
+    static {
+        List<Codec> tmpCodecs = new ArrayList<Codec>();
+        tmpCodecs.add(new HTMLEntityCodec());
+        tmpCodecs.add(new PercentCodec());
+        codecs = Collections.unmodifiableList(tmpCodecs);
+    }
+
+    public static class IntrusionException extends GeneralRuntimeException {
+        public IntrusionException(String message) {
+            super(message);
+        }
+    }
+
+    public static interface SimpleEncoder {
+        public String encode(String original);
+    }
+
+    public static interface SimpleDecoder {
+        public String decode(String original);
+    }
+
+    public static class HtmlEncoder implements SimpleEncoder {
+        private static final char[] IMMUNE_HTML = {',', '.', '-', '_', ' '};
+        private HTMLEntityCodec htmlCodec = new HTMLEntityCodec();
+        public String encode(String original) {
+            if (original == null) {
+       	    	return null;
+       	    }
+       	    return htmlCodec.encode(IMMUNE_HTML, original);
+        }
+    }
+
+    public static class XmlEncoder implements SimpleEncoder {
+        private static final char[] IMMUNE_XML = {',', '.', '-', '_', ' '};
+        private XMLEntityCodec xmlCodec = new XMLEntityCodec();
+        public String encode(String original) {
+            if (original == null) {
+       	    	return null;
+       	    }
+       	    return xmlCodec.encode(IMMUNE_XML, original);
+        }
+    }
+
+    public static class UrlCodec implements SimpleEncoder, SimpleDecoder {
+        public String encode(String original) {
+            try {
+                return URLEncoder.encode(original, "UTF-8");
+            } catch (UnsupportedEncodingException ee) {
+                Debug.logError(ee, module);
+                return null;
+            }
+        }
+
+        public String decode(String original) {
+            try {
+                String canonical = canonicalize(original);
+                return URLDecoder.decode(canonical, "UTF-8");
+            } catch (UnsupportedEncodingException ee) {
+                Debug.logError(ee, module);
+                return null;
+            }
+        }
+    }
+
+    public static class StringEncoder implements SimpleEncoder {
+        public String encode(String original) {
+            if (original != null) {
+                original = original.replace("\"", "\\\"");
+            }
+            return original;
+        }
+    }
+
+    // ================== Begin General Functions ==================
+
+    public static SimpleEncoder getEncoder(String type) {
+        if ("url".equals(type)) {
+            return urlCodec;
+        } else if ("xml".equals(type)) {
+            return xmlEncoder;
+        } else if ("html".equals(type)) {
+            return htmlEncoder;
+        } else if ("string".equals(type)) {
+            return stringEncoder;
+        } else {
+            return null;
+        }
+    }
+
+    public static SimpleDecoder getDecoder(String type) {
+        if ("url".equals(type)) {
+            return urlCodec;
+        } else {
+            return null;
+        }
+    }
+
+    public static String canonicalize(String value) throws IntrusionException {
+        return canonicalize(value, true, true);
+    }
+
+    public static String canonicalize(String value, boolean strict) throws IntrusionException {
+        return canonicalize(value, strict, strict);
+    }
+
+    public static String canonicalize(String input, boolean restrictMultiple, boolean restrictMixed) {
+        if (input == null) {
+            return null;
+        }
+
+        String working = input;
+        Codec codecFound = null;
+        int mixedCount = 1;
+        int foundCount = 0;
+        boolean clean = false;
+        while (!clean) {
+            clean = true;
+
+            // try each codec and keep track of which ones work
+            Iterator i = codecs.iterator();
+            while (i.hasNext()) {
+                Codec codec = (Codec) i.next();
+                String old = working;
+                working = codec.decode(working);
+                if (!old.equals(working)) {
+                    if (codecFound != null && codecFound != codec) {
+                        mixedCount++;
+                    }
+                    codecFound = codec;
+                    if (clean) {
+                        foundCount++;
+                    }
+                    clean = false;
+                }
+            }
+        }
+
+        // do strict tests and handle if any mixed, multiple, nested encoding were found
+        if (foundCount >= 2 && mixedCount > 1) {
+            if (restrictMultiple || restrictMixed) {
+                throw new IntrusionException("Input validation failure");
+            } else {
+                Debug.logWarning("Multiple (" + foundCount + "x) and mixed encoding (" + mixedCount + "x) detected in " + input, module);
+            }
+        } else if (foundCount >= 2) {
+            if (restrictMultiple) {
+                throw new IntrusionException("Input validation failure");
+            } else {
+                Debug.logWarning("Multiple (" + foundCount + "x) encoding detected in " + input, module);
+            }
+        } else if (mixedCount > 1) {
+            if (restrictMixed) {
+                throw new IntrusionException("Input validation failure");
+            } else {
+                Debug.logWarning("Mixed encoding (" + mixedCount + "x) detected in " + input, module);
+            }
+        }
+        return working;
+    }
+
+    /**
+     * Uses a black-list approach for necessary characters for HTML.
+     * Does not allow various characters (after canonicalization), including "<", ">", "&" (if not followed by a space), and "%" (if not followed by a space).
+     *
+     * @param value
+     * @param errorMessageList
+     */
+    public static String checkStringForHtmlStrictNone(String valueName, String value, List<String> errorMessageList) {
+        if (UtilValidate.isEmpty(value)) return value;
+
+        // canonicalize, strict (error on double-encoding)
+        try {
+            value = canonicalize(value, true);
+        } catch (IntrusionException e) {
+            // NOTE: using different log and user targeted error messages to allow the end-user message to be less technical
+            Debug.logError("Canonicalization (format consistency, character escaping that is mixed or double, etc) error for attribute named [" + valueName + "], String [" + value + "]: " + e.toString(), module);
+            errorMessageList.add("In field [" + valueName + "] found character escaping (mixed or double) that is not allowed or other format consistency error: " + e.toString());
+        }
+
+        // check for "<", ">"
+        if (value.indexOf("<") >= 0 || value.indexOf(">") >= 0) {
+            errorMessageList.add("In field [" + valueName + "] less-than (<) and greater-than (>) symbols are not allowed.");
+        }
+
+        /* NOTE DEJ 20090311: After playing with this more this doesn't seem to be necessary; the canonicalize will convert all such characters into actual text before this check is done, including other illegal chars like &lt; which will canonicalize to < and then get caught
+        // check for & followed a semicolon within 7 characters, no spaces in-between (and perhaps other things sometime?)
+        int curAmpIndex = value.indexOf("&");
+        while (curAmpIndex > -1) {
+            int semicolonIndex = value.indexOf(";", curAmpIndex + 1);
+            int spaceIndex = value.indexOf(" ", curAmpIndex + 1);
+            if (semicolonIndex > -1 && (semicolonIndex - curAmpIndex <= 7) && (spaceIndex < 0 || (spaceIndex > curAmpIndex && spaceIndex < semicolonIndex))) {
+                errorMessageList.add("In field [" + valueName + "] the ampersand (&) symbol is only allowed if not used as an encoded character: no semicolon (;) within 7 spaces or there is a space between.");
+                // once we find one like this we have the message so no need to check for more
+                break;
+            }
+            curAmpIndex = value.indexOf("&", curAmpIndex + 1);
+        }
+         */
+
+        /* NOTE DEJ 20090311: After playing with this more this doesn't seem to be necessary; the canonicalize will convert all such characters into actual text before this check is done, including other illegal chars like %3C which will canonicalize to < and then get caught
+        // check for % followed by 2 hex characters
+        int curPercIndex = value.indexOf("%");
+        while (curPercIndex >= 0) {
+            if (value.length() > (curPercIndex + 3) && UtilValidate.isHexDigit(value.charAt(curPercIndex + 1)) && UtilValidate.isHexDigit(value.charAt(curPercIndex + 2))) {
+                errorMessageList.add("In field [" + valueName + "] the percent (%) symbol is only allowed if followed by a space.");
+                // once we find one like this we have the message so no need to check for more
+                break;
+            }
+            curPercIndex = value.indexOf("%", curPercIndex + 1);
+        }
+         */
+
+        // TODO: anything else to check for that can be used to get HTML or JavaScript going without these characters?
+
+        return value;
+    }
+
+    /**
+     * A simple Map wrapper class that will do HTML encoding. To be used for passing a Map to something that will expand Strings with it as a context, etc.
+     */
+    public static class HtmlEncodingMapWrapper<K> implements Map<K, Object> {
+        public static <K> HtmlEncodingMapWrapper<K> getHtmlEncodingMapWrapper(Map<K, Object> mapToWrap, SimpleEncoder encoder) {
+            if (mapToWrap == null) return null;
+
+            HtmlEncodingMapWrapper<K> mapWrapper = new HtmlEncodingMapWrapper<K>();
+            mapWrapper.setup(mapToWrap, encoder);
+            return mapWrapper;
+        }
+
+        protected Map<K, Object> internalMap = null;
+        protected SimpleEncoder encoder = null;
+        protected HtmlEncodingMapWrapper() { }
+
+        public void setup(Map<K, Object> mapToWrap, SimpleEncoder encoder) {
+            this.internalMap = mapToWrap;
+            this.encoder = encoder;
+        }
+        public void reset() {
+            this.internalMap = null;
+            this.encoder = null;
+        }
+
+        public int size() { return this.internalMap.size(); }
+        public boolean isEmpty() { return this.internalMap.isEmpty(); }
+        public boolean containsKey(Object key) { return this.internalMap.containsKey(key); }
+        public boolean containsValue(Object value) { return this.internalMap.containsValue(value); }
+        public Object get(Object key) {
+            Object theObject = this.internalMap.get(key);
+            if (theObject instanceof String) {
+                if (this.encoder != null) {
+                    return encoder.encode((String) theObject);
+                } else {
+                    return UtilCodec.getEncoder("html").encode((String) theObject);
+                }
+            } else if (theObject instanceof Map<?, ?>) {
+                return HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(UtilGenerics.<K, Object>checkMap(theObject), this.encoder);
+            }
+            return theObject;
+        }
+        public Object put(K key, Object value) { return this.internalMap.put(key, value); }
+        public Object remove(Object key) { return this.internalMap.remove(key); }
+        public void putAll(Map<? extends K, ? extends Object> arg0) { this.internalMap.putAll(arg0); }
+        public void clear() { this.internalMap.clear(); }
+        public Set<K> keySet() { return this.internalMap.keySet(); }
+        public Collection<Object> values() { return this.internalMap.values(); }
+        public Set<Map.Entry<K, Object>> entrySet() { return this.internalMap.entrySet(); }
+        @Override
+        public String toString() { return this.internalMap.toString(); }
+    }
+
+}
diff --git a/framework/base/src/org/ofbiz/base/util/UtilDateTime.java b/framework/base/src/org/ofbiz/base/util/UtilDateTime.java
index ede2c0d..96fe317 100644
--- a/framework/base/src/org/ofbiz/base/util/UtilDateTime.java
+++ b/framework/base/src/org/ofbiz/base/util/UtilDateTime.java
@@ -25,8 +25,8 @@
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Date;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -972,7 +972,7 @@
         if (UtilValidate.isEmpty(dateFormat)) {
             df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
         } else {
-            df = new SimpleDateFormat(dateFormat);
+            df = new SimpleDateFormat(dateFormat, locale == null ? Locale.getDefault() : locale);
         }
         df.setTimeZone(tz);
         return df;
@@ -990,7 +990,7 @@
         if (UtilValidate.isEmpty(dateTimeFormat)) {
             df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale);
         } else {
-            df = new SimpleDateFormat(dateTimeFormat);
+            df = new SimpleDateFormat(dateTimeFormat, locale == null ? Locale.getDefault() : locale);
         }
         df.setTimeZone(tz);
         return df;
@@ -1008,7 +1008,7 @@
         if (UtilValidate.isEmpty(timeFormat)) {
             df = DateFormat.getTimeInstance(DateFormat.MEDIUM, locale);
         } else {
-            df = new SimpleDateFormat(timeFormat);
+            df = new SimpleDateFormat(timeFormat, locale == null ? Locale.getDefault() : locale);
         }
         df.setTimeZone(tz);
         return df;
@@ -1042,34 +1042,37 @@
      */
     public static String timeStampToString(Timestamp stamp, String dateTimeFormat, TimeZone tz, Locale locale) {
         DateFormat dateFormat = toDateTimeFormat(dateTimeFormat, tz, locale);
-        dateFormat.setTimeZone(tz);
         return dateFormat.format(stamp);
     }
 
-    protected static List<TimeZone> availableTimeZoneList = null;
+    // Private lazy-initializer class 
+    private static class TimeZoneHolder {
+        private static final List<TimeZone> availableTimeZoneList = getTimeZones();
+
+        private static List<TimeZone> getTimeZones() {
+            ArrayList<TimeZone> availableTimeZoneList = new ArrayList<TimeZone>();
+            List<String> idList = null;
+            String tzString = UtilProperties.getPropertyValue("general", "timeZones.available");
+            if (UtilValidate.isNotEmpty(tzString)) {
+                idList = StringUtil.split(tzString, ",");
+            } else {
+                idList = Arrays.asList(TimeZone.getAvailableIDs());
+            }
+            for (String id : idList) {
+                TimeZone curTz = TimeZone.getTimeZone(id);
+                availableTimeZoneList.add(curTz);
+            }
+            availableTimeZoneList.trimToSize();
+            return Collections.unmodifiableList(availableTimeZoneList);
+        }
+
+    }
+
     /** Returns a List of available TimeZone objects.
      * @see java.util.TimeZone
      */
     public static List<TimeZone> availableTimeZones() {
-        if (availableTimeZoneList == null) {
-            synchronized(UtilDateTime.class) {
-                if (availableTimeZoneList == null) {
-                    availableTimeZoneList = new LinkedList<TimeZone>();
-                    List<String> idList = null;
-                    String tzString = UtilProperties.getPropertyValue("general", "timeZones.available");
-                    if (UtilValidate.isNotEmpty(tzString)) {
-                        idList = StringUtil.split(tzString, ",");
-                    } else {
-                        idList = Arrays.asList(TimeZone.getAvailableIDs());
-                    }
-                    for (String id: idList) {
-                        TimeZone curTz = TimeZone.getTimeZone(id);
-                        availableTimeZoneList.add(curTz);
-                    }
-                }
-            }
-        }
-        return availableTimeZoneList;
+        return TimeZoneHolder.availableTimeZoneList;
     }
 
     /** Returns a TimeZone object based upon a time zone ID. Method defaults to
@@ -1096,47 +1099,47 @@
     }
 
     public static int getSecond(Timestamp stamp, TimeZone timeZone, Locale locale) {
-        Calendar cal = UtilDateTime.toCalendar(stamp, timeZone, locale);
+        Calendar cal = toCalendar(stamp, timeZone, locale);
         return cal.get(Calendar.SECOND);
     }
 
     public static int getMinute(Timestamp stamp, TimeZone timeZone, Locale locale) {
-        Calendar cal = UtilDateTime.toCalendar(stamp, timeZone, locale);
+        Calendar cal = toCalendar(stamp, timeZone, locale);
         return cal.get(Calendar.MINUTE);
     }
 
     public static int getHour(Timestamp stamp, TimeZone timeZone, Locale locale) {
-        Calendar cal = UtilDateTime.toCalendar(stamp, timeZone, locale);
+        Calendar cal = toCalendar(stamp, timeZone, locale);
         return cal.get(Calendar.HOUR_OF_DAY);
     }
 
     public static int getDayOfWeek(Timestamp stamp, TimeZone timeZone, Locale locale) {
-        Calendar cal = UtilDateTime.toCalendar(stamp, timeZone, locale);
+        Calendar cal = toCalendar(stamp, timeZone, locale);
         return cal.get(Calendar.DAY_OF_WEEK);
     }
 
     public static int getDayOfMonth(Timestamp stamp, TimeZone timeZone, Locale locale) {
-        Calendar cal = UtilDateTime.toCalendar(stamp, timeZone, locale);
+        Calendar cal = toCalendar(stamp, timeZone, locale);
         return cal.get(Calendar.DAY_OF_MONTH);
     }
 
     public static int getDayOfYear(Timestamp stamp, TimeZone timeZone, Locale locale) {
-        Calendar cal = UtilDateTime.toCalendar(stamp, timeZone, locale);
+        Calendar cal = toCalendar(stamp, timeZone, locale);
         return cal.get(Calendar.DAY_OF_YEAR);
     }
 
     public static int getWeek(Timestamp stamp, TimeZone timeZone, Locale locale) {
-        Calendar cal = UtilDateTime.toCalendar(stamp, timeZone, locale);
+        Calendar cal = toCalendar(stamp, timeZone, locale);
         return cal.get(Calendar.WEEK_OF_YEAR);
     }
 
     public static int getMonth(Timestamp stamp, TimeZone timeZone, Locale locale) {
-        Calendar cal = UtilDateTime.toCalendar(stamp, timeZone, locale);
+        Calendar cal = toCalendar(stamp, timeZone, locale);
         return cal.get(Calendar.MONTH);
     }
 
     public static int getYear(Timestamp stamp, TimeZone timeZone, Locale locale) {
-        Calendar cal = UtilDateTime.toCalendar(stamp, timeZone, locale);
+        Calendar cal = toCalendar(stamp, timeZone, locale);
         return cal.get(Calendar.YEAR);
     }
 
@@ -1163,4 +1166,67 @@
         cal.set(Calendar.MILLISECOND, 999);
         return cal.getTime();
     }
+
+    /**
+     * Returns a copy of <code>date</code> that cannot be modified.
+     * Attempts to modify the returned date will result in an
+     * <tt>UnsupportedOperationException</tt>.
+     * 
+     * @param date
+     */
+    public static Date unmodifiableDate(Date date) {
+        if (date instanceof ImmutableDate) {
+            return date;
+        }
+        return new ImmutableDate(date.getTime());
+    }
+
+    @SuppressWarnings("serial")
+    private static class ImmutableDate extends Date {
+        private ImmutableDate(long date) {
+            super(date);
+        }
+
+        @Override
+        public Object clone() {
+            // No need to clone an immutable object.
+            return this;
+        }
+
+        @Override
+        public void setYear(int year) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void setMonth(int month) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void setDate(int date) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void setHours(int hours) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void setMinutes(int minutes) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void setSeconds(int seconds) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void setTime(long time) {
+            throw new UnsupportedOperationException();
+        }
+
+    }
 }
diff --git a/framework/base/src/org/ofbiz/base/util/UtilHttp.java b/framework/base/src/org/ofbiz/base/util/UtilHttp.java
index 9f545a8..60c27f3 100644
--- a/framework/base/src/org/ofbiz/base/util/UtilHttp.java
+++ b/framework/base/src/org/ofbiz/base/util/UtilHttp.java
@@ -53,8 +53,6 @@
 import org.apache.oro.text.regex.Pattern;
 import org.apache.oro.text.regex.PatternMatcher;
 import org.apache.oro.text.regex.Perl5Matcher;
-import org.owasp.esapi.errors.EncodingException;
-import org.owasp.esapi.errors.IntrusionException;
 
 import com.ibm.icu.util.Calendar;
 
@@ -155,10 +153,6 @@
         return canonicalizeParameterMap(paramMap);
     }
 
-    public static Map<String, Object> getQueryStringOnlyParameterMap(HttpServletRequest request) {
-        return getQueryStringOnlyParameterMap(request.getQueryString());
-    }
-
     public static Map<String, Object> getQueryStringOnlyParameterMap(String queryString) {
         Map<String, Object> paramMap = new HashMap<String, Object>();
         if (UtilValidate.isNotEmpty(queryString)) {
@@ -232,13 +226,9 @@
     }
 
     public static Map<String, Object> getUrlOnlyParameterMap(HttpServletRequest request) {
-        return getUrlOnlyParameterMap(request.getQueryString(), request.getPathInfo());
-    }
-
-    public static Map<String, Object> getUrlOnlyParameterMap(String queryString, String pathInfo) {
         // NOTE: these have already been through canonicalizeParameterMap, so not doing it again here
-        Map<String, Object> paramMap = getQueryStringOnlyParameterMap(queryString);
-        paramMap.putAll(getPathInfoOnlyParameterMap(pathInfo, null, null));
+        Map<String, Object> paramMap = getQueryStringOnlyParameterMap(request.getQueryString());
+        paramMap.putAll(getPathInfoOnlyParameterMap(request.getPathInfo(), null, null));
         return paramMap;
     }
 
@@ -259,10 +249,11 @@
 
     public static String canonicalizeParameter(String paramValue) {
         try {
-            String cannedStr = StringUtil.defaultWebEncoder.canonicalize(paramValue, StringUtil.esapiCanonicalizeStrict);
+            /** calling canonicalize with strict flag set to false so we only get warnings about double encoding, etc; can be set to true for exceptions and more security */
+            String cannedStr = UtilCodec.canonicalize(paramValue, false);
             if (Debug.verboseOn()) Debug.logVerbose("Canonicalized parameter with " + (cannedStr.equals(paramValue) ? "no " : "") + "change: original [" + paramValue + "] canned [" + cannedStr + "]", module);
             return cannedStr;
-        } catch (IntrusionException e) {
+        } catch (Exception e) {
             Debug.logError(e, "Error in canonicalize parameter value [" + paramValue + "]: " + e.toString(), module);
             return paramValue;
         }
@@ -799,22 +790,14 @@
                                 buf.append("&");
                             }
                         }
-                        try {
-                            buf.append(StringUtil.defaultWebEncoder.encodeForURL(name));
-                        } catch (EncodingException e) {
-                            Debug.logError(e, module);
-                        }
+                        buf.append(UtilCodec.getEncoder("url").encode(name));
                         /* the old way: try {
                             buf.append(URLEncoder.encode(name, "UTF-8"));
                         } catch (UnsupportedEncodingException e) {
                             Debug.logError(e, module);
                         } */
                         buf.append('=');
-                        try {
-                            buf.append(StringUtil.defaultWebEncoder.encodeForURL(valueStr));
-                        } catch (EncodingException e) {
-                            Debug.logError(e, module);
-                        }
+                        buf.append(UtilCodec.getEncoder("url").encode(valueStr));
                         /* the old way: try {
                             buf.append(URLEncoder.encode(valueStr, "UTF-8"));
                         } catch (UnsupportedEncodingException e) {
diff --git a/framework/base/src/org/ofbiz/base/util/UtilMisc.java b/framework/base/src/org/ofbiz/base/util/UtilMisc.java
index e31637c..6cb32c3 100644
--- a/framework/base/src/org/ofbiz/base/util/UtilMisc.java
+++ b/framework/base/src/org/ofbiz/base/util/UtilMisc.java
@@ -722,46 +722,40 @@
      * @param localeObject An Object representing the locale
      */
     public static Locale ensureLocale(Object localeObject) {
-        if (localeObject != null && localeObject instanceof String) {
-            localeObject = UtilMisc.parseLocale((String) localeObject);
-        }
-        if (localeObject != null && localeObject instanceof Locale) {
+        if (localeObject instanceof String) {
+            return parseLocale((String) localeObject);
+        } else if (localeObject instanceof Locale) {
             return (Locale) localeObject;
         }
         return Locale.getDefault();
     }
 
-    public static List<Locale> availableLocaleList = null;
-    /** Returns a List of available locales sorted by display name */
-    public static List<Locale> availableLocales() {
-        if (availableLocaleList == null) {
-            synchronized(UtilMisc.class) {
-                if (availableLocaleList == null) {
-                    TreeMap<String, Locale> localeMap = new TreeMap<String, Locale>();
-                    String localesString = UtilProperties.getPropertyValue("general", "locales.available");
-                    if (UtilValidate.isNotEmpty(localesString)) { // check if available locales need to be limited according general.properties file
-                        int end = -1;
-                        int start = 0;
-                        for (int i=0; start < localesString.length(); i++) {
-                            end = localesString.indexOf(",", start);
-                            if (end == -1) {
-                                end = localesString.length();
-                            }
-                            Locale curLocale = UtilMisc.ensureLocale(localesString.substring(start, end));
-                            localeMap.put(curLocale.getDisplayName(), curLocale);
-                            start = end + 1;
-                        }
-                    } else {
-                        Locale[] locales = Locale.getAvailableLocales();
-                        for (int i = 0; i < locales.length && locales[i] != null; i++) {
-                            localeMap.put(locales[i].getDisplayName(), locales[i]);
-                        }
-                    }
-                    availableLocaleList = new LinkedList<Locale>(localeMap.values());
+    // Private lazy-initializer class
+    private static class LocaleHolder {
+        private static final List<Locale> availableLocaleList = getAvailableLocaleList();
+
+        private static List<Locale> getAvailableLocaleList() {
+            TreeMap<String, Locale> localeMap = new TreeMap<String, Locale>();
+            String localesString = UtilProperties.getPropertyValue("general", "locales.available");
+            if (UtilValidate.isNotEmpty(localesString)) {
+                List<String> idList = StringUtil.split(localesString, ",");
+                for (String id : idList) {
+                    Locale curLocale = parseLocale(id);
+                    localeMap.put(curLocale.getDisplayName(), curLocale);
+                }
+            } else {
+                Locale[] locales = Locale.getAvailableLocales();
+                for (int i = 0; i < locales.length && locales[i] != null; i++) {
+                    localeMap.put(locales[i].getDisplayName(), locales[i]);
                 }
             }
+            return Collections.unmodifiableList(new ArrayList<Locale>(localeMap.values()));
         }
-        return availableLocaleList;
+    }
+
+    /** Returns a List of available locales sorted by display name */
+    public static List<Locale> availableLocales() {
+        return LocaleHolder.availableLocaleList;
     }
 
     /** @deprecated use Thread.sleep() */
diff --git a/framework/base/src/org/ofbiz/base/util/UtilProperties.java b/framework/base/src/org/ofbiz/base/util/UtilProperties.java
index 8ee8142..9b9da8c 100644
--- a/framework/base/src/org/ofbiz/base/util/UtilProperties.java
+++ b/framework/base/src/org/ofbiz/base/util/UtilProperties.java
@@ -30,6 +30,7 @@
 import java.net.URL;
 import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.InvalidPropertiesFormatException;
@@ -77,8 +78,6 @@
      */
     private static final UtilCache<String, Properties> urlCache = UtilCache.createUtilCache("properties.UtilPropertiesUrlCache");
 
-    protected static Locale fallbackLocale = null;
-    protected static Set<Locale> defaultCandidateLocales = null;
     protected static Set<String> propertiesNotFound = new HashSet<String>();
 
     /** Compares the specified property to the compareString, returns true if they are the same, false otherwise
@@ -746,29 +745,31 @@
 
     // ========= Classes and Methods for expanded Properties file support ========== //
 
+    // Private lazy-initializer class
+    private static class FallbackLocaleHolder {
+        private static final Locale fallbackLocale = getFallbackLocale();
+
+        private static Locale getFallbackLocale() {
+            Locale fallbackLocale = null;
+            String locale = getPropertyValue("general", "locale.properties.fallback");
+            if (UtilValidate.isNotEmpty(locale)) {
+                fallbackLocale = UtilMisc.parseLocale(locale);
+            }
+            if (fallbackLocale == null) {
+                fallbackLocale = Locale.ENGLISH;
+            }
+            return fallbackLocale;
+        }
+    }
+
     /** Returns the configured fallback locale. UtilProperties uses this locale
      * to resolve locale-specific XML properties.<p>The fallback locale can be
      * configured using the <code>locale.properties.fallback</code> property in
      * <code>general.properties</code>.
      * @return The configured fallback locale
-     * @deprecated Use <code>java.util.ResourceBundle.Control.getFallbackLocale(...)</code>
      */
-    @Deprecated
     public static Locale getFallbackLocale() {
-        if (fallbackLocale == null) {
-            synchronized (UtilProperties.class) {
-                if (fallbackLocale == null) {
-                    String locale = getPropertyValue("general", "locale.properties.fallback");
-                    if (UtilValidate.isNotEmpty(locale)) {
-                        fallbackLocale = UtilMisc.parseLocale(locale);
-                    }
-                    if (fallbackLocale == null) {
-                        fallbackLocale = UtilMisc.parseLocale("en");
-                    }
-                }
-            }
-        }
-        return fallbackLocale;
+        return FallbackLocaleHolder.fallbackLocale;
     }
 
     /** Converts a Locale instance to a candidate Locale list. The list
@@ -790,23 +791,26 @@
         return localeList;
     }
 
+    // Private lazy-initializer class
+    private static class CandidateLocalesHolder {
+        private static Set<Locale> defaultCandidateLocales = getDefaultCandidateLocales();
+
+        private static Set<Locale> getDefaultCandidateLocales() {
+            Set<Locale> defaultCandidateLocales = new LinkedHashSet<Locale>();
+            defaultCandidateLocales.addAll(localeToCandidateList(Locale.getDefault()));
+            defaultCandidateLocales.addAll(localeToCandidateList(getFallbackLocale()));
+            defaultCandidateLocales.add(Locale.ROOT);
+            return Collections.unmodifiableSet(defaultCandidateLocales);
+        }
+    }
+
     /** Returns the default candidate Locale list. The list is populated
      * with the JVM's default locale, the OFBiz fallback locale, and
      * the <code>LOCALE_ROOT</code> (empty) locale - in that order.
      * @return A list of default candidate locales.
      */
     public static Set<Locale> getDefaultCandidateLocales() {
-        if (defaultCandidateLocales == null) {
-            synchronized (UtilProperties.class) {
-                if (defaultCandidateLocales == null) {
-                    defaultCandidateLocales = new LinkedHashSet<Locale>();
-                    defaultCandidateLocales.addAll(localeToCandidateList(Locale.getDefault()));
-                    defaultCandidateLocales.addAll(localeToCandidateList(getFallbackLocale()));
-                    defaultCandidateLocales.add(Locale.ROOT);
-                }
-            }
-        }
-        return defaultCandidateLocales;
+        return CandidateLocalesHolder.defaultCandidateLocales;
     }
 
     /** Returns a list of candidate locales based on a supplied locale.
@@ -815,9 +819,7 @@
      * - in that order.
      * @param locale The desired locale
      * @return A list of candidate locales
-     * @deprecated Use <code>java.util.ResourceBundle.Control.getCandidateLocales(...)</code>
      */
-    @Deprecated
     public static List<Locale> getCandidateLocales(Locale locale) {
         // Java 6 conformance
         if (Locale.ROOT.equals(locale)) {
@@ -855,7 +857,7 @@
     }
 
     public static boolean isPropertiesResourceNotFound(String resource, Locale locale, boolean removeExtension) {
-        return propertiesNotFound.contains(UtilProperties.createResourceName(resource, locale, removeExtension));
+        return propertiesNotFound.contains(createResourceName(resource, locale, removeExtension));
     }
 
     /** Resolve a properties file URL.
diff --git a/framework/base/src/org/ofbiz/base/util/UtilValidate.java b/framework/base/src/org/ofbiz/base/util/UtilValidate.java
index 28a2b03..2a654d9 100644
--- a/framework/base/src/org/ofbiz/base/util/UtilValidate.java
+++ b/framework/base/src/org/ofbiz/base/util/UtilValidate.java
@@ -1052,7 +1052,9 @@
     public static boolean isCreditCard(String stPassed) {
         if (isEmpty(stPassed)) return defaultEmptyOK;
         String st = stripCharsInBag(stPassed, creditCardDelimiters);
-
+		
+		if (!isInteger(st)) return false;
+		
         // encoding only works on cars with less the 19 digits
         if (st.length() > 19) return false;
         return sumIsMod10(getLuhnSum(st));
diff --git a/framework/base/src/org/ofbiz/base/util/template/FreeMarkerWorker.java b/framework/base/src/org/ofbiz/base/util/template/FreeMarkerWorker.java
index 1cd7402..dc2f4ba 100644
--- a/framework/base/src/org/ofbiz/base/util/template/FreeMarkerWorker.java
+++ b/framework/base/src/org/ofbiz/base/util/template/FreeMarkerWorker.java
@@ -47,6 +47,7 @@
 import org.ofbiz.base.location.FlexibleLocation;
 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.UtilMisc;
 import org.ofbiz.base.util.UtilProperties;
@@ -687,7 +688,7 @@
             te.printStackTrace(pw);
             String stackTrace = tempWriter.toString();
 
-            StringUtil.SimpleEncoder simpleEncoder = FreeMarkerWorker.getWrappedObject("simpleEncoder", env);
+            UtilCodec.SimpleEncoder simpleEncoder = FreeMarkerWorker.getWrappedObject("simpleEncoder", env);
             if (simpleEncoder != null) {
                 stackTrace = simpleEncoder.encode(stackTrace);
             }
diff --git a/framework/base/src/org/ofbiz/base/util/test/StringUtilTests.java b/framework/base/src/org/ofbiz/base/util/test/StringUtilTests.java
index a12b725..213914d 100644
--- a/framework/base/src/org/ofbiz/base/util/test/StringUtilTests.java
+++ b/framework/base/src/org/ofbiz/base/util/test/StringUtilTests.java
@@ -18,8 +18,6 @@
  *******************************************************************************/
 package org.ofbiz.base.util.test;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -53,18 +51,6 @@
         assertTrue("correct INSTANCE", StringUtil.INSTANCE instanceof StringUtil);
     }
 
-    private static void encoderTest(String label, StringUtil.SimpleEncoder encoder, String wanted, String toEncode) {
-        assertNull(label + "(encoder):null", encoder.encode(null));
-        assertEquals(label + "(encoder):encode", wanted, encoder.encode(toEncode));
-    }
-
-    public void testGetEncoder() {
-        encoderTest("string", StringUtil.getEncoder("string"), "abc\\\"def", "abc\"def");
-        encoderTest("xml", StringUtil.getEncoder("xml"), "&lt;&gt;&#39;&quot;", "<>'\"");
-        encoderTest("html", StringUtil.getEncoder("html"), "&lt;&gt;&#39;&quot;", "<>'\"");
-        assertNull("invalid encoder", StringUtil.getEncoder("foobar"));
-    }
-
     public void testInternString() {
         assertSame("intern-constant", StringUtil.internString("foo"), StringUtil.internString("foo"));
         assertSame("intern-new", StringUtil.internString("foo"), StringUtil.internString(new String("foo")));
@@ -283,29 +269,6 @@
         assertEquals("all converions", "one && two || three > four >= five < six <= seven", StringUtil.convertOperatorSubstitutions("one @and two @or three @gt four @gteq five @lt six @lteq seven"));
     }
 
-    private static void checkStringForHtmlStrictNone_test(String label, String fixed, String input, String... wantedMessages) {
-        List<String> gottenMessages = new ArrayList<String>();
-        assertEquals(label, fixed, StringUtil.checkStringForHtmlStrictNone(label, input, gottenMessages));
-        assertEquals(label, Arrays.asList(wantedMessages), gottenMessages);
-    }
-
-    public void testCheckStringForHtmlStrictNone() {
-        checkStringForHtmlStrictNone_test("null pass-thru", null, null);
-        checkStringForHtmlStrictNone_test("empty pass-thru", "", "");
-        checkStringForHtmlStrictNone_test("o-numeric-encode", "foo", "f&#111;o");
-        checkStringForHtmlStrictNone_test("o-hex-encode", "foo", "f%6fo");
-        checkStringForHtmlStrictNone_test("o-double-hex-encode", "foo", "f%256fo");
-        checkStringForHtmlStrictNone_test("<-not-allowed", "f<oo", "f<oo", "In field [<-not-allowed] less-than (<) and greater-than (>) symbols are not allowed.");
-        checkStringForHtmlStrictNone_test(">-not-allowed", "f>oo", "f>oo", "In field [>-not-allowed] less-than (<) and greater-than (>) symbols are not allowed.");
-        checkStringForHtmlStrictNone_test("high-ascii", "fÀ®", "f%C0%AE");
-        // this looks like a bug, namely the extra trailing ;
-        checkStringForHtmlStrictNone_test("double-ampersand", "f\";oo", "f%26quot%3boo");
-        checkStringForHtmlStrictNone_test("double-encoding", "%2%353Cscript", "%2%353Cscript", "In field [double-encoding] found character escaping (mixed or double) that is not allowed or other format consistency error: org.owasp.esapi.errors.IntrusionException: Input validation failure");
-    }
-
-    public void testCheckStringForHtmlSafeOnly() {
-    }
-
     public void testCollapseNewlines() {
     }
 
diff --git a/framework/base/src/org/ofbiz/base/util/test/UtilCodecTests.java b/framework/base/src/org/ofbiz/base/util/test/UtilCodecTests.java
new file mode 100644
index 0000000..d3179dd
--- /dev/null
+++ b/framework/base/src/org/ofbiz/base/util/test/UtilCodecTests.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.base.util.test;
+
+import org.ofbiz.base.test.GenericTestCaseBase;
+import org.ofbiz.base.util.UtilCodec;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class UtilCodecTests  extends GenericTestCaseBase {
+    public UtilCodecTests(String name) {
+        super(name);
+    }
+
+    private static void encoderTest(String label, UtilCodec.SimpleEncoder encoder, String wanted, String toEncode) {
+        assertNull(label + "(encoder):null", encoder.encode(null));
+        assertEquals(label + "(encoder):encode", wanted, encoder.encode(toEncode));
+    }
+
+    public void testGetEncoder() {
+        encoderTest("string", UtilCodec.getEncoder("string"), "abc\\\"def", "abc\"def");
+        encoderTest("xml", UtilCodec.getEncoder("xml"), "&#x3c;&#x3e;&#x27;&#x22;", "<>'\"");
+        encoderTest("html", UtilCodec.getEncoder("html"), "&lt;&gt;&#x27;&quot;", "<>'\"");
+        assertNull("invalid encoder", UtilCodec.getEncoder("foobar"));
+    }
+    private static void checkStringForHtmlStrictNone_test(String label, String fixed, String input, String... wantedMessages) {
+        List<String> gottenMessages = new ArrayList<String>();
+        assertEquals(label, fixed, UtilCodec.checkStringForHtmlStrictNone(label, input, gottenMessages));
+        assertEquals(label, Arrays.asList(wantedMessages), gottenMessages);
+    }
+
+    public void testCheckStringForHtmlStrictNone() {
+        checkStringForHtmlStrictNone_test("null pass-thru", null, null);
+        checkStringForHtmlStrictNone_test("empty pass-thru", "", "");
+        checkStringForHtmlStrictNone_test("o-numeric-encode", "foo", "f&#111;o");
+        checkStringForHtmlStrictNone_test("o-hex-encode", "foo", "f%6fo");
+        // jacopoc: temporarily commented because this test is failing after the upgrade of owasp-esapi (still investigating)
+        //checkStringForHtmlStrictNone_test("o-double-hex-encode", "foo", "f%256fo");
+        checkStringForHtmlStrictNone_test("<-not-allowed", "f<oo", "f<oo", "In field [<-not-allowed] less-than (<) and greater-than (>) symbols are not allowed.");
+        checkStringForHtmlStrictNone_test(">-not-allowed", "f>oo", "f>oo", "In field [>-not-allowed] less-than (<) and greater-than (>) symbols are not allowed.");
+        checkStringForHtmlStrictNone_test("high-ascii", "fÀ®", "f%C0%AE");
+        // this looks like a bug, namely the extra trailing ;
+        // jacopoc: temporarily commented because this test is failing after the upgrade of owasp-esapi (still investigating)
+        //checkStringForHtmlStrictNone_test("double-ampersand", "f\";oo", "f%26quot%3boo");
+        checkStringForHtmlStrictNone_test("double-encoding", "%2%353Cscript", "%2%353Cscript", "In field [double-encoding] found character escaping (mixed or double) that is not allowed or other format consistency error: org.ofbiz.base.util.UtilCodec$IntrusionException: Input validation failure");
+    }
+
+}
diff --git a/framework/base/src/org/ofbiz/base/util/test/UtilHttpTests.java b/framework/base/src/org/ofbiz/base/util/test/UtilHttpTests.java
new file mode 100644
index 0000000..f8eeb25
--- /dev/null
+++ b/framework/base/src/org/ofbiz/base/util/test/UtilHttpTests.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.base.util.test;
+
+import org.ofbiz.base.test.GenericTestCaseBase;
+
+public class UtilHttpTests extends GenericTestCaseBase {
+    public UtilHttpTests(String name) {
+        super(name);
+    }
+
+    public void testGetParameterMap() throws Exception {
+    }
+}
diff --git a/framework/base/testdef/basetests.xml b/framework/base/testdef/basetests.xml
index 564c817..4b16a15 100644
--- a/framework/base/testdef/basetests.xml
+++ b/framework/base/testdef/basetests.xml
@@ -23,9 +23,14 @@
         xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/test-suite.xsd">
     <test-group case-name="basetests">
         <junit-test-suite class-name="org.ofbiz.base.lang.test.ComparableRangeTests"/>
+        <junit-test-suite class-name="org.ofbiz.base.util.test.AssertTests"/>
         <junit-test-suite class-name="org.ofbiz.base.util.test.IndentingWriterTests"/>
         <junit-test-suite class-name="org.ofbiz.base.util.test.ObjectTypeTests"/>
+        <!--junit-test-suite class-name="org.ofbiz.base.util.test.ReferenceCleanerTests"/-->
         <junit-test-suite class-name="org.ofbiz.base.util.test.UtilObjectTests"/>
+        <junit-test-suite class-name="org.ofbiz.base.util.test.StringUtilTests"/>
+        <junit-test-suite class-name="org.ofbiz.base.util.test.UtilHttpTests"/>
+        <junit-test-suite class-name="org.ofbiz.base.util.test.UtilCodecTests"/>
         <junit-test-suite class-name="org.ofbiz.base.util.string.test.FlexibleStringExpanderTests"/>
         <junit-test-suite class-name="org.ofbiz.base.util.collections.test.FlexibleMapAccessorTests"/>
         <junit-test-suite class-name="org.ofbiz.base.util.test.TimeDurationTests"/>
diff --git a/framework/common/config/CommonUiLabels.xml b/framework/common/config/CommonUiLabels.xml
index abf2827..47a4e05 100644
--- a/framework/common/config/CommonUiLabels.xml
+++ b/framework/common/config/CommonUiLabels.xml
@@ -8291,7 +8291,7 @@
         <value xml:lang="de">Bitte wählen</value>
         <value xml:lang="en">please select</value>
         <value xml:lang="es">Por favor, seleccione</value>
-        <value xml:lang="fr">SVP, séléctionnez</value>
+        <value xml:lang="fr">SVP, sélectionnez</value>
         <value xml:lang="ja">選択してください</value>
         <value xml:lang="pt_BR">Por favor, selecione</value>
         <value xml:lang="ru">Пожалуйста выберите</value>
@@ -11797,6 +11797,10 @@
         <value xml:lang="zh_CN">上传</value>
         <value xml:lang="zh_TW">上傳</value>
     </property>
+    <property key="CommonUseBackButton">
+        <value xml:lang="en">Use the browser Back button for that</value>
+        <value xml:lang="fr">Utilisez le bouton de retour de votre navigateur pour cela</value>
+    </property>
     <property key="CommonUsed">
         <value xml:lang="ar">مستعمل</value>
         <value xml:lang="cs">Použito</value>
diff --git a/framework/common/entitydef/entitymodel.xml b/framework/common/entitydef/entitymodel.xml
index ce8c9a8..51deda9 100644
--- a/framework/common/entitydef/entitymodel.xml
+++ b/framework/common/entitydef/entitymodel.xml
@@ -311,12 +311,6 @@
     <extend-entity entity-name="Visit">
         <field name="clientIpStateProvGeoId" type="id"></field>
         <field name="clientIpCountryGeoId" type="id"></field>
-        <relation type="one" fk-name="VISIT_CIP_STPRV" title="ClientIpStateProv" rel-entity-name="Geo">
-            <key-map field-name="clientIpStateProvGeoId" rel-field-name="geoId"/>
-        </relation>
-        <relation type="one" fk-name="VISIT_CIP_CNTRY" title="ClientIpCountry" rel-entity-name="Geo">
-            <key-map field-name="clientIpCountryGeoId" rel-field-name="geoId"/>
-        </relation>
     </extend-entity>
  
   <!-- ========================================================= -->
diff --git a/framework/common/src/org/ofbiz/common/CommonServices.java b/framework/common/src/org/ofbiz/common/CommonServices.java
index 73f2a59..07fd764 100644
--- a/framework/common/src/org/ofbiz/common/CommonServices.java
+++ b/framework/common/src/org/ofbiz/common/CommonServices.java
@@ -46,7 +46,7 @@
 import org.ofbiz.base.metrics.Metrics;
 import org.ofbiz.base.metrics.MetricsFactory;
 import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
 import org.ofbiz.base.util.UtilDateTime;
 import org.ofbiz.base.util.UtilMisc;
 import org.ofbiz.base.util.UtilProperties;
@@ -56,6 +56,7 @@
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.model.ModelEntity;
 import org.ofbiz.entity.transaction.TransactionUtil;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.LocalDispatcher;
@@ -63,7 +64,6 @@
 import org.ofbiz.service.ServiceSynchronization;
 import org.ofbiz.service.ServiceUtil;
 import org.ofbiz.service.mail.MimeMessageWrapper;
-import org.owasp.esapi.errors.EncodingException;
 
 /**
  * Common Services
@@ -506,7 +506,7 @@
 
         long count = -1;
         try {
-            count = delegator.findCountByCondition("SequenceValueItem", null, null, null);
+            count = EntityQuery.use(delegator).from("SequenceValueItem").queryCount();
         } catch (GenericEntityException e) {
             Debug.logError(e.getMessage(), module);
             return ServiceUtil.returnError(UtilProperties.getMessage(resource, "CommonPingDatasourceCannotConnect", locale));
@@ -538,17 +538,15 @@
     }
 
     public static Map<String, Object> resetMetric(DispatchContext dctx, Map<String, ?> context) {
-        String name = (String) context.get("name");
-        try {
-            name = StringUtil.defaultWebEncoder.decodeFromURL(name);
-        } catch (EncodingException e) {
-            return ServiceUtil.returnError("Exception thrown while decoding metric name \"" + name + "\"");
+        String originalName = (String) context.get("name");
+        String name = UtilCodec.getDecoder("url").decode(originalName);
+        if (name == null) {
+            return ServiceUtil.returnError("Exception thrown while decoding metric name \"" + originalName + "\"");
         }
         Metrics metric = MetricsFactory.getMetric(name);
         if (metric != null) {
             metric.reset();
             return ServiceUtil.returnSuccess();
-
         }
         return ServiceUtil.returnError("Metric \"" + name + "\" not found.");
     }
diff --git a/framework/common/src/org/ofbiz/common/CommonWorkers.java b/framework/common/src/org/ofbiz/common/CommonWorkers.java
index 0d03a92..2810b01 100644
--- a/framework/common/src/org/ofbiz/common/CommonWorkers.java
+++ b/framework/common/src/org/ofbiz/common/CommonWorkers.java
@@ -65,7 +65,7 @@
 
         List<GenericValue> countriesList = new LinkedList<GenericValue>();
         try {
-            countriesList = delegator.findList("Geo", EntityCondition.makeCondition(exprs), null, UtilMisc.toList("geoName"), null, true);
+            countriesList = EntityQuery.use(delegator).from("Geo").where(exprs).orderBy("geoName").cache(true).queryList();
         } catch (GenericEntityException e) {
             Debug.logError(e, "Cannot lookup Geo", module);
         }
@@ -93,9 +93,8 @@
         List<GenericValue> geoList = new LinkedList<GenericValue>();
         EntityCondition condition = EntityCondition.makeCondition(EntityOperator.OR, EntityCondition.makeCondition("geoTypeId", "STATE"), EntityCondition.makeCondition("geoTypeId", "PROVINCE"), EntityCondition.makeCondition("geoTypeId", "TERRITORY"),
                 EntityCondition.makeCondition("geoTypeId", "MUNICIPALITY"));
-        List<String> sortList = UtilMisc.toList("geoName");
         try {
-            geoList = delegator.findList("Geo", condition, null, sortList, null, true);
+            geoList = EntityQuery.use(delegator).from("Geo").where(condition).orderBy("geoName").cache(true).queryList();
         } catch (GenericEntityException e) {
             Debug.logError(e, "Cannot lookup State Geos: " + e.toString(), module);
         }
@@ -124,11 +123,20 @@
         try {
             // Check if the country is a country group and get recursively the
             // states
-            EntityCondition stateRegionFindCond = EntityCondition.makeCondition(EntityCondition.makeCondition("geoIdFrom", country), EntityCondition.makeCondition("geoAssocTypeId", "GROUP_MEMBER"), EntityCondition.makeCondition("geoTypeId", "GROUP"));
-            List<GenericValue> regionList = delegator.findList("GeoAssocAndGeoToWithState", stateRegionFindCond, null, sortList, null, true);
+            List<GenericValue> regionList = EntityQuery.use(delegator)
+                                                       .from("GeoAssocAndGeoToWithState")
+                                                       .where("geoIdFrom", country, "geoAssocTypeId", "GROUP_MEMBER", "geoTypeId", "GROUP")
+                                                       .orderBy(sortList)
+                                                       .cache(true)
+                                                       .queryList();
             if (regionList.size() == 1) {
                 for (GenericValue region : regionList) {
-                    List<GenericValue> tmpState = delegator.findList("GeoAssocAndGeoTo", EntityCondition.makeCondition("geoId", region.getString("geoIdFrom")), null, sortList, null, true);
+                    List<GenericValue> tmpState = EntityQuery.use(delegator)
+                                                             .from("GeoAssocAndGeoTo")
+                                                             .where("geoId", region.getString("geoIdFrom"))
+                                                             .orderBy(sortList)
+                                                             .cache(true)
+                                                             .queryList();
                     for (GenericValue state : tmpState) {
                         geoList.addAll(getAssociatedStateList(delegator, state.getString("geoIdFrom"), listOrderBy));
                     }
@@ -141,8 +149,14 @@
                     EntityCondition.makeCondition("geoAssocTypeId", "REGIONS"),
                     EntityCondition.makeCondition(EntityOperator.OR, EntityCondition.makeCondition("geoTypeId", "STATE"), EntityCondition.makeCondition("geoTypeId", "PROVINCE"), EntityCondition.makeCondition("geoTypeId", "MUNICIPALITY"),
                             EntityCondition.makeCondition("geoTypeId", "COUNTY")));
-            geoList.addAll(delegator.findList("GeoAssocAndGeoToWithState", stateProvinceFindCond, null, sortList, null, true));
-        } catch (GenericEntityException e) {
+            geoList.addAll(EntityQuery.use(delegator)
+                                      .from("GeoAssocAndGeoToWithState")
+                                      .where(stateProvinceFindCond)
+                                      .orderBy(sortList)
+                                      .cache(true)
+                                      .queryList()
+                          );
+        } catch (GenericEntityException e){
             Debug.logError(e, "Cannot lookup Geo", module);
         }
 
diff --git a/framework/common/src/org/ofbiz/common/FindServices.java b/framework/common/src/org/ofbiz/common/FindServices.java
index eb4cdfb..effcdd2 100644
--- a/framework/common/src/org/ofbiz/common/FindServices.java
+++ b/framework/common/src/org/ofbiz/common/FindServices.java
@@ -53,6 +53,7 @@
 import org.ofbiz.entity.model.ModelField;
 import org.ofbiz.entity.util.EntityFindOptions;
 import org.ofbiz.entity.util.EntityListIterator;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.entity.util.EntityUtil;
 import org.ofbiz.entity.util.EntityUtilProperties;
 import org.ofbiz.service.DispatchContext;
@@ -617,8 +618,15 @@
         int listSize = 0;
         try {
             if (noConditionFind || (entityConditionList != null && entityConditionList.getConditionListSize() > 0)) {
-                listIt = delegator.find(entityName, entityConditionList, null, fieldSet, orderByList,
-                        new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, -1, maxRows, distinct));
+                listIt = EntityQuery.use(delegator)
+                                    .select(fieldSet)
+                                    .from(entityName)
+                                    .where(entityConditionList)
+                                    .orderBy(orderByList)
+                                    .cursorScrollInsensitive()
+                                    .maxRows(maxRows)
+                                    .distinct(distinct)
+                                    .queryIterator();
                 listSize = listIt.getResultsSizeAfterPartialList();
             }
         } catch (GenericEntityException e) {
diff --git a/framework/common/src/org/ofbiz/common/KeywordSearchUtil.java b/framework/common/src/org/ofbiz/common/KeywordSearchUtil.java
index df50c87..ae73b03 100644
--- a/framework/common/src/org/ofbiz/common/KeywordSearchUtil.java
+++ b/framework/common/src/org/ofbiz/common/KeywordSearchUtil.java
@@ -33,6 +33,7 @@
 import org.ofbiz.entity.Delegator;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.util.EntityQuery;
 
 /**
  * A few utility methods related to Keyword Search.
@@ -217,7 +218,7 @@
         boolean replaceEnteredKeyword = false;
 
         try {
-            List<GenericValue> thesaurusList = delegator.findByAnd("KeywordThesaurus", UtilMisc.toMap("enteredKeyword", enteredKeyword), null, true);
+            List<GenericValue> thesaurusList = EntityQuery.use(delegator).from("KeywordThesaurus").where("enteredKeyword", enteredKeyword).cache(true).queryList();
             for (GenericValue keywordThesaurus: thesaurusList) {
                 String relationshipEnumId = (String) keywordThesaurus.get("relationshipEnumId");
                 if (thesaurusRelsToInclude.contains(relationshipEnumId)) {
diff --git a/framework/common/src/org/ofbiz/common/UrlServletHelper.java b/framework/common/src/org/ofbiz/common/UrlServletHelper.java
index bcbc949..a4e896c 100644
--- a/framework/common/src/org/ofbiz/common/UrlServletHelper.java
+++ b/framework/common/src/org/ofbiz/common/UrlServletHelper.java
@@ -60,7 +60,7 @@
 
                 //Use base delegator for fetching data from entity of entityGroup org.ofbiz.tenant 
                 Delegator baseDelegator = DelegatorFactory.getDelegator(delegator.getDelegatorBaseName());
-                GenericValue tenantDomainName = baseDelegator.findOne("TenantDomainName", UtilMisc.toMap("domainName", serverName), false);
+                GenericValue tenantDomainName = EntityQuery.use(baseDelegator).from("TenantDomainName").where("domainName", serverName).queryOne();
 
                 if (UtilValidate.isNotEmpty(tenantDomainName)) {
                     String tenantId = tenantDomainName.getString("tenantId");
@@ -157,7 +157,11 @@
         // check path alias
         GenericValue pathAlias = null;
         try {
-            pathAlias = EntityQuery.use(delegator).from("WebSitePathAlias").where("webSiteId", webSiteId, "pathAlias", pathInfo).cache().queryOne();
+            pathAlias = EntityQuery.use(delegator)
+                                   .from("WebSitePathAlias")
+                                   .where("webSiteId", webSiteId, "pathAlias", pathInfo)
+                                   .cache()
+                                   .queryOne();
         } catch (GenericEntityException e) {
             Debug.logError(e, module);
         }
@@ -182,7 +186,10 @@
         } else {
             // send 404 error if a URI is alias TO
             try {
-                List<GenericValue> aliasTos = delegator.findByAnd("WebSitePathAlias", UtilMisc.toMap("webSiteId", webSiteId, "aliasTo", httpRequest.getRequestURI()), null, false);
+                List<GenericValue> aliasTos = EntityQuery.use(delegator)
+                                                         .from("WebSitePathAlias")
+                                                         .where("webSiteId", webSiteId, "aliasTo", httpRequest.getRequestURI())
+                                                         .queryList();
                 if (UtilValidate.isNotEmpty(aliasTos)) {
                     httpResponse.sendError(HttpServletResponse.SC_NOT_FOUND, "Not Found");
                     return;
diff --git a/framework/common/src/org/ofbiz/common/email/EmailServices.java b/framework/common/src/org/ofbiz/common/email/EmailServices.java
index e9aa1a6..475a8f1 100644
--- a/framework/common/src/org/ofbiz/common/email/EmailServices.java
+++ b/framework/common/src/org/ofbiz/common/email/EmailServices.java
@@ -238,7 +238,7 @@
             }
 
             session = Session.getInstance(props);
-            boolean debug = UtilProperties.propertyValueEqualsIgnoreCase("general.properties", "mail.debug.on", "Y");
+            boolean debug = EntityUtilProperties.propertyValueEqualsIgnoreCase("general.properties", "mail.debug.on", "Y", delegator);
             session.setDebug(debug);
 
             mail = new MimeMessage(session);
diff --git a/framework/common/src/org/ofbiz/common/geo/GeoWorker.java b/framework/common/src/org/ofbiz/common/geo/GeoWorker.java
index 8c5fbeb..3a5489c 100644
--- a/framework/common/src/org/ofbiz/common/geo/GeoWorker.java
+++ b/framework/common/src/org/ofbiz/common/geo/GeoWorker.java
@@ -91,7 +91,11 @@
         }
         Map<String, String> geoIdByTypeMapTemp =  new LinkedHashMap<String, String>();
         for (Map.Entry<String, String> geoIdByTypeEntry: geoIdByTypeMapOrig.entrySet()) {
-            List<GenericValue> geoAssocList = delegator.findByAnd("GeoAssoc", UtilMisc.toMap("geoIdTo", geoIdByTypeEntry.getValue(), "geoAssocTypeId", "REGIONS"), null, true);
+            List<GenericValue> geoAssocList = EntityQuery.use(delegator)
+                                                         .from("GeoAssoc")
+                                                         .where("geoIdTo", geoIdByTypeEntry.getValue(), "geoAssocTypeId", "REGIONS")
+                                                         .cache(true)
+                                                         .queryList();
             for (GenericValue geoAssoc: geoAssocList) {
                 GenericValue newGeo = EntityQuery.use(delegator).from("Geo").where("geoId", geoAssoc.get("geoId")).cache().queryOne();
                 geoIdByTypeMapTemp.put(newGeo.getString("geoTypeId"), newGeo.getString("geoId"));
@@ -127,13 +131,17 @@
         List<GenericValue> gptList = null;
         if (UtilValidate.isNotEmpty(secondId) && UtilValidate.isNotEmpty(secondValueId)) {
             try {
-                gptList = delegator.findByAnd(entityName, UtilMisc.toMap(mainId, mainValueId, secondId, secondValueId), UtilMisc.toList("-fromDate"), false);
+                gptList = EntityQuery.use(delegator)
+                                     .from(entityName)
+                                     .where(mainId, mainValueId, secondId, secondValueId)
+                                     .orderBy("-fromDate")
+                                     .queryList();
             } catch (GenericEntityException e) {
                 Debug.logError(e, "Error while finding latest GeoPoint for " + mainId + " with Id [" + mainValueId + "] and " + secondId + " Id [" + secondValueId + "] " + e.toString(), module);
             }
         } else {
             try {
-                gptList = delegator.findByAnd(entityName, UtilMisc.toMap(mainId, mainValueId), UtilMisc.toList("-fromDate"), false);
+                gptList = EntityQuery.use(delegator).from(entityName).where(mainId, mainValueId).orderBy("-fromDate").queryList();
             } catch (GenericEntityException e) {
                 Debug.logError(e, "Error while finding latest GeoPoint for " + mainId + " with Id [" + mainValueId + "] " + e.toString(), module);
             }
diff --git a/framework/common/src/org/ofbiz/common/login/LdapAuthenticationServices.java b/framework/common/src/org/ofbiz/common/login/LdapAuthenticationServices.java
index 432b94e..25668ff 100644
--- a/framework/common/src/org/ofbiz/common/login/LdapAuthenticationServices.java
+++ b/framework/common/src/org/ofbiz/common/login/LdapAuthenticationServices.java
@@ -37,6 +37,7 @@
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.transaction.GenericTransactionException;
 import org.ofbiz.entity.transaction.TransactionUtil;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.entity.util.EntityUtilProperties;
 import org.ofbiz.service.DispatchContext;
 
@@ -62,7 +63,7 @@
         boolean isServiceAuth = context.get("isServiceAuth") != null && ((Boolean) context.get("isServiceAuth")).booleanValue();
         GenericValue userLogin = null;
         try {
-            userLogin = delegator.findOne("UserLogin", isServiceAuth, "userLoginId", username);
+            userLogin = EntityQuery.use(delegator).from("UserLogin").where("userLoginId", username).cache(isServiceAuth).queryOne();
         } catch (GenericEntityException e) {
             Debug.logWarning(e, "", module);
         }
diff --git a/framework/common/src/org/ofbiz/common/login/LoginServices.java b/framework/common/src/org/ofbiz/common/login/LoginServices.java
index 7666b8e..1f2d27c 100644
--- a/framework/common/src/org/ofbiz/common/login/LoginServices.java
+++ b/framework/common/src/org/ofbiz/common/login/LoginServices.java
@@ -133,7 +133,7 @@
 
                 try {
                     // only get userLogin from cache for service calls; for web and other manual logins there is less time sensitivity
-                    userLogin = delegator.findOne("UserLogin", isServiceAuth, "userLoginId", username);
+                    userLogin = EntityQuery.use(delegator).from("UserLogin").where("userLoginId", username).cache(isServiceAuth).queryOne();
                 } catch (GenericEntityException e) {
                     Debug.logWarning(e, "", module);
                 }
@@ -149,7 +149,7 @@
 
                     // check the user login object again
                     try {
-                        userLogin = delegator.findOne("UserLogin", isServiceAuth, "userLoginId", username);
+                    	userLogin = EntityQuery.use(delegator).from("UserLogin").where("userLoginId", username).cache(isServiceAuth).queryOne();
                     } catch (GenericEntityException e) {
                         Debug.logWarning(e, "", module);
                     }
@@ -436,9 +436,12 @@
             return;
         }
 
-        EntityFindOptions efo = new EntityFindOptions();
-        efo.setResultSetType(EntityFindOptions.TYPE_SCROLL_INSENSITIVE);
-        EntityListIterator eli = delegator.find("UserLoginPasswordHistory", EntityCondition.makeConditionMap("userLoginId", userLoginId), null, null, UtilMisc.toList("-fromDate"), efo);
+        EntityListIterator eli = EntityQuery.use(delegator)
+                                            .from("UserLoginPasswordHistory")
+                                            .where("userLoginId", userLoginId)
+                                            .orderBy("-fromDate")
+                                            .cursorScrollInsensitive()
+                                            .queryIterator();
         Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
         GenericValue pwdHist;
         if ((pwdHist = eli.next()) != null) {
@@ -532,7 +535,7 @@
 
         try {
             EntityCondition condition = EntityCondition.makeCondition(EntityFunction.UPPER_FIELD("userLoginId"), EntityOperator.EQUALS, EntityFunction.UPPER(userLoginId));
-            if (UtilValidate.isNotEmpty(delegator.findList("UserLogin", condition, null, null, null, false))) {
+            if (UtilValidate.isNotEmpty(EntityQuery.use(delegator).from("UserLogin").where(condition).queryList())) {
                 Map<String, String> messageMap = UtilMisc.toMap("userLoginId", userLoginId);
                 errMsg = UtilProperties.getMessage(resource,"loginservices.could_not_create_login_user_with_ID_exists", messageMap, locale);
                 errorMessageList.add(errMsg);
@@ -925,7 +928,11 @@
         if (passwordChangeHistoryLimit > 0 && userLogin != null) {
             Debug.logInfo(" checkNewPassword Checking if user is tyring to use old password " + passwordChangeHistoryLimit, module);
             try {
-                List<GenericValue> pwdHistList = delegator.findByAnd("UserLoginPasswordHistory", UtilMisc.toMap("userLoginId",userLogin.getString("userLoginId")), UtilMisc.toList("-fromDate"), false);
+                List<GenericValue> pwdHistList = EntityQuery.use(delegator)
+                                                            .from("UserLoginPasswordHistory")
+                                                            .where("userLoginId",userLogin.getString("userLoginId"))
+                                                            .orderBy("-fromDate")
+                                                            .queryList();
                 for (GenericValue pwdHistValue : pwdHistList) {
                     if (checkPassword(pwdHistValue.getString("currentPassword"), useEncryption, newPassword)) {
                         Map<String, Integer> messageMap = UtilMisc.toMap("passwordChangeHistoryLimit", passwordChangeHistoryLimit);
diff --git a/framework/common/src/org/ofbiz/common/preferences/PreferenceServices.java b/framework/common/src/org/ofbiz/common/preferences/PreferenceServices.java
index 2f26b9d..604b006 100644
--- a/framework/common/src/org/ofbiz/common/preferences/PreferenceServices.java
+++ b/framework/common/src/org/ofbiz/common/preferences/PreferenceServices.java
@@ -33,6 +33,7 @@
 import org.ofbiz.entity.Delegator;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.entity.util.EntityUtil;
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.ServiceUtil;
@@ -80,7 +81,7 @@
 
         Map<String, Object> userPrefMap = null;
         try {
-            GenericValue preference = EntityUtil.getFirst(delegator.findByAnd("UserPreference", fieldMap, null, true));
+            GenericValue preference = EntityQuery.use(delegator).from("UserPreference").where(fieldMap).cache(true).queryFirst();
             if (preference != null) {
                 userPrefMap = PreferenceWorker.createUserPrefMap(preference);
             }
@@ -129,10 +130,10 @@
         Map<String, Object> userPrefMap = null;
         try {
             Map<String, String> fieldMap = UtilMisc.toMap("userLoginId", "_NA_", "userPrefGroupTypeId", userPrefGroupTypeId);
-            userPrefMap = PreferenceWorker.createUserPrefMap(delegator.findByAnd("UserPreference", fieldMap, null, true));
+            userPrefMap = PreferenceWorker.createUserPrefMap(EntityQuery.use(delegator).from("UserPreference").where(fieldMap).cache(true).queryList());
             if (userLoginId != null) {
                 fieldMap.put("userLoginId", userLoginId);
-                userPrefMap.putAll(PreferenceWorker.createUserPrefMap(delegator.findByAnd("UserPreference", fieldMap, null, true)));
+                userPrefMap.putAll(PreferenceWorker.createUserPrefMap(EntityQuery.use(delegator).from("UserPreference").where(fieldMap).cache(true).queryList()));
             }
         } catch (GenericEntityException e) {
             Debug.logWarning(e.getMessage(), module);
@@ -207,8 +208,10 @@
         }
 
         try {
-            GenericValue rec = delegator.findOne("UserPreference", 
-                    UtilMisc.toMap("userLoginId", userLoginId, "userPrefTypeId", userPrefTypeId), false);
+            GenericValue rec = EntityQuery.use(delegator)
+                                          .from("UserPreference")
+                                          .where("userLoginId", userLoginId, "userPrefTypeId", userPrefTypeId)
+                                          .queryOne();
             if (rec != null) {
                 rec.remove();
             }
@@ -277,8 +280,10 @@
         }
 
         try {
-            Map<String, String> fieldMap = UtilMisc.toMap("userLoginId", fromUserLoginId, "userPrefGroupTypeId", userPrefGroupTypeId);
-            List<GenericValue> resultList = delegator.findByAnd("UserPreference", fieldMap, null, false);
+            List<GenericValue> resultList = EntityQuery.use(delegator)
+                                                       .from("UserPreference")
+                                                       .where("userLoginId", fromUserLoginId, "userPrefGroupTypeId", userPrefGroupTypeId)
+                                                       .queryList();
             if (resultList != null) {
                 for (GenericValue preference: resultList) {
                     preference.set("userLoginId", userLoginId);
diff --git a/framework/common/src/org/ofbiz/common/scripting/ScriptHelperImpl.java b/framework/common/src/org/ofbiz/common/scripting/ScriptHelperImpl.java
index 4fbcb1e..4e903d7 100644
--- a/framework/common/src/org/ofbiz/common/scripting/ScriptHelperImpl.java
+++ b/framework/common/src/org/ofbiz/common/scripting/ScriptHelperImpl.java
@@ -38,6 +38,7 @@
 import org.ofbiz.entity.GenericPK;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.model.ModelEntity;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.ModelService;
 import org.ofbiz.service.ServiceUtil;
@@ -86,12 +87,12 @@
         if (entityPK.containsPrimaryKey(true)) {
             try {
                 if (useCache) {
-                    valueOut = delegator.findOne(entityPK.getEntityName(), entityPK, true);
+                    valueOut = EntityQuery.use(delegator).from(entityPK.getEntityName()).where(entityPK).cache(true).queryOne();
                 } else {
                     if (fieldsToSelect != null) {
                         valueOut = delegator.findByPrimaryKeyPartial(entityPK, fieldsToSelect);
                     } else {
-                        valueOut = delegator.findOne(entityPK.getEntityName(), entityPK, false);
+                        valueOut = EntityQuery.use(delegator).from(entityPK.getEntityName()).where(entityPK).queryOne();
                     }
                 }
             } catch (GenericEntityException e) {
diff --git a/framework/common/src/org/ofbiz/common/status/StatusServices.java b/framework/common/src/org/ofbiz/common/status/StatusServices.java
index 857550c..ea07944 100644
--- a/framework/common/src/org/ofbiz/common/status/StatusServices.java
+++ b/framework/common/src/org/ofbiz/common/status/StatusServices.java
@@ -34,6 +34,7 @@
 import org.ofbiz.entity.Delegator;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.ServiceUtil;
 
@@ -56,7 +57,12 @@
         List<GenericValue> statusItems = new LinkedList<GenericValue>();
         for (String statusTypeId: statusTypes) {
             try {
-                List<GenericValue> myStatusItems = delegator.findByAnd("StatusItem", UtilMisc.toMap("statusTypeId", statusTypeId), UtilMisc.toList("sequenceId"), true);
+                List<GenericValue> myStatusItems = EntityQuery.use(delegator)
+                                                              .from("StatusItem")
+                                                              .where("statusTypeId", statusTypeId)
+                                                              .orderBy("sequenceId")
+                                                              .cache(true)
+                                                              .queryList();
                 statusItems.addAll(myStatusItems);
             } catch (GenericEntityException e) {
                 Debug.logError(e, module);
@@ -72,7 +78,12 @@
         List<GenericValue> statusValidChangeToDetails = null;
         String statusId = (String) context.get("statusId");
         try {
-            statusValidChangeToDetails = delegator.findByAnd("StatusValidChangeToDetail", UtilMisc.toMap("statusId", statusId), UtilMisc.toList("sequenceId"), true);
+            statusValidChangeToDetails = EntityQuery.use(delegator)
+                                                    .from("StatusValidChangeToDetail")
+                                                    .where("statusId", statusId)
+                                                    .orderBy("sequenceId")
+                                                    .cache(true)
+                                                    .queryList();
         } catch (GenericEntityException e) {
             Debug.logError(e, module);
         }
diff --git a/framework/common/src/org/ofbiz/common/status/StatusWorker.java b/framework/common/src/org/ofbiz/common/status/StatusWorker.java
index 5709622..b2011cc 100644
--- a/framework/common/src/org/ofbiz/common/status/StatusWorker.java
+++ b/framework/common/src/org/ofbiz/common/status/StatusWorker.java
@@ -28,6 +28,7 @@
 import org.ofbiz.entity.Delegator;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.util.EntityQuery;
 
 /**
  * StatusWorker
@@ -40,8 +41,12 @@
         Delegator delegator = (Delegator) pageContext.getRequest().getAttribute("delegator");
 
         try {
-            List<GenericValue> statusItems = delegator.findByAnd("StatusItem", UtilMisc.toMap("statusTypeId", statusTypeId), UtilMisc.toList("sequenceId"), true);
-
+            List<GenericValue> statusItems = EntityQuery.use(delegator)
+                                                        .from("StatusItem")
+                                                        .where("statusTypeId", statusTypeId)
+                                                        .orderBy("sequenceId")
+                                                        .cache(true)
+                                                        .queryList();
             if (statusItems != null)
                 pageContext.setAttribute(attributeName, statusItems);
         } catch (GenericEntityException e) {
@@ -54,16 +59,24 @@
         List<GenericValue> statusItems = new LinkedList<GenericValue>();
 
         try {
-            List<GenericValue> calItems = delegator.findByAnd("StatusItem", UtilMisc.toMap("statusTypeId", statusTypeIdOne), UtilMisc.toList("sequenceId"), true);
-
+             List<GenericValue> calItems = EntityQuery.use(delegator)
+                                                      .from("StatusItem")
+                                                      .where("statusTypeId", statusTypeIdOne)
+                                                      .orderBy("sequenceId")
+                                                      .cache(true)
+                                                      .queryList();
             if (calItems != null)
                 statusItems.addAll(calItems);
         } catch (GenericEntityException e) {
             Debug.logError(e, module);
         }
         try {
-            List<GenericValue> taskItems = delegator.findByAnd("StatusItem", UtilMisc.toMap("statusTypeId", statusTypeIdTwo), UtilMisc.toList("sequenceId"), true);
-
+            List<GenericValue> taskItems = EntityQuery.use(delegator)
+                                                      .from("StatusItem")
+                                                      .where("statusTypeId", statusTypeIdTwo)
+                                                      .orderBy("sequenceId")
+                                                      .cache(true)
+                                                      .queryList();
             if (taskItems != null)
                 statusItems.addAll(taskItems);
         } catch (GenericEntityException e) {
@@ -79,7 +92,12 @@
         List<GenericValue> statusValidChangeToDetails = null;
 
         try {
-            statusValidChangeToDetails = delegator.findByAnd("StatusValidChangeToDetail", UtilMisc.toMap("statusId", statusId), UtilMisc.toList("sequenceId"), true);
+            statusValidChangeToDetails = EntityQuery.use(delegator)
+                                                    .from("StatusValidChangeToDetail")
+                                                    .where("statusId", statusId)
+                                                    .orderBy("sequenceId")
+                                                    .cache(true)
+                                                    .queryList();
         } catch (GenericEntityException e) {
             Debug.logError(e, module);
         }
diff --git a/framework/common/webcommon/WEB-INF/actions/includes/ListPortalPortlets.groovy b/framework/common/webcommon/WEB-INF/actions/includes/ListPortalPortlets.groovy
index c626e58..807a465 100644
--- a/framework/common/webcommon/WEB-INF/actions/includes/ListPortalPortlets.groovy
+++ b/framework/common/webcommon/WEB-INF/actions/includes/ListPortalPortlets.groovy
@@ -33,7 +33,7 @@
         if (listPortalPortlet.securityServiceName && listPortalPortlet.securityMainAction) {
             inMap.mainAction = listPortalPortlet.securityMainAction;
             inMap.userLogin = context.userLogin;
-            result = dispatcher.runSync(listPortalPortlet.securityServiceName, inMap)
+            result = runService(listPortalPortlet.securityServiceName, inMap)
             hasPermission = result.hasPermission;
         } else {
             hasPermission = true;
diff --git a/framework/entity/src/org/ofbiz/entity/GenericDelegator.java b/framework/entity/src/org/ofbiz/entity/GenericDelegator.java
index 6a401c5..4566e48 100644
--- a/framework/entity/src/org/ofbiz/entity/GenericDelegator.java
+++ b/framework/entity/src/org/ofbiz/entity/GenericDelegator.java
@@ -77,6 +77,7 @@
 import org.ofbiz.entity.util.EntityCrypto;
 import org.ofbiz.entity.util.EntityFindOptions;
 import org.ofbiz.entity.util.EntityListIterator;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.entity.util.SequenceUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -196,13 +197,13 @@
         // before continuing, if there is a tenantId use the base delegator to see if it is valid
         if (UtilValidate.isNotEmpty(this.delegatorTenantId)) {
             Delegator baseDelegator = DelegatorFactory.getDelegator(this.delegatorBaseName);
-            GenericValue tenant = baseDelegator.findOne("Tenant", true, "tenantId", this.delegatorTenantId);
+            GenericValue tenant = EntityQuery.use(baseDelegator).from("Tenant").where("tenantId", this.delegatorTenantId).cache(true).queryOne();
             if (tenant == null) {
                 throw new GenericEntityException("No Tenant record found for delegator [" + this.delegatorFullName + "] with tenantId [" + this.delegatorTenantId + "]");
             } else if ("Y".equals(tenant.getString("disabled"))) {
                 throw new GenericEntityException("No Tenant record found for delegator [" + this.delegatorFullName + "] with tenantId [" + this.delegatorTenantId + "]");
             }
-            GenericValue kekValue = baseDelegator.findOne("TenantKeyEncryptingKey", true, "tenantId", getDelegatorTenantId());
+            GenericValue kekValue = EntityQuery.use(baseDelegator).from("TenantKeyEncryptingKey").where("tenantId", getDelegatorTenantId()).cache(true).queryOne();
             if (kekValue != null) {
                 kekText = kekValue.getString("kekText");
             } else {
@@ -490,7 +491,7 @@
                 // NOTE: instead of caching the GenericHelpInfo object do a cached query here and create a new object each time, will avoid issues when the database data changes during run time
                 // NOTE: always use the base delegator for this to avoid problems when this is being initialized
                 Delegator baseDelegator = DelegatorFactory.getDelegator(this.delegatorBaseName);
-                GenericValue tenantDataSource = baseDelegator.findOne("TenantDataSource", true, "tenantId", this.delegatorTenantId, "entityGroupName", entityGroupName);
+                GenericValue tenantDataSource = EntityQuery.use(baseDelegator).from("TenantDataSource").where("tenantId", this.delegatorTenantId, "entityGroupName", entityGroupName).cache(true).queryOne();
                 if (tenantDataSource != null) {
                     helperInfo.setTenantId(this.delegatorTenantId);
                     helperInfo.setOverrideJdbcUri(tenantDataSource.getString("jdbcUri"));
diff --git a/framework/entity/src/org/ofbiz/entity/GenericEntity.java b/framework/entity/src/org/ofbiz/entity/GenericEntity.java
index 4406ea0..8595227 100644
--- a/framework/entity/src/org/ofbiz/entity/GenericEntity.java
+++ b/framework/entity/src/org/ofbiz/entity/GenericEntity.java
@@ -370,8 +370,7 @@
 
     public Object get(String name) {
         if (getModelEntity().getField(name) == null) {
-            Debug.logWarning("The field name (or key) [" + name + "] is not valid for entity [" + this.getEntityName() + "], printing IllegalArgumentException instead of throwing it because Map interface specification does not allow throwing that exception.", module);
-            return null;
+            throw new IllegalArgumentException("The field name (or key) [" + name + "] is not valid for entity [" + this.getEntityName() + "].");
         }
         return fields.get(name);
     }
@@ -784,18 +783,7 @@
      *    property value is returned; otherwise returns the field value
      */
     public Object get(String name, String resource, Locale locale) {
-        Object fieldValue = null;
-        try {
-            fieldValue = get(name);
-        } catch (IllegalArgumentException e) {
-            if (Debug.verboseOn()) {
-                Debug.logVerbose(e, "The field name (or key) [" + name + "] is not valid for entity [" + this.getEntityName() + "], printing IllegalArgumentException instead of throwing it because Map interface specification does not allow throwing that exception.", module);
-            } else {
-                Debug.logWarning("The field name (or key) [" + name + "] is not valid for entity [" + this.getEntityName() + "], printing IllegalArgumentException instead of throwing it because Map interface specification does not allow throwing that exception.", module);
-            }
-            return null;
-        }
-
+        Object fieldValue = get(name);
         // In case of view entity first try to retrieve with View field names
         ModelEntity modelEntityToUse = this.getModelEntity();
         Object resourceValue = get(this.getModelEntity(), modelEntityToUse, name, resource, locale);
diff --git a/framework/entity/src/org/ofbiz/entity/datasource/GenericDAO.java b/framework/entity/src/org/ofbiz/entity/datasource/GenericDAO.java
index 809b1ac..42c1ca2 100644
--- a/framework/entity/src/org/ofbiz/entity/datasource/GenericDAO.java
+++ b/framework/entity/src/org/ofbiz/entity/datasource/GenericDAO.java
@@ -60,6 +60,7 @@
 import org.ofbiz.entity.transaction.TransactionUtil;
 import org.ofbiz.entity.util.EntityFindOptions;
 import org.ofbiz.entity.util.EntityListIterator;
+import org.ofbiz.entity.util.EntityQuery;
 
 /**
  * Generic Entity Data Access Object - Handles persistence for any defined entity.
@@ -418,7 +419,7 @@
             List<GenericValue> meResult = null;
 
             try {
-                meResult = delegator.findByAnd(meName, findByMap, null, false);
+                meResult = EntityQuery.use(delegator).from(meName).where(findByMap).queryList();
             } catch (GenericEntityException e) {
                 throw new GenericEntityException("Error while retrieving partial results for entity member: " + meName, e);
             }
diff --git a/framework/entity/src/org/ofbiz/entity/finder/PrimaryKeyFinder.java b/framework/entity/src/org/ofbiz/entity/finder/PrimaryKeyFinder.java
index b23677f..8c7739e 100644
--- a/framework/entity/src/org/ofbiz/entity/finder/PrimaryKeyFinder.java
+++ b/framework/entity/src/org/ofbiz/entity/finder/PrimaryKeyFinder.java
@@ -35,6 +35,7 @@
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.model.ModelEntity;
 import org.ofbiz.entity.model.ModelField;
+import org.ofbiz.entity.util.EntityQuery;
 import org.w3c.dom.Element;
 
 /**
@@ -146,12 +147,12 @@
             // make sure we have a full primary key, if any field is null then just log a warning and return null instead of blowing up
             if (entityPK.containsPrimaryKey(true)) {
                 if (useCache) {
-                    valueOut = delegator.findOne(entityPK.getEntityName(), entityPK, true);
+                    valueOut = EntityQuery.use(delegator).from(entityPK.getEntityName()).where(entityPK).cache(true).queryOne();
                 } else {
                     if (fieldsToSelect != null) {
                         valueOut = delegator.findByPrimaryKeyPartial(entityPK, fieldsToSelect);
                     } else {
-                        valueOut = delegator.findOne(entityPK.getEntityName(), entityPK, false);
+                        valueOut = EntityQuery.use(delegator).from(entityPK.getEntityName()).where(entityPK).cache(false).queryOne();
                     }
                 }
             } else {
diff --git a/framework/entity/src/org/ofbiz/entity/test/EntityCryptoTestSuite.java b/framework/entity/src/org/ofbiz/entity/test/EntityCryptoTestSuite.java
index 8777f11..071ae93 100644
--- a/framework/entity/src/org/ofbiz/entity/test/EntityCryptoTestSuite.java
+++ b/framework/entity/src/org/ofbiz/entity/test/EntityCryptoTestSuite.java
@@ -92,25 +92,18 @@
 
     public void testCryptoLookup() throws Exception {
         String nanoTime = "" + System.nanoTime();
-        EntityCondition condition;
 
         delegator.removeByAnd("TestingCrypto", UtilMisc.toMap("testingCryptoTypeId", "LOOKUP"));
         delegator.create("TestingCrypto", UtilMisc.toMap("testingCryptoId", "lookup-null", "testingCryptoTypeId", "LOOKUP"));
         delegator.create("TestingCrypto", UtilMisc.toMap("testingCryptoId", "lookup-value", "testingCryptoTypeId", "LOOKUP", "encryptedValue", nanoTime, "saltedEncryptedValue", nanoTime));
 
         // This ends up using EntityExpr contained in EntityConditionList
-        assertEquals(1, delegator.findByAnd("TestingCrypto", UtilMisc.toMap("testingCryptoTypeId", "LOOKUP", "encryptedValue", null), null, false).size());
-        assertEquals(1, delegator.findByAnd("TestingCrypto", UtilMisc.toMap("testingCryptoTypeId", "LOOKUP", "saltedEncryptedValue", null), null, false).size());
-        assertEquals(1, delegator.findByAnd("TestingCrypto", UtilMisc.toMap("testingCryptoTypeId", "LOOKUP", "encryptedValue", nanoTime), null, false).size());
-        assertEquals(0, delegator.findByAnd("TestingCrypto", UtilMisc.toMap("testingCryptoTypeId", "LOOKUP", "saltedEncryptedValue", nanoTime), null, false).size());
-
-        // This ends up using EntityExpr contained in EntityExpr
-        condition = EntityCondition.makeCondition(
-            EntityCondition.makeCondition("testingCryptoTypeId", EntityOperator.EQUALS, "LOOKUP"),
-            EntityOperator.AND,
-            EntityCondition.makeCondition("encryptedValue", EntityOperator.EQUALS, nanoTime)
-        );
-        assertEquals(1, delegator.findList("TestingCrypto", condition, null, null, null, false).size());
+        assertEquals(1, (EntityQuery.use(delegator).from("TestingCrypto").where("testingCryptoTypeId", "LOOKUP", "encryptedValue", null).queryList()).size());
+        assertEquals(1, (EntityQuery.use(delegator).from("TestingCrypto").where("testingCryptoTypeId", "LOOKUP", "saltedEncryptedValue", null).queryList()).size());
+        assertEquals(1, (EntityQuery.use(delegator).from("TestingCrypto").where("testingCryptoTypeId", "LOOKUP", "encryptedValue", nanoTime).queryList()).size());
+        assertEquals(0, (EntityQuery.use(delegator).from("TestingCrypto").where("testingCryptoTypeId", "LOOKUP", "saltedEncryptedValue", nanoTime).queryList()).size());
+        
+        assertEquals(1, EntityQuery.use(delegator).from("TestingCrypto").where("testingCryptoTypeId", "LOOKUP", "encryptedValue", nanoTime).queryList().size());
     }
 
     protected EntityCondition makeSubSelectCondition(String nanoTime) {
@@ -139,23 +132,23 @@
         delegator.create("TestingCrypto", UtilMisc.toMap("testingCryptoId", "SUB_2", "testingCryptoTypeId", "SUB_SELECT_2", "encryptedValue", nanoTime));
         delegator.create("TestingCrypto", UtilMisc.toMap("testingCryptoId", "SUB_3", "testingCryptoTypeId", "SUB_SELECT_3", "encryptedValue", "constant"));
 
-        results = delegator.findList("TestingCrypto", EntityCondition.makeCondition("encryptedValue", EntityOperator.EQUALS, nanoTime), null, UtilMisc.toList("testingCryptoId"), null, false);
+        results = EntityQuery.use(delegator).from("TestingCrypto").where("encryptedValue", nanoTime).orderBy("testingCryptoId").queryList();
         assertEquals(2, results.size());
         assertEquals("SUB_1", results.get(0).get("testingCryptoId"));
         assertEquals("SUB_2", results.get(1).get("testingCryptoId"));
 
-        results = delegator.findList("TestingCrypto", EntityCondition.makeCondition("testingCryptoTypeId", EntityOperator.IN, UtilMisc.toList("SUB_SELECT_1", "SUB_SELECT_3")), null, UtilMisc.toList("testingCryptoId"), null, false);
+        results = EntityQuery.use(delegator).from("TestingCrypto").where(EntityCondition.makeCondition("testingCryptoTypeId", EntityOperator.IN, UtilMisc.toList("SUB_SELECT_1", "SUB_SELECT_3"))).orderBy("testingCryptoId").queryList();
         assertEquals(2, results.size());
         assertEquals("SUB_1", results.get(0).get("testingCryptoId"));
         assertEquals("SUB_3", results.get(1).get("testingCryptoId"));
 
         condition = makeSubSelectCondition(nanoTime);
-        results = delegator.findList("TestingCrypto", condition, null, UtilMisc.toList("testingCryptoId"), null, false);
+        results = EntityQuery.use(delegator).from("TestingCrypto").where(condition).orderBy("testingCryptoId").queryList();
         assertEquals(1, results.size());
         assertEquals("SUB_1", results.get(0).get("testingCryptoId"));
 
         condition = EntityCondition.makeCondition("testingCryptoId", EntityOperator.EQUALS, makeSubSelect(nanoTime));
-        results = delegator.findList("TestingCrypto", condition, null, UtilMisc.toList("testingCryptoId"), null, false);
+        results = EntityQuery.use(delegator).from("TestingCrypto").where(condition).orderBy("testingCryptoId").queryList();
         assertEquals(1, results.size());
         assertEquals("SUB_1", results.get(0).get("testingCryptoId"));
     }
diff --git a/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java b/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java
index 8f56885..71ac34c 100644
--- a/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java
+++ b/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java
@@ -64,6 +64,7 @@
 import org.ofbiz.entity.transaction.TransactionUtil;
 import org.ofbiz.entity.util.EntityFindOptions;
 import org.ofbiz.entity.util.EntityListIterator;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.entity.util.EntitySaxReader;
 import org.ofbiz.entity.util.EntityUtil;
 import org.ofbiz.entity.util.SequenceUtil;
@@ -119,8 +120,11 @@
         delegator.storeAll(newValues);
 
         // finds a List of newly created values.  the second parameter specifies the fields to order results by.
-        EntityCondition condition = EntityCondition.makeCondition("testingTypeId", EntityOperator.LIKE, "TEST-MAKE-%");
-        List<GenericValue> newlyCreatedValues = delegator.findList("TestingType", condition, null, UtilMisc.toList("testingTypeId"), null, false);
+        List<GenericValue> newlyCreatedValues = EntityQuery.use(delegator)
+                                                           .from("TestingType")
+                                                           .where(EntityCondition.makeCondition("testingTypeId", EntityOperator.LIKE, "TEST-MAKE-%"))
+                                                           .orderBy("testingTypeId")
+                                                           .queryList();
         assertEquals("4 TestingTypes(for make) found", 4, newlyCreatedValues.size());
     }
 
@@ -130,10 +134,10 @@
     public void testUpdateValue() throws Exception {
         // retrieve a sample GenericValue, make sure it's correct
         delegator.removeByCondition("TestingType", EntityCondition.makeCondition("testingTypeId", EntityOperator.LIKE, "TEST-UPDATE-%"));
-        GenericValue testValue = delegator.findOne("TestingType", false, "testingTypeId", "TEST-UPDATE-1");
+        GenericValue testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-UPDATE-1").queryOne();
         assertNull("No pre-existing type value", testValue);
         delegator.create("TestingType", "testingTypeId", "TEST-UPDATE-1", "description", "Testing Type #Update-1");
-        testValue = delegator.findOne("TestingType", false, "testingTypeId", "TEST-UPDATE-1");
+        testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-UPDATE-1").queryOne();
         assertEquals("Retrieved value has the correct description", "Testing Type #Update-1", testValue.getString("description"));
         // Test Observable aspect
         assertFalse("Observable has not changed", testValue.hasChanged());
@@ -151,17 +155,17 @@
         testValue.store();
         assertFalse("Observable has not changed", testValue.hasChanged());
         // now retrieve it again and make sure that the updated value is correct
-        testValue = delegator.findOne("TestingType", false, "testingTypeId", "TEST-UPDATE-1");
+        testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-UPDATE-1").queryOne();
         assertEquals("Retrieved value has the correct description", "New Testing Type #Update-1", testValue.getString("description"));
     }
 
     public void testRemoveValue() throws Exception {
         // Retrieve a sample GenericValue, make sure it's correct
         delegator.removeByCondition("TestingType", EntityCondition.makeCondition("testingTypeId", EntityOperator.LIKE, "TEST-REMOVE-%"));
-        GenericValue testValue = delegator.findOne("TestingType", false, "testingTypeId", "TEST-REMOVE-1");
+        GenericValue testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-REMOVE-1").queryOne();
         assertNull("No pre-existing type value", testValue);
         delegator.create("TestingType", "testingTypeId", "TEST-REMOVE-1", "description", "Testing Type #Remove-1");
-        testValue = delegator.findOne("TestingType", false, "testingTypeId", "TEST-REMOVE-1");
+        testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-REMOVE-1").queryOne();
         assertEquals("Retrieved value has the correct description", "Testing Type #Remove-1", testValue.getString("description"));
         testValue.remove();
         assertFalse("Observable has not changed", testValue.hasChanged());
@@ -176,7 +180,7 @@
             fail("Modified an immutable GenericValue");
         } catch (UnsupportedOperationException e) {
         }
-        testValue = delegator.findOne("TestingType", false, "testingTypeId", "TEST-REMOVE-1");
+        testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-REMOVE-1").queryOne();
         assertEquals("Finding removed value returns null", null, testValue);
     }
 
@@ -187,10 +191,10 @@
         // Test primary key cache
         delegator.removeByCondition("TestingType", EntityCondition.makeCondition("testingTypeId", EntityOperator.LIKE, "TEST-CACHE-%"));
         delegator.removeByCondition("TestingSubtype", EntityCondition.makeCondition("testingTypeId", EntityOperator.LIKE, "TEST-CACHE-%"));
-        GenericValue testValue = delegator.findOne("TestingType", true, "testingTypeId", "TEST-CACHE-1");
+        GenericValue testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-CACHE-1").cache(true).queryOne();
         assertNull("No pre-existing type value", testValue);
         delegator.create("TestingType", "testingTypeId", "TEST-CACHE-1", "description", "Testing Type #Cache-1");
-        testValue = delegator.findOne("TestingType", true, "testingTypeId", "TEST-CACHE-1");
+        testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-CACHE-1").cache(true).queryOne();
         assertEquals("Retrieved from cache value has the correct description", "Testing Type #Cache-1", testValue.getString("description"));
         // Test immutable
         try {
@@ -207,32 +211,40 @@
         testValue = (GenericValue) testValue.clone();
         testValue.put("description", "New Testing Type #Cache-1");
         testValue.store();
-        testValue = delegator.findOne("TestingType", true, "testingTypeId", "TEST-CACHE-1");
+        testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-CACHE-1").cache(true).queryOne();
         assertEquals("Retrieved from cache value has the correct description", "New Testing Type #Cache-1", testValue.getString("description"));
         // Test storeByCondition updates the cache
-        testValue = EntityUtil.getFirst(delegator.findByAnd("TestingType", UtilMisc.toMap("testingTypeId", "TEST-CACHE-1"), null, true));
+        testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-CACHE-1").cache(true).queryFirst();
         EntityCondition storeByCondition = EntityCondition.makeCondition(UtilMisc.toMap("testingTypeId", "TEST-CACHE-1",
                 "lastUpdatedStamp", testValue.get("lastUpdatedStamp")));
         int qtyChanged = delegator.storeByCondition("TestingType", UtilMisc.toMap("description", "New Testing Type #Cache-0"), storeByCondition);
         assertEquals("Delegator.storeByCondition updated one value", 1, qtyChanged);
-        testValue = EntityUtil.getFirst(delegator.findByAnd("TestingType", UtilMisc.toMap("testingTypeId", "TEST-CACHE-1"), null, true));
+        testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-CACHE-1").cache(true).queryFirst();
+        
         assertEquals("Retrieved from cache value has the correct description", "New Testing Type #Cache-0", testValue.getString("description"));
         // Test removeByCondition updates the cache
         qtyChanged = delegator.removeByCondition("TestingType", storeByCondition);
         assertEquals("Delegator.removeByCondition removed one value", 1, qtyChanged);
-        testValue = EntityUtil.getFirst(delegator.findByAnd("TestingType", UtilMisc.toMap("testingTypeId", "TEST-CACHE-1"), null, true));
+        testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-CACHE-1").cache(true).queryFirst();
         assertEquals("Retrieved from cache value is null", null, testValue);
         // Test entity value remove operation updates the cache
         testValue = delegator.create("TestingType", "testingTypeId", "TEST-CACHE-1", "description", "Testing Type #Cache-1");
         testValue.remove();
-        testValue = delegator.findOne("TestingType", true, "testingTypeId", "TEST-CACHE-1");
+        testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-CACHE-1").cache(true).queryOne();
         assertEquals("Retrieved from cache value is null", null, testValue);
         // Test entity condition cache
-        EntityCondition testCondition = EntityCondition.makeCondition("description", EntityOperator.EQUALS, "Testing Type #Cache-2");
-        List<GenericValue> testList = delegator.findList("TestingType", testCondition, null, null, null, true);
+        List<GenericValue> testList = EntityQuery.use(delegator)
+                                                 .from("TestingType")
+                                                 .where(EntityCondition.makeCondition("description", EntityOperator.EQUALS, "Testing Type #Cache-2"))
+                                                 .cache(true)
+                                                 .queryList();
         assertEquals("Delegator findList returned no values", 0, testList.size());
         delegator.create("TestingType", "testingTypeId", "TEST-CACHE-2", "description", "Testing Type #Cache-2");
-        testList = delegator.findList("TestingType", testCondition, null, null, null, true);
+        testList = EntityQuery.use(delegator)
+                              .from("TestingType")
+                              .where(EntityCondition.makeCondition("description", EntityOperator.EQUALS, "Testing Type #Cache-2"))
+                              .cache(true)
+                              .queryList();
         assertEquals("Delegator findList returned one value", 1, testList.size());
         testValue = testList.get(0);
         assertEquals("Retrieved from cache value has the correct description", "Testing Type #Cache-2", testValue.getString("description"));
@@ -251,34 +263,46 @@
         testValue = (GenericValue) testValue.clone();
         testValue.put("testingTypeId", "TEST-CACHE-3");
         testValue.create();
-        testList = delegator.findList("TestingType", testCondition, null, null, null, true);
+        testList = EntityQuery.use(delegator)
+                              .from("TestingType")
+                              .where(EntityCondition.makeCondition("description", EntityOperator.EQUALS, "Testing Type #Cache-2"))
+                              .cache(true)
+                              .queryList();
         assertEquals("Delegator findList returned two values", 2, testList.size());
         // Test entity value update operation updates the cache
         testValue.put("description", "New Testing Type #Cache-3");
         testValue.store();
-        testList = delegator.findList("TestingType", testCondition, null, null, null, true);
+        testList = EntityQuery.use(delegator)
+                              .from("TestingType")
+                              .where(EntityCondition.makeCondition("description", EntityOperator.EQUALS, "Testing Type #Cache-2"))
+                              .cache(true)
+                              .queryList();
         assertEquals("Delegator findList returned one value", 1, testList.size());
         // Test entity value remove operation updates the cache
         testValue = testList.get(0);
         testValue = (GenericValue) testValue.clone();
         testValue.remove();
-        testList = delegator.findList("TestingType", testCondition, null, null, null, true);
+        testList = EntityQuery.use(delegator)
+                              .from("TestingType")
+                              .where(EntityCondition.makeCondition("description", EntityOperator.EQUALS, "Testing Type #Cache-2"))
+                              .cache(true)
+                              .queryList();
         assertEquals("Delegator findList returned empty list", 0, testList.size());
         // Test view entities in the pk cache - updating an entity should clear pk caches for all view entities containing that entity.
-        testValue = delegator.findOne("TestingSubtype", true, "testingTypeId", "TEST-CACHE-3");
+        testValue = EntityQuery.use(delegator).from("TestingSubtype").where("testingTypeId", "TEST-CACHE-3").cache(true).queryOne();
         assertNull("No pre-existing TestingSubtype", testValue);
         testValue = delegator.create("TestingSubtype", "testingTypeId", "TEST-CACHE-3", "subtypeDescription", "Testing Subtype #Cache-3");
         assertNotNull("TestingSubtype created", testValue);
         // Confirm member entity appears in the view
-        testValue = delegator.findOne("TestingViewPks", true, "testingTypeId", "TEST-CACHE-3");
+        testValue = EntityQuery.use(delegator).from("TestingViewPks").where("testingTypeId", "TEST-CACHE-3").cache(true).queryOne();
         assertEquals("View retrieved from cache has the correct member description", "Testing Subtype #Cache-3", testValue.getString("subtypeDescription"));
-        testValue = delegator.findOne("TestingSubtype", true, "testingTypeId", "TEST-CACHE-3");
+        testValue = EntityQuery.use(delegator).from("TestingSubtype").where("testingTypeId", "TEST-CACHE-3").cache(true).queryOne();
         // Modify member entity
         testValue = (GenericValue) testValue.clone();
         testValue.put("subtypeDescription", "New Testing Subtype #Cache-3");
         testValue.store();
         // Check if cached view contains the modification
-        testValue = delegator.findOne("TestingViewPks", true, "testingTypeId", "TEST-CACHE-3");
+        testValue = EntityQuery.use(delegator).from("TestingViewPks").where("testingTypeId", "TEST-CACHE-3").cache(true).queryOne();
         assertEquals("View retrieved from cache has the correct member description", "New Testing Subtype #Cache-3", testValue.getString("subtypeDescription"));
     }
 
@@ -291,14 +315,14 @@
         Delegator localDelegator = DelegatorFactory.getDelegator("default");
         boolean transBegin = TransactionUtil.begin();
         localDelegator.create("TestingType", "testingTypeId", "TEST-5", "description", "Testing Type #5");
-        GenericValue testValue = localDelegator.findOne("TestingType", false, "testingTypeId", "TEST-5");
+        GenericValue testValue = EntityQuery.use(localDelegator).from("TestingType").where("testingTypeId", "TEST-5").queryOne();
         assertEquals("Retrieved value has the correct description", "Testing Type #5", testValue.getString("description"));
         String newValueStr = UtilXml.toXml(testValue);
         GenericValue newValue = (GenericValue) UtilXml.fromXml(newValueStr);
         assertEquals("Retrieved value has the correct description", "Testing Type #5", newValue.getString("description"));
         newValue.put("description", "XML Testing Type #5");
         newValue.store();
-        newValue = localDelegator.findOne("TestingType", false, "testingTypeId", "TEST-5");
+        newValue = EntityQuery.use(localDelegator).from("TestingType").where("testingTypeId", "TEST-5").queryOne();
         assertEquals("Retrieved value has the correct description", "XML Testing Type #5", newValue.getString("description"));
         TransactionUtil.rollback(transBegin, null, null);
     }
@@ -331,8 +355,10 @@
         // get how many child nodes did we have before creating the tree
         delegator.removeByCondition("TestingNode", EntityCondition.makeCondition("description", EntityOperator.LIKE, "create:"));
         long created = flushAndRecreateTree("create");
-        long newlyStored = delegator.findCountByCondition("TestingNode", EntityCondition.makeCondition("description", EntityOperator.LIKE, "create:%"), null, null);
-
+        long newlyStored = EntityQuery.use(delegator)
+                                      .from("TestingNode")
+                                      .where(EntityCondition.makeCondition("description", EntityOperator.LIKE, "create:%"))
+                                      .queryCount();
         assertEquals("Created/Stored Nodes", created, newlyStored);
     }
 
@@ -341,12 +367,14 @@
      */
     public void testAddMembersToTree() throws Exception {
         delegator.removeByCondition("TestingType", EntityCondition.makeCondition("testingTypeId", EntityOperator.LIKE, "TEST-TREE-%"));
-        GenericValue testValue = delegator.findOne("TestingType", true, "testingTypeId", "TEST-TREE-1");
+        GenericValue testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-TREE-1").cache(true).queryOne();
         assertNull("No pre-existing type value", testValue);
         delegator.create("TestingType", "testingTypeId", "TEST-TREE-1", "description", "Testing Type #Tree-1");
         // get the level1 nodes
-        EntityCondition isLevel1 = EntityCondition.makeCondition("primaryParentNodeId", EntityOperator.NOT_EQUAL, GenericEntity.NULL_FIELD);
-        List<GenericValue> nodeLevel1 = delegator.findList("TestingNode", isLevel1, null, null, null, false);
+        List<GenericValue> nodeLevel1 = EntityQuery.use(delegator)
+                                                   .from("TestingNode")
+                                                   .where(EntityCondition.makeCondition("primaryParentNodeId", EntityOperator.NOT_EQUAL, GenericEntity.NULL_FIELD))
+                                                   .queryList();
 
         List<GenericValue> newValues = new LinkedList<GenericValue>();
         Timestamp now = UtilDateTime.nowTimestamp();
@@ -387,7 +415,12 @@
         delegator.create("TestingType", "testingTypeId", typeId, "description", typeDescription);
         int i = 0;
         Timestamp now = UtilDateTime.nowTimestamp();
-        for (GenericValue node: delegator.findList("TestingNode", EntityCondition.makeCondition("description", EntityOperator.LIKE, descriptionPrefix + "%"), null, null, null, false)) {
+        
+        for (GenericValue node: EntityQuery.use(delegator)
+                                           .from("TestingNode")
+                                           .where(EntityCondition.makeCondition("description", EntityOperator.LIKE, descriptionPrefix + "%"))
+                                           .queryList()
+        ) {
             if (i % 2 == 0) {
                 GenericValue testing = delegator.create("Testing", "testingId", descriptionPrefix + ":" + node.get("testingNodeId"), "testingTypeId", typeId, "description", node.get("description"));
                 GenericValue member = delegator.makeValue("TestingNodeMember",
@@ -416,7 +449,7 @@
             EntityOperator.AND,
             EntityCondition.makeCondition("description", EntityOperator.LIKE, "count-views:%")
         );
-        List<GenericValue> nodeWithMembers = delegator.findList("TestingNodeAndMember", isNodeWithMember, null, null, null, false);
+        List<GenericValue> nodeWithMembers = EntityQuery.use(delegator).from("TestingNodeAndMember").where(isNodeWithMember).queryList();
 
         for (GenericValue v: nodeWithMembers) {
             Map<String, Object> fields = v.getAllFields();
@@ -428,7 +461,7 @@
                 Debug.logInfo(field.toString() + " = " + ((value == null) ? "[null]" : value), module);
             }
         }
-        long testingcount = delegator.findCountByCondition("Testing", EntityCondition.makeCondition("testingTypeId", EntityOperator.EQUALS, "TEST-COUNT-VIEW"), null, null);
+        long testingcount = EntityQuery.use(delegator).from("Testing").where("testingTypeId", "TEST-COUNT-VIEW").queryCount();
         assertEquals("Number of views should equal number of created entities in the test.", testingcount, nodeWithMembers.size());
     }
 
@@ -437,28 +470,31 @@
      */
     public void testFindDistinct() throws Exception {
         delegator.removeByCondition("Testing", EntityCondition.makeCondition("testingTypeId", EntityOperator.LIKE, "TEST-DISTINCT-%"));
-        List<GenericValue> testingDistinctList = delegator.findList("Testing", EntityCondition.makeCondition("testingTypeId", EntityOperator.LIKE, "TEST-DISTINCT-%"), null, null, null, false);
+        List<GenericValue> testingDistinctList = EntityQuery.use(delegator)
+                                                            .from("Testing")
+                                                            .where(EntityCondition.makeCondition("testingTypeId", EntityOperator.LIKE, "TEST-DISTINCT-%"))
+                                                            .queryList();
+        
         assertEquals("No existing Testing entities for distinct", 0, testingDistinctList.size());
         delegator.removeByCondition("TestingType", EntityCondition.makeCondition("testingTypeId", EntityOperator.LIKE, "TEST-DISTINCT-%"));
-        GenericValue testValue = delegator.findOne("TestingType", true, "testingTypeId", "TEST-DISTINCT-1");
+        GenericValue testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-DISTINCT-1").cache(true).queryOne();
         assertNull("No pre-existing type value", testValue);
         delegator.create("TestingType", "testingTypeId", "TEST-DISTINCT-1", "description", "Testing Type #Distinct-1");
-        testValue = delegator.findOne("TestingType", true, "testingTypeId", "TEST-DISTINCT-1");
+        testValue = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "TEST-DISTINCT-1").cache(true).queryOne();
         assertNotNull("Found newly created type value", testValue);
 
         delegator.create("Testing", "testingId", "TEST-DISTINCT-1", "testingTypeId", "TEST-DISTINCT-1", "testingSize", Long.valueOf(10), "comments", "No-comments");
         delegator.create("Testing", "testingId", "TEST-DISTINCT-2", "testingTypeId", "TEST-DISTINCT-1", "testingSize", Long.valueOf(10), "comments", "Some-comments");
         delegator.create("Testing", "testingId", "TEST-DISTINCT-3", "testingTypeId", "TEST-DISTINCT-1", "testingSize", Long.valueOf(9), "comments", "No-comments");
         delegator.create("Testing", "testingId", "TEST-DISTINCT-4", "testingTypeId", "TEST-DISTINCT-1", "testingSize", Long.valueOf(11), "comments", "Some-comments");
-        List<EntityExpr> exprList = UtilMisc.toList(
-                EntityCondition.makeCondition("testingSize", EntityOperator.EQUALS, Long.valueOf(10)),
-                EntityCondition.makeCondition("comments", EntityOperator.EQUALS, "No-comments"));
-        EntityConditionList<EntityExpr> condition = EntityCondition.makeCondition(exprList);
 
-        EntityFindOptions findOptions = new EntityFindOptions();
-        findOptions.setDistinct(true);
-
-        List<GenericValue> testingSize10 = delegator.findList("Testing", condition, UtilMisc.toSet("testingSize", "comments"), null, findOptions, false);
+        List<GenericValue> testingSize10 = EntityQuery.use(delegator)
+                                                      .select("testingSize", "comments")
+                                                      .from("Testing")
+                                                      .where("testingSize", Long.valueOf(10), "comments", "No-comments")
+                                                      .distinct()
+                                                      .cache()
+                                                      .queryList();
         Debug.logInfo("testingSize10 is " + testingSize10.size(), module);
 
         assertEquals("There should only be 1 result found by findDistinct()", 1, testingSize10.size());
@@ -468,8 +504,10 @@
      * Tests a findByCondition using not like
      */
     public void testNotLike() throws Exception {
-        EntityCondition cond  = EntityCondition.makeCondition("description", EntityOperator.NOT_LIKE, "root%");
-        List<GenericValue> nodes = delegator.findList("TestingNode", cond, null, null, null, false);
+        List<GenericValue> nodes = EntityQuery.use(delegator)
+                                              .from("TestingNode")
+                                              .where(EntityCondition.makeCondition("description", EntityOperator.NOT_LIKE, "root%"))
+                                              .queryList();
         assertNotNull("Found nodes", nodes);
 
         for (GenericValue product: nodes) {
@@ -542,8 +580,10 @@
         //
         // Find the testing entities tru the node member and build a list of them
         //
-        EntityCondition isNodeWithMember = EntityCondition.makeCondition("testingId", EntityOperator.LIKE, "rnmat:%");
-        List<GenericValue> values = delegator.findList("TestingNodeMember", isNodeWithMember, null, null, null, false);
+        List<GenericValue> values = EntityQuery.use(delegator)
+                                               .from("TestingNodeMember")
+                                               .where(EntityCondition.makeCondition("testingId", EntityOperator.LIKE, "rnmat:%"))
+                                               .queryList();
 
         ArrayList<GenericValue> testings = new ArrayList<GenericValue>();
 
@@ -552,11 +592,17 @@
         }
         // and remove the nodeMember afterwards
         delegator.removeAll(values);
-        values = delegator.findList("TestingNodeMember", isNodeWithMember, null, null, null, false);
+        values = EntityQuery.use(delegator)
+                            .from("TestingNodeMember")
+                            .where(EntityCondition.makeCondition("testingId", EntityOperator.LIKE, "rnmat:%"))
+                            .queryList();
         assertEquals("No more Node Member entities", 0, values.size());
 
         delegator.removeAll(testings);
-        values = delegator.findList("Testing", EntityCondition.makeCondition("description", EntityOperator.LIKE, "rnmat:%"), null, null, null, false);
+        values = EntityQuery.use(delegator)
+                            .from("Testing")
+                            .where(EntityCondition.makeCondition("description", EntityOperator.LIKE, "rnmat:%"))
+                            .queryList();
         assertEquals("No more Testing entities", 0, values.size());
     }
 
@@ -570,7 +616,7 @@
         EntityCondition isLevel1 = EntityCondition.makeCondition("description", EntityOperator.LIKE, "store-by-condition-a:%");
         Map<String, String> fieldsToSet = UtilMisc.toMap("description", "store-by-condition-a:updated");
         delegator.storeByCondition("TestingNode", fieldsToSet, isLevel1);
-        List<GenericValue> updatedNodes = delegator.findByAnd("TestingNode", fieldsToSet, null, false);
+        List<GenericValue> updatedNodes = EntityQuery.use(delegator).from("TestingNode").where(fieldsToSet).queryList();
         int n = updatedNodes.size();
         assertTrue("testStoreByCondition updated nodes > 0", n > 0);
     }
@@ -602,7 +648,7 @@
             EntityOperator.AND,
             EntityCondition.makeCondition("primaryParentNodeId", EntityOperator.NOT_EQUAL, GenericEntity.NULL_FIELD)
         );
-        List<GenericValue> rootValues = delegator.findList("TestingNode", isRoot, UtilMisc.toSet("testingNodeId"), null, null, false);
+        List<GenericValue> rootValues = EntityQuery.use(delegator).select("testingNodeId").from("TestingNode").where(isRoot).queryList();
 
         for (GenericValue value: rootValues) {
             GenericPK pk = value.getPrimaryKey();
@@ -612,7 +658,7 @@
 
         // no more TestingNode should be in the data base anymore.
 
-        List<GenericValue> testingNodes = delegator.findList("TestingNode", isRoot, null, null, null, false);
+        List<GenericValue> testingNodes = EntityQuery.use(delegator).from("TestingNode").where(isRoot).queryList();
         assertEquals("No more TestingNode after removing the roots", 0, testingNodes.size());
     }
 
@@ -620,20 +666,20 @@
      * Tests the .removeAll method only.
      */
     public void testRemoveType() throws Exception {
-        List<GenericValue> values = delegator.findList("TestingRemoveAll", null, null, null, null, false);
+        List<GenericValue> values = EntityQuery.use(delegator).from("TestingRemoveAll").queryList();
         delegator.removeAll(values);
-        values = delegator.findList("TestingRemoveAll", null, null, null, null, false);
+        values = EntityQuery.use(delegator).from("TestingRemoveAll").queryList();
         assertEquals("No more TestingRemoveAll: setup", 0, values.size());
         for (int i = 0; i < 10; i++) {
             delegator.create("TestingRemoveAll", "testingRemoveAllId", "prefix:" + i);
         }
-        values = delegator.findList("TestingRemoveAll", null, null, null, null, false);
+        values = EntityQuery.use(delegator).from("TestingRemoveAll").queryList();
         assertEquals("No more TestingRemoveAll: create", 10, values.size());
 
         delegator.removeAll(values);
 
         // now make sure there are no more of these
-        values = delegator.findList("TestingRemoveAll", null, null, null, null, false);
+        values = EntityQuery.use(delegator).from("TestingRemoveAll").queryList();
         assertEquals("No more TestingRemoveAll: finish", 0, values.size());
     }
 
@@ -641,17 +687,24 @@
      * This test will create a large number of unique items and add them to the delegator at once
      */
     public void testCreateManyAndStoreAtOnce() throws Exception {
-        EntityCondition condition = EntityCondition.makeCondition("testingId", EntityOperator.LIKE, "T1-%");
         try {
             List<GenericValue> newValues = new LinkedList<GenericValue>();
             for (int i = 0; i < TEST_COUNT; i++) {
                 newValues.add(delegator.makeValue("Testing", "testingId", getTestId("T1-", i)));
             }
             delegator.storeAll(newValues);
-            List<GenericValue> newlyCreatedValues = delegator.findList("Testing", condition, null, UtilMisc.toList("testingId"), null, false);
+            List<GenericValue> newlyCreatedValues = EntityQuery.use(delegator)
+                                                               .from("Testing")
+                                                               .where(EntityCondition.makeCondition("testingId", EntityOperator.LIKE, "T1-%"))
+                                                               .orderBy("testingId")
+                                                               .queryList();
             assertEquals("Test to create " + TEST_COUNT + " and store all at once", TEST_COUNT, newlyCreatedValues.size());
         } finally {
-            List<GenericValue> newlyCreatedValues = delegator.findList("Testing", condition, null, UtilMisc.toList("testingId"), null, false);
+            List<GenericValue> newlyCreatedValues = EntityQuery.use(delegator)
+                                                               .from("Testing")
+                                                               .where(EntityCondition.makeCondition("testingId", EntityOperator.LIKE, "T1-%"))
+                                                               .orderBy("testingId")
+                                                               .queryList();
             delegator.removeAll(newlyCreatedValues);
         }
     }
@@ -660,15 +713,22 @@
      * This test will create a large number of unique items and add them to the delegator at once
      */
     public void testCreateManyAndStoreOneAtATime() throws Exception {
-        EntityCondition condition = EntityCondition.makeCondition("testingId", EntityOperator.LIKE, "T2-%");
         try {
             for (int i = 0; i < TEST_COUNT; i++) {
                 delegator.create(delegator.makeValue("Testing", "testingId", getTestId("T2-", i)));
             }
-            List<GenericValue> newlyCreatedValues = delegator.findList("Testing", condition, null, UtilMisc.toList("testingId"), null, false);
+            List<GenericValue> newlyCreatedValues = EntityQuery.use(delegator)
+                                                               .from("Testing")
+                                                               .where(EntityCondition.makeCondition("testingId", EntityOperator.LIKE, "T2-%"))
+                                                               .orderBy("testingId")
+                                                               .queryList();
             assertEquals("Test to create " + TEST_COUNT + " and store one at a time: ", TEST_COUNT, newlyCreatedValues.size());
         } finally {
-            List<GenericValue> newlyCreatedValues = delegator.findList("Testing", condition, null, UtilMisc.toList("testingId"), null, false);
+            List<GenericValue> newlyCreatedValues = EntityQuery.use(delegator)
+                                                               .from("Testing")
+                                                               .where(EntityCondition.makeCondition("testingId", EntityOperator.LIKE, "T2-%"))
+                                                               .orderBy("testingId")
+                                                               .queryList();
             delegator.removeAll(newlyCreatedValues);
         }
     }
@@ -677,19 +737,26 @@
      * This test will use the large number of unique items from above and test the EntityListIterator looping through the list
      */
     public void testEntityListIterator() throws Exception {
-        EntityCondition condition = EntityCondition.makeCondition("testingId", EntityOperator.LIKE, "T3-%");
         try {
             List<GenericValue> newValues = new LinkedList<GenericValue>();
             for (int i = 0; i < TEST_COUNT; i++) {
                 newValues.add(delegator.makeValue("Testing", "testingId", getTestId("T3-", i)));
             }
             delegator.storeAll(newValues);
-            List<GenericValue> newlyCreatedValues = delegator.findList("Testing", condition, null, UtilMisc.toList("testingId"), null, false);
+            List<GenericValue> newlyCreatedValues = EntityQuery.use(delegator)
+                                                               .from("Testing")
+                                                               .where(EntityCondition.makeCondition("testingId", EntityOperator.LIKE, "T3-%"))
+                                                               .orderBy("testingId")
+                                                               .queryList();
             assertEquals("Test to create " + TEST_COUNT + " and store all at once", TEST_COUNT, newlyCreatedValues.size());
             boolean beganTransaction = false;
             try {
                 beganTransaction = TransactionUtil.begin();
-                EntityListIterator iterator = delegator.find("Testing", condition, null, null, UtilMisc.toList("testingId"), null);
+                EntityListIterator iterator = EntityQuery.use(delegator)
+                                                         .from("Testing")
+                                                         .where(EntityCondition.makeCondition("testingId", EntityOperator.LIKE, "T3-%"))
+                                                         .orderBy("testingId")
+                                                         .queryIterator();
                 assertNotNull("Test if EntityListIterator was created: ", iterator);
 
                 int i = 0;
@@ -709,7 +776,10 @@
                 TransactionUtil.commit(beganTransaction);
             }
         } finally {
-            List<GenericValue> entitiesToRemove = delegator.findList("Testing", condition, null, null, null, false);
+            List<GenericValue> entitiesToRemove = EntityQuery.use(delegator)
+                                                             .from("Testing")
+                                                             .where(EntityCondition.makeCondition("testingId", EntityOperator.LIKE, "T3-%"))
+                                                             .queryList();
             delegator.removeAll(entitiesToRemove);
         }
     }
@@ -722,7 +792,7 @@
         boolean transBegin = TransactionUtil.begin();
         delegator.create(testValue);
         TransactionUtil.rollback(transBegin, null, null);
-        GenericValue testValueOut = delegator.findOne("Testing", false, "testingId", "rollback-test");
+        GenericValue testValueOut = EntityQuery.use(delegator).from("Testing").where("testingId", "rollback-test").queryOne();
         assertEquals("Test that transaction rollback removes value: ", null, testValueOut);
     }
 
@@ -802,7 +872,7 @@
             testValue.set("numericField", numeric);
             testValue.set("clobField", clobStr);
             testValue.store();
-            testValue = delegator.findOne("TestFieldType", UtilMisc.toMap("testFieldTypeId", id), false);
+            testValue = EntityQuery.use(delegator).from("TestFieldType").where("testFieldTypeId", id).queryOne();
             assertEquals("testFieldTypeId", id, testValue.get("testFieldTypeId"));
             Blob blob = (Blob) testValue.get("blobField");
             byte[] c = blob.getBytes(1, (int) blob.length());
@@ -834,7 +904,7 @@
             testValue.set("numericField", null);
             testValue.set("clobField", null);
             testValue.store();
-            testValue = delegator.findOne("TestFieldType", UtilMisc.toMap("testFieldTypeId", id), false);
+            testValue = EntityQuery.use(delegator).from("TestFieldType").where("testFieldTypeId", id).queryOne();
             assertEquals("testFieldTypeId", id, testValue.get("testFieldTypeId"));
             assertNull("blobField null", testValue.get("blobField"));
             assertNull("byteArrayField null", testValue.get("byteArrayField"));
@@ -848,7 +918,7 @@
             assertNull("clobField null", testValue.get("clobField"));
         } finally {
             // Remove all our newly inserted values.
-            List<GenericValue> values = delegator.findList("TestFieldType", null, null, null, null, false);
+            List<GenericValue> values = EntityQuery.use(delegator).from("TestFieldType").queryList();
             delegator.removeAll(values);
         }
     }
@@ -980,8 +1050,8 @@
         EntitySaxReader reader = new EntitySaxReader(delegator);
         long numberLoaded = reader.parse(xmlContentLoad);
         assertEquals("Create Entity loaded ", 4, numberLoaded);
-        GenericValue t1 = delegator.findOne("Testing", UtilMisc.toMap("testingId", "T1"), false);
-        GenericValue t2 = delegator.findOne("Testing", UtilMisc.toMap("testingId", "T2"), true);
+        GenericValue t1 = EntityQuery.use(delegator).from("Testing").where("testingId", "T1").queryOne();
+        GenericValue t2 = EntityQuery.use(delegator).from("Testing").where("testingId", "T2").cache(true).queryOne();
         assertNotNull("Create Testing(T1)", t1);
         assertEquals("Create Testing(T1).testingTypeId", "JUNIT-TEST", t1.getString("testingTypeId"));
         assertEquals("Create Testing(T1).testingName", "First test", t1.getString("testingName"));
@@ -1008,7 +1078,7 @@
         reader = new EntitySaxReader(delegator);
         numberLoaded += reader.parse(xmlContentLoad);
         assertEquals("Create Skip Entity loaded ", 3, numberLoaded);
-        GenericValue t1 = delegator.findOne("Testing", UtilMisc.toMap("testingId", "reader-create-skip"), false);
+        GenericValue t1 = EntityQuery.use(delegator).from("Testing").where("testingId", "reader-create-skip").queryOne();
         assertNotNull("Create Skip Testing(T1)", t1);
         assertEquals("Create Skip Testing(T1).testingTypeId", "reader-create-skip", t1.getString("testingTypeId"));
         assertEquals("Create Skip Testing(T1).testingName", "reader create skip", t1.getString("testingName"));
@@ -1028,8 +1098,8 @@
         EntitySaxReader reader = new EntitySaxReader(delegator);
         long numberLoaded = reader.parse(xmlContentLoad);
         assertEquals("Update Entity loaded ", 5, numberLoaded);
-        GenericValue t1 = delegator.findOne("Testing", UtilMisc.toMap("testingId", "create-update-T1"), false);
-        GenericValue t3 = delegator.findOne("Testing", UtilMisc.toMap("testingId", "create-update-T3"), false);
+        GenericValue t1 = EntityQuery.use(delegator).from("Testing").where("testingId", "create-update-T1").queryOne();
+        GenericValue t3 = EntityQuery.use(delegator).from("Testing").where("testingId", "create-update-T3").queryOne();
         assertNotNull("Update Testing(T1)", t1);
         assertEquals("Update Testing(T1).testingTypeId", "create-update", t1.getString("testingTypeId"));
         assertEquals("Update Testing(T1).testingName", "First test update", t1.getString("testingName"));
@@ -1054,8 +1124,8 @@
         EntitySaxReader reader = new EntitySaxReader(delegator);
         long numberLoaded = reader.parse(xmlContentLoad);
         assertEquals("Replace Entity loaded ", 4, numberLoaded);
-        GenericValue t1 = delegator.findOne("Testing", UtilMisc.toMap("testingId", "create-replace-T1"), false);
-        GenericValue t2 = delegator.findOne("Testing", UtilMisc.toMap("testingId", "create-replace-T2"), false);
+        GenericValue t1 = EntityQuery.use(delegator).from("Testing").where("testingId", "create-replace-T1").queryOne();
+        GenericValue t2 = EntityQuery.use(delegator).from("Testing").where("testingId", "create-replace-T2").queryOne();
         assertNotNull("Replace Testing(T1)", t1);
         assertEquals("Replace Testing(T1).testingTypeId", "create-replace", t1.getString("testingTypeId"));
         assertEquals("Replace Testing(T1).testingName", "First test replace", t1.getString("testingName"));
@@ -1081,15 +1151,15 @@
         EntitySaxReader reader = new EntitySaxReader(delegator);
         long numberLoaded = reader.parse(xmlContentLoad);
         assertEquals("Delete Entity loaded ", 5, numberLoaded);
-        GenericValue t1 = delegator.findOne("Testing", UtilMisc.toMap("testingId", "T1"), false);
-        GenericValue t2 = delegator.findOne("Testing", UtilMisc.toMap("testingId", "T2"), false);
-        GenericValue t3 = delegator.findOne("Testing", UtilMisc.toMap("testingId", "T2"), false);
+        GenericValue t1 = EntityQuery.use(delegator).from("Testing").where("testingId", "T1").queryOne();
+        GenericValue t2 = EntityQuery.use(delegator).from("Testing").where("testingId", "T2").queryOne();
+        GenericValue t3 = EntityQuery.use(delegator).from("Testing").where("testingId", "T3").queryOne();
         assertNull("Delete Testing(T1)", t1);
         assertNull("Delete Testing(T2)", t2);
         assertNull("Delete Testing(T3)", t3);
-        GenericValue testType = delegator.findOne("TestingType", UtilMisc.toMap("testingTypeId", "JUNIT-TEST"), false);
+        GenericValue testType = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "JUNIT-TEST").queryOne();
         assertNull("Delete TestingType 1", testType);
-        testType = delegator.findOne("TestingType", UtilMisc.toMap("testingTypeId", "JUNIT-TEST2"), false);
+        testType = EntityQuery.use(delegator).from("TestingType").where("testingTypeId", "JUNIT-TEST2").queryOne();
         assertNull("Delete TestingType 2", testType);
     }
 
@@ -1174,7 +1244,7 @@
         try {
             transactionStarted = TransactionUtil.begin();
             for (int i = 1; i <= numberOfQueries; i++) {
-                List rows = delegator.findAll("SequenceValueItem", false);
+                List rows = EntityQuery.use(delegator).from("SequenceValueItem").queryList();
                 totalNumberOfRows = totalNumberOfRows + rows.size();
             }
             TransactionUtil.commit(transactionStarted);
@@ -1194,7 +1264,7 @@
         try {
             for (int i = 1; i <= numberOfQueries; i++) {
                 transactionStarted = TransactionUtil.begin();
-                List rows = delegator.findAll("SequenceValueItem", false);
+                List rows = EntityQuery.use(delegator).from("SequenceValueItem").queryList();
                 totalNumberOfRows = totalNumberOfRows + rows.size();
                 TransactionUtil.commit(transactionStarted);
             }
diff --git a/framework/entity/src/org/ofbiz/entity/util/EntityDataAssert.java b/framework/entity/src/org/ofbiz/entity/util/EntityDataAssert.java
index 67037d7..a3f3105 100644
--- a/framework/entity/src/org/ofbiz/entity/util/EntityDataAssert.java
+++ b/framework/entity/src/org/ofbiz/entity/util/EntityDataAssert.java
@@ -85,7 +85,7 @@
 
         try {
             checkPK = checkValue.getPrimaryKey();
-            GenericValue currentValue = delegator.findOne(checkPK.getEntityName(), checkPK, false);
+            GenericValue currentValue = EntityQuery.use(delegator).from(checkPK.getEntityName()).where(checkPK).queryOne();
             if (currentValue == null) {
                 errorMessages.add("Entity [" + checkPK.getEntityName() + "] record not found for pk: " + checkPK);
                 return;
diff --git a/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java b/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
index 4dc2784..90e88ec 100644
--- a/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
+++ b/framework/entity/src/org/ofbiz/entity/util/EntityQuery.java
@@ -423,7 +423,15 @@
      */
     public long queryCount() throws GenericEntityException {
         if (dynamicViewEntity != null) {
-            return queryIterator().getResultsSizeAfterPartialList();
+            EntityListIterator iterator = null;
+            try {
+                iterator = queryIterator();
+                return iterator.getResultsSizeAfterPartialList();
+            } finally {
+                if (iterator != null) {
+                    iterator.close();
+                }
+            }
         }
         return delegator.findCountByCondition(entityName, makeWhereCondition(false), havingEntityCondition, makeEntityFindOptions());
     }
diff --git a/framework/entity/src/org/ofbiz/entity/util/EntityTypeUtil.java b/framework/entity/src/org/ofbiz/entity/util/EntityTypeUtil.java
index 2acf4c3..f8f70c5 100644
--- a/framework/entity/src/org/ofbiz/entity/util/EntityTypeUtil.java
+++ b/framework/entity/src/org/ofbiz/entity/util/EntityTypeUtil.java
@@ -133,7 +133,7 @@
     public static boolean hasParentType(Delegator delegator, String entityName, String primaryKey, String childType, String parentTypeField, String parentType) {
         GenericValue childTypeValue = null;
         try {
-            childTypeValue = delegator.findOne(entityName, UtilMisc.toMap(primaryKey, childType), true);
+            childTypeValue = EntityQuery.use(delegator).from(entityName).where(primaryKey, childType).cache(true).queryOne();
         } catch (GenericEntityException e) {
             Debug.logError("Error finding "+entityName+" record for type "+childType, module);
         }
diff --git a/framework/entity/src/org/ofbiz/entity/util/EntityUtil.java b/framework/entity/src/org/ofbiz/entity/util/EntityUtil.java
index 401e681..134b42d 100644
--- a/framework/entity/src/org/ofbiz/entity/util/EntityUtil.java
+++ b/framework/entity/src/org/ofbiz/entity/util/EntityUtil.java
@@ -430,7 +430,7 @@
     public static List<GenericValue> findDatedInclusionEntity(Delegator delegator, String entityName, Map<String, ? extends Object> search, Timestamp now) throws GenericEntityException {
         EntityCondition searchCondition = EntityCondition.makeCondition(UtilMisc.toList(
                 EntityCondition.makeCondition(search), EntityUtil.getFilterByDateExpr(now)));
-        return delegator.findList(entityName, searchCondition, null, UtilMisc.toList("-fromDate"), null, false);
+        return EntityQuery.use(delegator).from(entityName).where(searchCondition).orderBy("-fromDate").queryList();
     }
 
     public static GenericValue newDatedInclusionEntity(Delegator delegator, String entityName, Map<String, ? extends Object> search) throws GenericEntityException {
@@ -466,7 +466,7 @@
             search.putAll(find);
         }
         if (now.equals(search.get("fromDate"))) {
-            return EntityUtil.getOnly(delegator.findByAnd(entityName, search, null, false));
+            return EntityUtil.getOnly(EntityQuery.use(delegator).from(entityName).where(search).queryList());
         } else {
             search.put("fromDate",now);
             search.remove("thruDate");
diff --git a/framework/entity/src/org/ofbiz/entity/util/EntityUtilProperties.java b/framework/entity/src/org/ofbiz/entity/util/EntityUtilProperties.java
index 1ef82fc..1bffdb1 100644
--- a/framework/entity/src/org/ofbiz/entity/util/EntityUtilProperties.java
+++ b/framework/entity/src/org/ofbiz/entity/util/EntityUtilProperties.java
@@ -55,7 +55,11 @@
         
         // find system property
         try {
-            GenericValue systemProperty = EntityQuery.use(delegator).from("SystemProperty").where("systemResourceId", resource, "systemPropertyId", name).cache().queryOne();
+            GenericValue systemProperty = EntityQuery.use(delegator)
+                                                     .from("SystemProperty")
+                                                     .where("systemResourceId", resource, "systemPropertyId", name)
+                                                     .cache()
+                                                     .queryOne();
             if (systemProperty != null) {
                 String systemPropertyValue = systemProperty.getString("systemPropertyValue");
                 if (UtilValidate.isNotEmpty(systemPropertyValue)) {
diff --git a/framework/entityext/src/org/ofbiz/entityext/EntityGroupUtil.java b/framework/entityext/src/org/ofbiz/entityext/EntityGroupUtil.java
index a88a1bc..ecb55fb 100644
--- a/framework/entityext/src/org/ofbiz/entityext/EntityGroupUtil.java
+++ b/framework/entityext/src/org/ofbiz/entityext/EntityGroupUtil.java
@@ -30,6 +30,7 @@
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.model.ModelEntity;
 import org.ofbiz.entity.model.ModelViewEntity;
+import org.ofbiz.entity.util.EntityQuery;
 
 /**
  * EntityEcaUtil
@@ -41,8 +42,7 @@
     public static Set<String> getEntityNamesByGroup(String entityGroupId, Delegator delegator, boolean requireStampFields) throws GenericEntityException {
         Set<String> entityNames = new HashSet<String>();
 
-        List<GenericValue> entitySyncGroupIncludes = delegator.findByAnd("EntityGroupEntry", UtilMisc.toMap("entityGroupId", entityGroupId), null, false);
-
+        List<GenericValue> entitySyncGroupIncludes = EntityQuery.use(delegator).from("EntityGroupEntry").where("entityGroupId", entityGroupId).queryList();
         List<ModelEntity> modelEntities = getModelEntitiesFromRecords(entitySyncGroupIncludes, delegator, requireStampFields);
         for (ModelEntity modelEntity: modelEntities) {
             entityNames.add(modelEntity.getEntityName());
diff --git a/framework/entityext/src/org/ofbiz/entityext/data/EntityDataLoadContainer.java b/framework/entityext/src/org/ofbiz/entityext/data/EntityDataLoadContainer.java
index f92a5ac..bc595f8 100644
--- a/framework/entityext/src/org/ofbiz/entityext/data/EntityDataLoadContainer.java
+++ b/framework/entityext/src/org/ofbiz/entityext/data/EntityDataLoadContainer.java
@@ -49,6 +49,7 @@
 import org.ofbiz.entity.jdbc.DatabaseUtil;
 import org.ofbiz.entity.model.ModelEntity;
 import org.ofbiz.entity.util.EntityDataLoader;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.entity.util.EntityUtil;
 import org.ofbiz.service.ServiceDispatcher;
 
@@ -232,7 +233,7 @@
             expr.add(EntityCondition.makeCondition("disabled", EntityOperator.EQUALS, null));
             List<GenericValue> tenantList;
             try {
-                tenantList = delegator.findList("Tenant", EntityCondition.makeCondition(expr, EntityOperator.OR), null, null, null, false);
+                tenantList = EntityQuery.use(delegator).from("Tenant").where(expr, EntityOperator.OR).queryList();
             } catch (GenericEntityException e) {
                 throw new ContainerException(e.getMessage());
             }
@@ -311,7 +312,7 @@
             componentEntry.set("componentName", config.getComponentName());
             componentEntry.set("rootLocation", config.getRootLocation());
             try {
-                GenericValue componentCheck = baseDelegator.findOne("Component", UtilMisc.toMap("componentName", config.getComponentName()), false);
+                GenericValue componentCheck = EntityQuery.use(baseDelegator).from("Component").where("componentName", config.getComponentName()).queryOne();
                 if (UtilValidate.isEmpty(componentCheck)) {
                     componentEntry.create();
                 } else {
@@ -329,14 +330,13 @@
                     for (ComponentConfig config : allComponents) {
                         loadComponents.add(config.getComponentName());
                     }
-                    List<GenericValue> tenantComponents = baseDelegator.findByAnd("TenantComponent", UtilMisc.toMap("tenantId", delegator.getDelegatorTenantId()), UtilMisc.toList("sequenceNum"), false);
+                    List<GenericValue> tenantComponents = EntityQuery.use(baseDelegator).from("TenantComponent").where("tenantId", delegator.getDelegatorTenantId()).orderBy("sequenceNum").queryList();
                     for (GenericValue tenantComponent : tenantComponents) {
                         loadComponents.add(tenantComponent.getString("componentName"));
                     }
                     Debug.logInfo("Loaded components by tenantId : " + delegator.getDelegatorTenantId() + ", " + tenantComponents.size() + " components", module);
                 } else {
-                    List<GenericValue> tenantComponents = baseDelegator.findByAnd("TenantComponent", UtilMisc.toMap("tenantId", delegator.getDelegatorTenantId(), "componentName", this.component),
-                            UtilMisc.toList("sequenceNum"), false);
+                    List<GenericValue> tenantComponents = EntityQuery.use(baseDelegator).from("TenantComponent").where("tenantId", delegator.getDelegatorTenantId(), "componentName", this.component).orderBy("sequenceNum").queryList();
                     for (GenericValue tenantComponent : tenantComponents) {
                         loadComponents.add(tenantComponent.getString("componentName"));
                     }
diff --git a/framework/entityext/src/org/ofbiz/entityext/data/EntityDataServices.java b/framework/entityext/src/org/ofbiz/entityext/data/EntityDataServices.java
index 8de0981..a278108 100644
--- a/framework/entityext/src/org/ofbiz/entityext/data/EntityDataServices.java
+++ b/framework/entityext/src/org/ofbiz/entityext/data/EntityDataServices.java
@@ -45,6 +45,7 @@
 import org.ofbiz.entity.jdbc.DatabaseUtil;
 import org.ofbiz.entity.model.ModelEntity;
 import org.ofbiz.entity.util.EntityListIterator;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.security.Security;
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.GenericServiceException;
@@ -419,7 +420,7 @@
         Locale locale = (Locale) context.get("locale");
         EntityListIterator eli = null;
         try {
-            eli = delegator.find(entityName, null, null, null, null, null);
+            eli = EntityQuery.use(delegator).from(entityName).queryIterator();
             GenericValue currentValue;
             while ((currentValue = eli.next()) != null) {
                 byte[] bytes = currentValue.getBytes(fieldName);
diff --git a/framework/entityext/src/org/ofbiz/entityext/permission/EntityPermissionChecker.java b/framework/entityext/src/org/ofbiz/entityext/permission/EntityPermissionChecker.java
index 79074df..bec461f 100644
--- a/framework/entityext/src/org/ofbiz/entityext/permission/EntityPermissionChecker.java
+++ b/framework/entityext/src/org/ofbiz/entityext/permission/EntityPermissionChecker.java
@@ -265,9 +265,12 @@
         //}
         //EntityCondition opCond = EntityCondition.makeCondition(condList, EntityOperator.OR);
 
-        EntityCondition opCond = EntityCondition.makeCondition(lcEntityName + "OperationId", EntityOperator.IN, targetOperationList);
 
-        List<GenericValue> targetOperationEntityList = delegator.findList(modelOperationEntity.getEntityName(), opCond, null, null, null, true);
+        List<GenericValue> targetOperationEntityList = EntityQuery.use(delegator)
+                                                                  .from(modelOperationEntity.getEntityName())
+                                                                  .where(EntityCondition.makeCondition(lcEntityName + "OperationId", EntityOperator.IN, targetOperationList))
+                                                                  .cache(true)
+                                                                  .queryList();
         Map<String, GenericValue> entities = new HashMap<String, GenericValue>();
         String pkFieldName = modelEntity.getFirstPkFieldName();
 
@@ -609,7 +612,7 @@
             String entityId  = (String)obj;
             if (entities != null) entity = entities.get(entityId);
 
-            if (entity == null) entity = delegator.findOne(entityName,UtilMisc.toMap(pkFieldName, entityId), true);
+            if (entity == null) entity = EntityQuery.use(delegator).from(entityName).where(pkFieldName, entityId).cache(true).queryOne();
         } else if (obj instanceof GenericValue) {
             entity = (GenericValue)obj;
         }
@@ -648,7 +651,7 @@
         if (hasNeed) {
             try {
                 if (UtilValidate.isNotEmpty(partyId)) {
-                    List<GenericValue> partyRoleList = delegator.findByAnd("PartyRole", UtilMisc.toMap("partyId", partyId), null, true);
+                    List<GenericValue> partyRoleList = EntityQuery.use(delegator).from("PartyRole").where("partyId", partyId).cache(true).queryList();
                     for (GenericValue partyRole: partyRoleList) {
                         String roleTypeId = partyRole.getString("roleTypeId");
                         for (String thisRole: newHasRoleList) {
@@ -884,9 +887,6 @@
         //    thruDate = (Timestamp)partyRelationshipValues.get("thruDate") ;
         //}
 
-        EntityExpr partyFromExpr = EntityCondition.makeCondition("partyIdFrom", partyIdFrom);
-        EntityExpr partyToExpr = EntityCondition.makeCondition("partyIdTo", partyIdTo);
-
         //EntityExpr relationExpr = EntityCondition.makeCondition("partyRelationshipTypeId", "CONTENT_PERMISSION");
         //EntityExpr roleTypeIdFromExpr = EntityCondition.makeCondition("roleTypeIdFrom", "CONTENT_PERMISSION_GROUP_MEMBER");
         //EntityExpr roleTypeIdToExpr = EntityCondition.makeCondition("roleTypeIdTo", "CONTENT_PERMISSION_GROUP");
@@ -896,12 +896,10 @@
 
         // This method is simplified to make it work, these conditions need to be added back in.
         //List joinList = UtilMisc.toList(fromExpr, thruCond, partyFromExpr, partyToExpr, relationExpr);
-        List<? extends EntityCondition> joinList = UtilMisc.toList(partyFromExpr, partyToExpr);
-        EntityCondition condition = EntityCondition.makeCondition(joinList);
 
         List<GenericValue> partyRelationships = null;
         try {
-            partyRelationships = delegator.findList("PartyRelationship", condition, null, null, null, false);
+            partyRelationships = EntityQuery.use(delegator).from("PartyRelationship").where("partyIdFrom", partyIdFrom, "partyIdTo", partyIdTo).queryList();
         } catch (GenericEntityException e) {
             Debug.logError(e, "Problem finding PartyRelationships. ", module);
             return false;
@@ -1041,8 +1039,11 @@
         }
 
         public void init(Delegator delegator) throws GenericEntityException {
-            EntityCondition opCond = EntityCondition.makeCondition(operationFieldName, EntityOperator.IN, this.operationList);
-            this.entityList = delegator.findList(this.entityName, opCond, null, null, null, true);
+            this.entityList = EntityQuery.use(delegator)
+                                         .from(this.entityName)
+                                         .where(EntityCondition.makeCondition(operationFieldName, EntityOperator.IN, this.operationList))
+                                         .cache(true)
+                                         .queryList();
         }
 
         public void restart() {
@@ -1180,7 +1181,7 @@
             if (UtilValidate.isEmpty(this.entityName)) {
                 return;
             }
-            List<GenericValue> values = delegator.findByAnd(this.entityName, UtilMisc.toMap(this.entityIdName, entityId), null, true);
+            List<GenericValue> values = EntityQuery.use(delegator).from(this.entityName).where(this.entityIdName, entityId).cache(true).queryList();
             for (GenericValue entity: values) {
                 this.entityList.add(entity.getString(this.auxiliaryFieldName));
             }
@@ -1328,8 +1329,11 @@
 
         EntityExpr expr = EntityCondition.makeCondition(entityIdFieldName, EntityOperator.IN, idList);
         EntityExpr expr2 = EntityCondition.makeCondition(partyIdFieldName, partyId);
-        EntityConditionList<EntityExpr> condList = EntityCondition.makeCondition(UtilMisc.toList(expr, expr2));
-        List<GenericValue> roleList = delegator.findList(entityName, condList, null, null, null, true);
+        List<GenericValue> roleList = EntityQuery.use(delegator)
+                                                 .from(entityName)
+                                                 .where(EntityCondition.makeCondition(UtilMisc.toList(expr, expr2)))
+                                                 .cache(true)
+                                                 .queryList();
         List<GenericValue> roleListFiltered = EntityUtil.filterByDate(roleList);
         Set<String> distinctSet = new HashSet<String>();
         for (GenericValue contentRole: roleListFiltered) {
@@ -1347,7 +1351,7 @@
             contentOwnerList.add(ownerContentId);
             ModelEntity modelEntity = delegator.getModelEntity(entityName);
             String pkFieldName = modelEntity.getFirstPkFieldName();
-            GenericValue ownerContent = delegator.findOne(entityName, UtilMisc.toMap(pkFieldName, ownerContentId), true);
+            GenericValue ownerContent = EntityQuery.use(delegator).from(entityName).where(pkFieldName, ownerContentId).cache(true).queryOne();
             if (ownerContent != null) {
                 getEntityOwners(delegator, ownerContent, contentOwnerList, entityName, ownerIdFieldName);
             }
diff --git a/framework/entityext/src/org/ofbiz/entityext/synchronization/EntitySyncContext.java b/framework/entityext/src/org/ofbiz/entityext/synchronization/EntitySyncContext.java
index 89a4d4c..a366863 100644
--- a/framework/entityext/src/org/ofbiz/entityext/synchronization/EntitySyncContext.java
+++ b/framework/entityext/src/org/ofbiz/entityext/synchronization/EntitySyncContext.java
@@ -57,6 +57,7 @@
 import org.ofbiz.service.ServiceUtil;
 import org.xml.sax.SAXException;
 
+
 /**
  * Entity Engine Sync Services
  */
@@ -348,7 +349,11 @@
                 EntityCondition findValCondition = EntityCondition.makeCondition(
                         EntityCondition.makeCondition(ModelEntity.CREATE_STAMP_TX_FIELD, EntityOperator.GREATER_THAN_EQUAL_TO, currentRunStartTime),
                         EntityCondition.makeCondition(ModelEntity.CREATE_STAMP_TX_FIELD, EntityOperator.LESS_THAN, currentRunEndTime));
-                EntityListIterator eli = delegator.find(modelEntity.getEntityName(), findValCondition, null, null, UtilMisc.toList(ModelEntity.CREATE_STAMP_TX_FIELD, ModelEntity.CREATE_STAMP_FIELD), null);
+                EntityListIterator eli = EntityQuery.use(delegator)
+                                                    .from(modelEntity.getEntityName())
+                                                    .where(findValCondition)
+                                                    .orderBy(ModelEntity.CREATE_STAMP_TX_FIELD, ModelEntity.CREATE_STAMP_FIELD)
+                                                    .queryIterator();
                 GenericValue nextValue = null;
                 long valuesPerEntity = 0;
                 while ((nextValue = eli.next()) != null) {
@@ -377,7 +382,11 @@
                     EntityCondition findNextCondition = EntityCondition.makeCondition(
                             EntityCondition.makeCondition(ModelEntity.CREATE_STAMP_TX_FIELD, EntityOperator.NOT_EQUAL, null),
                             EntityCondition.makeCondition(ModelEntity.CREATE_STAMP_TX_FIELD, EntityOperator.GREATER_THAN_EQUAL_TO, currentRunEndTime));
-                    EntityListIterator eliNext = delegator.find(modelEntity.getEntityName(), findNextCondition, null, null, UtilMisc.toList(ModelEntity.CREATE_STAMP_TX_FIELD), null);
+                    EntityListIterator eliNext = EntityQuery.use(delegator)
+                                                            .from(modelEntity.getEntityName())
+                                                            .where(findNextCondition)
+                                                            .orderBy(ModelEntity.CREATE_STAMP_TX_FIELD)
+                                                            .queryIterator();
                     // get the first element and it's tx time value...
                     GenericValue firstVal = eliNext.next();
                     eliNext.close();
@@ -491,7 +500,11 @@
                         EntityCondition.makeCondition(ModelEntity.STAMP_TX_FIELD, EntityOperator.GREATER_THAN_EQUAL_TO, currentRunStartTime),
                         EntityCondition.makeCondition(ModelEntity.STAMP_TX_FIELD, EntityOperator.LESS_THAN, currentRunEndTime),
                         createdBeforeStartCond);
-                EntityListIterator eli = delegator.find(modelEntity.getEntityName(), findValCondition, null, null, UtilMisc.toList(ModelEntity.STAMP_TX_FIELD, ModelEntity.STAMP_FIELD), null);
+                EntityListIterator eli = EntityQuery.use(delegator)
+                                                    .from(modelEntity.getEntityName())
+                                                    .where(findValCondition)
+                                                    .orderBy(ModelEntity.STAMP_TX_FIELD, ModelEntity.STAMP_FIELD)
+                                                    .queryIterator();
                 GenericValue nextValue = null;
                 long valuesPerEntity = 0;
                 while ((nextValue = eli.next()) != null) {
@@ -522,7 +535,11 @@
                             EntityCondition.makeCondition(ModelEntity.STAMP_TX_FIELD, EntityOperator.GREATER_THAN_EQUAL_TO, currentRunEndTime),
                             EntityCondition.makeCondition(ModelEntity.CREATE_STAMP_TX_FIELD, EntityOperator.NOT_EQUAL, null),
                             EntityCondition.makeCondition(ModelEntity.CREATE_STAMP_TX_FIELD, EntityOperator.LESS_THAN, currentRunEndTime));
-                    EntityListIterator eliNext = delegator.find(modelEntity.getEntityName(), findNextCondition, null, null, UtilMisc.toList(ModelEntity.STAMP_TX_FIELD), null);
+                    EntityListIterator eliNext = EntityQuery.use(delegator)
+                                                            .from(modelEntity.getEntityName())
+                                                            .where(findNextCondition)
+                                                            .orderBy(ModelEntity.STAMP_TX_FIELD)
+                                                            .queryIterator();
                     // get the first element and it's tx time value...
                     GenericValue firstVal = eliNext.next();
                     eliNext.close();
@@ -617,7 +634,11 @@
             EntityCondition findValCondition = EntityCondition.makeCondition(
                     EntityCondition.makeCondition(ModelEntity.STAMP_TX_FIELD, EntityOperator.GREATER_THAN_EQUAL_TO, currentRunStartTime),
                     EntityCondition.makeCondition(ModelEntity.STAMP_TX_FIELD, EntityOperator.LESS_THAN, currentRunEndTime));
-            EntityListIterator removeEli = delegator.find("EntitySyncRemove", findValCondition, null, null, UtilMisc.toList(ModelEntity.STAMP_TX_FIELD, ModelEntity.STAMP_FIELD), null);
+            EntityListIterator removeEli = EntityQuery.use(delegator)
+                                                      .from("EntitySyncRemove")
+                                                      .where(findValCondition)
+                                                      .orderBy(ModelEntity.STAMP_TX_FIELD, ModelEntity.STAMP_FIELD)
+                                                      .queryIterator();
             GenericValue entitySyncRemove = null;
             while ((entitySyncRemove = removeEli.next()) != null) {
                 // pull the PK from the EntitySyncRemove in the primaryKeyRemoved field, de-XML-serialize it
@@ -658,7 +679,11 @@
             // if we didn't find anything for this entity, find the next value's Timestamp and keep track of it
             if (keysToRemove.size() == 0) {
                 EntityCondition findNextCondition = EntityCondition.makeCondition(ModelEntity.STAMP_TX_FIELD, EntityOperator.GREATER_THAN_EQUAL_TO, currentRunEndTime);
-                EntityListIterator eliNext = delegator.find("EntitySyncRemove", findNextCondition, null, null, UtilMisc.toList(ModelEntity.STAMP_TX_FIELD), null);
+                EntityListIterator eliNext = EntityQuery.use(delegator)
+                                                        .from("EntitySyncRemove")
+                                                        .where(findNextCondition)
+                                                        .orderBy(ModelEntity.STAMP_TX_FIELD)
+                                                        .queryIterator();
                 // get the first element and it's tx time value...
                 GenericValue firstVal = eliNext.next();
                 eliNext.close();
@@ -866,7 +891,12 @@
                 Set<String> fieldsToSelect = UtilMisc.toSet(modelEntity.getPkFieldNames());
                 // find all instances of this entity with the STAMP_TX_FIELD != null, sort ascending to get lowest/oldest value first, then grab first and consider as candidate currentRunStartTime
                 fieldsToSelect.add(ModelEntity.STAMP_TX_FIELD);
-                EntityListIterator eli = delegator.find(modelEntity.getEntityName(), EntityCondition.makeCondition(ModelEntity.STAMP_TX_FIELD, EntityOperator.NOT_EQUAL, null), null, fieldsToSelect, UtilMisc.toList(ModelEntity.STAMP_TX_FIELD), null);
+                EntityListIterator eli = EntityQuery.use(delegator)
+                                                    .select(fieldsToSelect)
+                                                    .from(modelEntity.getEntityName())
+                                                    .where(ModelEntity.STAMP_TX_FIELD, EntityOperator.NOT_EQUAL, null)
+                                                    .orderBy(ModelEntity.STAMP_TX_FIELD)
+                                                    .queryIterator();
                 GenericValue nextValue = eli.next();
                 eli.close();
                 if (nextValue != null) {
@@ -1009,7 +1039,7 @@
         } else {
             try {
                 // set the latest values from the EntitySyncHistory, based on the values on the EntitySync
-                GenericValue entitySyncHistory = delegator.findOne("EntitySyncHistory", false, "entitySyncId", entitySyncId, "startDate", startDate);
+                GenericValue entitySyncHistory = EntityQuery.use(delegator).from("EntitySyncHistory").where("entitySyncId", entitySyncId, "startDate", startDate).queryOne();
                 this.toCreateInserted = UtilMisc.toLong(entitySyncHistory.getLong("toCreateInserted"));
                 this.toCreateUpdated = UtilMisc.toLong(entitySyncHistory.getLong("toCreateUpdated"));
                 this.toCreateNotUpdated = UtilMisc.toLong(entitySyncHistory.getLong("toCreateNotUpdated"));
diff --git a/framework/entityext/src/org/ofbiz/entityext/synchronization/EntitySyncServices.java b/framework/entityext/src/org/ofbiz/entityext/synchronization/EntitySyncServices.java
index 7d4290c..1b0d55d 100644
--- a/framework/entityext/src/org/ofbiz/entityext/synchronization/EntitySyncServices.java
+++ b/framework/entityext/src/org/ofbiz/entityext/synchronization/EntitySyncServices.java
@@ -51,6 +51,7 @@
 import org.ofbiz.entity.model.ModelEntity;
 import org.ofbiz.entity.serialize.SerializeException;
 import org.ofbiz.entity.serialize.XmlSerializer;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.entityext.synchronization.EntitySyncContext.SyncAbortException;
 import org.ofbiz.entityext.synchronization.EntitySyncContext.SyncErrorException;
 import org.ofbiz.service.DispatchContext;
@@ -172,7 +173,10 @@
                 // check to make sure all foreign keys are created; if not create dummy values as place holders
                 valueToCreate.checkFks(true);
 
-                GenericValue existingValue = delegator.findOne(valueToCreate.getEntityName(), valueToCreate.getPrimaryKey(), false);
+                GenericValue existingValue = EntityQuery.use(delegator)
+                                                        .from(valueToCreate.getEntityName())
+                                                        .where(valueToCreate.getPrimaryKey())
+                                                        .queryOne();
                 if (existingValue == null) {
                     delegator.create(valueToCreate);
                     toCreateInserted++;
@@ -197,7 +201,10 @@
                 // check to make sure all foreign keys are created; if not create dummy values as place holders
                 valueToStore.checkFks(true);
 
-                GenericValue existingValue = delegator.findOne(valueToStore.getEntityName(), valueToStore.getPrimaryKey(), false);
+                GenericValue existingValue = EntityQuery.use(delegator)
+                                                        .from(valueToStore.getEntityName())
+                                                        .where(valueToStore.getPrimaryKey())
+                                                        .queryOne();
                 if (existingValue == null) {
                     delegator.create(valueToStore);
                     toStoreInserted++;
@@ -596,7 +603,7 @@
             // find the largest keepRemoveInfoHours value on an EntitySyncRemove and kill everything before that, if none found default to 10 days (240 hours)
             double keepRemoveInfoHours = 24;
 
-            List<GenericValue> entitySyncRemoveList = delegator.findList("EntitySync", null, null, null, null, false);
+            List<GenericValue> entitySyncRemoveList = EntityQuery.use(delegator).from("EntitySync").queryList();
             for (GenericValue entitySyncRemove: entitySyncRemoveList) {
                 Double curKrih = entitySyncRemove.getDouble("keepRemoveInfoHours");
                 if (curKrih != null) {
diff --git a/framework/minilang/config/DefaultMessages.xml b/framework/minilang/config/DefaultMessages.xml
index eb27878..64ad242 100644
--- a/framework/minilang/config/DefaultMessages.xml
+++ b/framework/minilang/config/DefaultMessages.xml
@@ -26,7 +26,7 @@
         <value xml:lang="ja">エラー:</value>
         <value xml:lang="nl">Fout: </value>
         <value xml:lang="zh">错误:</value>
-        <value xml:lang="zh-TW">錯誤:</value>
+        <value xml:lang="zh_TW">錯誤:</value>
     </property>
     <property key="check.error.suffix">
         <value xml:lang="en"> </value>
@@ -49,7 +49,7 @@
         <value xml:lang="ru">Действие выполнено успешно.</value>
         <value xml:lang="th">การปฏิบัติหน้าที่เสร็จสมบูรณ์แล้ว</value>
         <value xml:lang="zh">已成功执行本操作。</value>
-        <value xml:lang="zh-TW">已成功執行本操作.</value>
+        <value xml:lang="zh_TW">已成功執行本操作.</value>
     </property>
     <property key="service.error.prefix">
         <value xml:lang="de">Fehler: </value>
@@ -59,7 +59,7 @@
         <value xml:lang="ja">エラー:</value>
         <value xml:lang="nl">Fout: </value>
         <value xml:lang="zh">错误:</value>
-        <value xml:lang="zh-TW">錯誤:</value>
+        <value xml:lang="zh_TW">錯誤:</value>
     </property>
     <property key="service.error.suffix">
         <value xml:lang="en"> </value>
diff --git a/framework/minilang/src/org/ofbiz/minilang/method/entityops/EntityCount.java b/framework/minilang/src/org/ofbiz/minilang/method/entityops/EntityCount.java
index 2fb1264..ccce878 100644
--- a/framework/minilang/src/org/ofbiz/minilang/method/entityops/EntityCount.java
+++ b/framework/minilang/src/org/ofbiz/minilang/method/entityops/EntityCount.java
@@ -30,6 +30,7 @@
 import org.ofbiz.entity.finder.EntityFinderUtil.ConditionList;
 import org.ofbiz.entity.finder.EntityFinderUtil.ConditionObject;
 import org.ofbiz.entity.model.ModelEntity;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.minilang.MiniLangException;
 import org.ofbiz.minilang.MiniLangValidate;
 import org.ofbiz.minilang.SimpleMethod;
@@ -103,7 +104,7 @@
             if (this.havingCondition != null) {
                 havingEntityCondition = this.havingCondition.createCondition(methodContext.getEnvMap(), modelEntity, delegator.getModelFieldTypeReader(modelEntity));
             }
-            long count = delegator.findCountByCondition(entityName, whereEntityCondition, havingEntityCondition, null);
+            long count = EntityQuery.use(delegator).from(entityName).where(whereEntityCondition).having(havingEntityCondition).queryCount();
             this.countFma.put(methodContext.getEnvMap(), count);
         } catch (GeneralException e) {
             String errMsg = "Exception thrown while performing entity count: " + e.getMessage();
diff --git a/framework/minilang/src/org/ofbiz/minilang/method/entityops/FindByAnd.java b/framework/minilang/src/org/ofbiz/minilang/method/entityops/FindByAnd.java
index cbca8d4..e73b8cc 100644
--- a/framework/minilang/src/org/ofbiz/minilang/method/entityops/FindByAnd.java
+++ b/framework/minilang/src/org/ofbiz/minilang/method/entityops/FindByAnd.java
@@ -29,6 +29,7 @@
 import org.ofbiz.entity.Delegator;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.condition.EntityCondition;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.minilang.MiniLangException;
 import org.ofbiz.minilang.MiniLangValidate;
 import org.ofbiz.minilang.SimpleMethod;
@@ -76,7 +77,6 @@
         boolean useCache = "true".equals(useCacheFse.expandString(methodContext.getEnvMap()));
         boolean useIterator = "true".equals(useIteratorFse.expandString(methodContext.getEnvMap()));
         List<String> orderByNames = orderByListFma.get(methodContext.getEnvMap());
-        Collection<String> fieldsToSelectList = fieldsToSelectListFma.get(methodContext.getEnvMap());
         Delegator delegator = getDelegator(methodContext);
         try {
             EntityCondition whereCond = null;
@@ -85,9 +85,20 @@
                 whereCond = EntityCondition.makeCondition(fieldMap);
             }
             if (useIterator) {
-                listFma.put(methodContext.getEnvMap(), delegator.find(entityName, whereCond, null, UtilMisc.toSet(fieldsToSelectList), orderByNames, null));
+                listFma.put(methodContext.getEnvMap(), EntityQuery.use(delegator)
+                                                                  .select(UtilMisc.toSet(fieldsToSelectListFma.get(methodContext.getEnvMap())))
+                                                                  .from(entityName)
+                                                                  .where(whereCond)
+                                                                  .orderBy(orderByNames)
+                                                                  .queryList());
             } else {
-                listFma.put(methodContext.getEnvMap(), delegator.findList(entityName, whereCond, UtilMisc.toSet(fieldsToSelectList), orderByNames, null, useCache));
+                listFma.put(methodContext.getEnvMap(), EntityQuery.use(delegator)
+                                                                  .select(UtilMisc.toSet(fieldsToSelectListFma.get(methodContext.getEnvMap())))
+                                                                  .from(entityName)
+                                                                  .where(whereCond)
+                                                                  .orderBy(orderByNames)
+                                                                  .cache(useCache)
+                                                                  .queryList());
             }
         } catch (GenericEntityException e) {
             String errMsg = "Exception thrown while performing entity find: " + e.getMessage();
diff --git a/framework/minilang/src/org/ofbiz/minilang/method/entityops/FindByPrimaryKey.java b/framework/minilang/src/org/ofbiz/minilang/method/entityops/FindByPrimaryKey.java
index e1464dd..d27a8b8 100644
--- a/framework/minilang/src/org/ofbiz/minilang/method/entityops/FindByPrimaryKey.java
+++ b/framework/minilang/src/org/ofbiz/minilang/method/entityops/FindByPrimaryKey.java
@@ -29,6 +29,7 @@
 import org.ofbiz.entity.GenericEntity;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.minilang.MiniLangException;
 import org.ofbiz.minilang.MiniLangRuntimeException;
 import org.ofbiz.minilang.MiniLangValidate;
@@ -88,7 +89,7 @@
             if (fieldsToSelectList != null) {
                 valueFma.put(methodContext.getEnvMap(), delegator.findByPrimaryKeyPartial(delegator.makePK(entityName, inMap), UtilMisc.toSet(fieldsToSelectList)));
             } else {
-                valueFma.put(methodContext.getEnvMap(), delegator.findOne(entityName, inMap, useCache));
+                valueFma.put(methodContext.getEnvMap(), EntityQuery.use(delegator).from(entityName).where(inMap).cache(useCache).queryOne());
             }
         } catch (GenericEntityException e) {
             String errMsg = "Exception thrown while performing entity find: " + e.getMessage();
diff --git a/framework/minilang/src/org/ofbiz/minilang/method/entityops/RefreshValue.java b/framework/minilang/src/org/ofbiz/minilang/method/entityops/RefreshValue.java
index a3d71e5..5effce3 100644
--- a/framework/minilang/src/org/ofbiz/minilang/method/entityops/RefreshValue.java
+++ b/framework/minilang/src/org/ofbiz/minilang/method/entityops/RefreshValue.java
@@ -20,7 +20,6 @@
 
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.collections.FlexibleMapAccessor;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.minilang.MiniLangException;
@@ -40,8 +39,6 @@
 
     public static final String module = RemoveValue.class.getName();
 
-    @Deprecated
-    private final FlexibleStringExpander doCacheClearFse;
     private final FlexibleMapAccessor<GenericValue> valueFma;
 
     public RefreshValue(Element element, SimpleMethod simpleMethod) throws MiniLangException {
@@ -53,7 +50,6 @@
             MiniLangValidate.noChildElements(simpleMethod, element);
         }
         valueFma = FlexibleMapAccessor.getInstance(element.getAttribute("value-field"));
-        doCacheClearFse = FlexibleStringExpander.getInstance(element.getAttribute("do-cache-clear"));
     }
 
     @Override
@@ -62,7 +58,6 @@
         if (value == null) {
             throw new MiniLangRuntimeException("Entity value not found with name: " + valueFma, this);
         }
-        boolean doCacheClear = !"false".equals(doCacheClearFse.expandString(methodContext.getEnvMap()));
         try {
             value.getDelegator().refresh(value);
         } catch (GenericEntityException e) {
@@ -78,9 +73,6 @@
     public String toString() {
         StringBuilder sb = new StringBuilder("<refresh-value ");
         sb.append("value-field=\"").append(this.valueFma).append("\" ");
-        if (!doCacheClearFse.isEmpty()) {
-            sb.append("do-cache-clear=\"").append(this.doCacheClearFse).append("\" ");
-        }
         sb.append("/>");
         return sb.toString();
     }
diff --git a/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveByAnd.java b/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveByAnd.java
index b23f9da..628abea 100644
--- a/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveByAnd.java
+++ b/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveByAnd.java
@@ -41,8 +41,6 @@
 public final class RemoveByAnd extends EntityOperation {
 
     public static final String module = RemoveByAnd.class.getName();
-    @Deprecated
-    private final FlexibleStringExpander doCacheClearFse;
     private final FlexibleStringExpander entityNameFse;
     private final FlexibleMapAccessor<Map<String, ? extends Object>> mapFma;
 
@@ -56,20 +54,18 @@
         }
         entityNameFse = FlexibleStringExpander.getInstance(element.getAttribute("entity-name"));
         mapFma = FlexibleMapAccessor.getInstance(element.getAttribute("map"));
-        doCacheClearFse = FlexibleStringExpander.getInstance(element.getAttribute("do-cache-clear"));
     }
 
     @Override
     public boolean exec(MethodContext methodContext) throws MiniLangException {
         @Deprecated
-        boolean doCacheClear = !"false".equals(doCacheClearFse.expandString(methodContext.getEnvMap()));
         String entityName = entityNameFse.expandString(methodContext.getEnvMap());
         if (entityName.isEmpty()) {
             throw new MiniLangRuntimeException("Entity name not found.", this);
         }
         try {
             Delegator delegator = getDelegator(methodContext);
-            delegator.removeByAnd(entityName, mapFma.get(methodContext.getEnvMap()), doCacheClear);
+            delegator.removeByAnd(entityName, mapFma.get(methodContext.getEnvMap()));
         } catch (GenericEntityException e) {
             String errMsg = "Exception thrown while removing entities: " + e.getMessage();
             Debug.logWarning(e, errMsg, module);
@@ -89,9 +85,6 @@
         StringBuilder sb = new StringBuilder("<remove-by-and ");
         sb.append("entity-name=\"").append(this.entityNameFse).append("\" ");
         sb.append("map=\"").append(this.mapFma).append("\" ");
-        if (!doCacheClearFse.isEmpty()) {
-            sb.append("do-cache-clear=\"").append(this.doCacheClearFse).append("\" ");
-        }
         sb.append("/>");
         return sb.toString();
     }
diff --git a/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveList.java b/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveList.java
index 6549abd..8ac162e 100644
--- a/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveList.java
+++ b/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveList.java
@@ -22,7 +22,6 @@
 
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.collections.FlexibleMapAccessor;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.Delegator;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
@@ -41,8 +40,6 @@
 public final class RemoveList extends EntityOperation {
 
     public static final String module = RemoveList.class.getName();
-    @Deprecated
-    private final FlexibleStringExpander doCacheClearFse;
     private final FlexibleMapAccessor<List<GenericValue>> listFma;
 
     public RemoveList(Element element, SimpleMethod simpleMethod) throws MiniLangException {
@@ -54,7 +51,6 @@
             MiniLangValidate.noChildElements(simpleMethod, element);
         }
         listFma = FlexibleMapAccessor.getInstance(element.getAttribute("list"));
-        doCacheClearFse = FlexibleStringExpander.getInstance(element.getAttribute("do-cache-clear"));
     }
 
     @Override
@@ -63,8 +59,6 @@
         if (values == null) {
             throw new MiniLangRuntimeException("Entity value list not found with name: " + listFma, this);
         }
-        @Deprecated
-        boolean doCacheClear = !"false".equals(doCacheClearFse.expandString(methodContext.getEnvMap()));
         try {
             Delegator delegator = getDelegator(methodContext);
             delegator.removeAll(values);
@@ -81,9 +75,6 @@
     public String toString() {
         StringBuilder sb = new StringBuilder("<remove-list ");
         sb.append("list=\"").append(this.listFma).append("\" ");
-        if (!doCacheClearFse.isEmpty()) {
-            sb.append("do-cache-clear=\"").append(this.doCacheClearFse).append("\" ");
-        }
         sb.append("/>");
         return sb.toString();
     }
diff --git a/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveRelated.java b/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveRelated.java
index eb7a180..decb129 100644
--- a/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveRelated.java
+++ b/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveRelated.java
@@ -40,8 +40,6 @@
 public final class RemoveRelated extends MethodOperation {
 
     public static final String module = RemoveRelated.class.getName();
-    @Deprecated
-    private final FlexibleStringExpander doCacheClearFse;
     private final FlexibleStringExpander relationNameFse;
     private final FlexibleMapAccessor<GenericValue> valueFma;
 
@@ -55,7 +53,6 @@
         }
         valueFma = FlexibleMapAccessor.getInstance(element.getAttribute("value-field"));
         relationNameFse = FlexibleStringExpander.getInstance(element.getAttribute("relation-name"));
-        doCacheClearFse = FlexibleStringExpander.getInstance(element.getAttribute("do-cache-clear"));
     }
 
     @Override
@@ -65,8 +62,6 @@
             throw new MiniLangRuntimeException("Entity value not found with name: " + valueFma, this);
         }
         String relationName = relationNameFse.expandString(methodContext.getEnvMap());
-        @Deprecated
-        boolean doCacheClear = !"false".equals(doCacheClearFse.expandString(methodContext.getEnvMap()));
         try {
             value.getDelegator().removeRelated(relationName, value);
         } catch (GenericEntityException e) {
@@ -88,9 +83,6 @@
         StringBuilder sb = new StringBuilder("<remove-related ");
         sb.append("value-field=\"").append(this.valueFma).append("\" ");
         sb.append("relation-name=\"").append(this.relationNameFse).append("\" ");
-        if (!doCacheClearFse.isEmpty()) {
-            sb.append("do-cache-clear=\"").append(this.doCacheClearFse).append("\" ");
-        }
         sb.append("/>");
         return sb.toString();
     }
diff --git a/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveValue.java b/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveValue.java
index dbd0cfd..93f2408 100644
--- a/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveValue.java
+++ b/framework/minilang/src/org/ofbiz/minilang/method/entityops/RemoveValue.java
@@ -20,7 +20,6 @@
 
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.collections.FlexibleMapAccessor;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.minilang.MiniLangException;
@@ -39,8 +38,6 @@
 public final class RemoveValue extends MethodOperation {
 
     public static final String module = RemoveValue.class.getName();
-    @Deprecated
-    private final FlexibleStringExpander doCacheClearFse;
     private final FlexibleMapAccessor<GenericValue> valueFma;
 
     public RemoveValue(Element element, SimpleMethod simpleMethod) throws MiniLangException {
@@ -52,7 +49,6 @@
             MiniLangValidate.noChildElements(simpleMethod, element);
         }
         valueFma = FlexibleMapAccessor.getInstance(element.getAttribute("value-field"));
-        doCacheClearFse = FlexibleStringExpander.getInstance(element.getAttribute("do-cache-clear"));
     }
 
     @Override
@@ -61,8 +57,6 @@
         if (value == null) {
             throw new MiniLangRuntimeException("Entity value not found with name: " + valueFma, this);
         }
-        @Deprecated
-        boolean doCacheClear = !"false".equals(doCacheClearFse.expandString(methodContext.getEnvMap()));
         try {
             value.getDelegator().removeValue(value);
         } catch (GenericEntityException e) {
@@ -78,9 +72,6 @@
     public String toString() {
         StringBuilder sb = new StringBuilder("<remove-value ");
         sb.append("value-field=\"").append(this.valueFma).append("\" ");
-        if (!doCacheClearFse.isEmpty()) {
-            sb.append("do-cache-clear=\"").append(this.doCacheClearFse).append("\" ");
-        }
         sb.append("/>");
         return sb.toString();
     }
diff --git a/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreList.java b/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreList.java
index c921f55..3c58ac5 100644
--- a/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreList.java
+++ b/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreList.java
@@ -22,7 +22,6 @@
 
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.collections.FlexibleMapAccessor;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.Delegator;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
@@ -41,8 +40,6 @@
 public final class StoreList extends EntityOperation {
 
     public static final String module = StoreList.class.getName();
-    @Deprecated
-    private final FlexibleStringExpander doCacheClearFse;
     private final FlexibleMapAccessor<List<GenericValue>> listFma;
 
     public StoreList(Element element, SimpleMethod simpleMethod) throws MiniLangException {
@@ -54,7 +51,6 @@
             MiniLangValidate.noChildElements(simpleMethod, element);
         }
         listFma = FlexibleMapAccessor.getInstance(element.getAttribute("list"));
-        doCacheClearFse = FlexibleStringExpander.getInstance(element.getAttribute("do-cache-clear"));
     }
 
     @Override
@@ -63,8 +59,6 @@
         if (values == null) {
             throw new MiniLangRuntimeException("Entity value list not found with name: " + listFma, this);
         }
-        @Deprecated
-        boolean doCacheClear = !"false".equals(doCacheClearFse.expandString(methodContext.getEnvMap()));
         try {
             Delegator delegator = getDelegator(methodContext);
             delegator.storeAll(values);
@@ -81,9 +75,6 @@
     public String toString() {
         StringBuilder sb = new StringBuilder("<store-list ");
         sb.append("list=\"").append(this.listFma).append("\" ");
-        if (!doCacheClearFse.isEmpty()) {
-            sb.append("do-cache-clear=\"").append(this.doCacheClearFse).append("\" ");
-        }
         sb.append("/>");
         return sb.toString();
     }
diff --git a/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreValue.java b/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreValue.java
index b33f235..4d2c18f 100644
--- a/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreValue.java
+++ b/framework/minilang/src/org/ofbiz/minilang/method/entityops/StoreValue.java
@@ -20,7 +20,6 @@
 
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.collections.FlexibleMapAccessor;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.minilang.MiniLangException;
@@ -39,8 +38,6 @@
 public final class StoreValue extends MethodOperation {
 
     public static final String module = StoreValue.class.getName();
-    @Deprecated
-    private final FlexibleStringExpander doCacheClearFse;
     private final FlexibleMapAccessor<GenericValue> valueFma;
 
     public StoreValue(Element element, SimpleMethod simpleMethod) throws MiniLangException {
@@ -52,7 +49,6 @@
             MiniLangValidate.noChildElements(simpleMethod, element);
         }
         valueFma = FlexibleMapAccessor.getInstance(element.getAttribute("value-field"));
-        doCacheClearFse = FlexibleStringExpander.getInstance(element.getAttribute("do-cache-clear"));
     }
 
     @Override
@@ -61,8 +57,6 @@
         if (value == null) {
             throw new MiniLangRuntimeException("Entity value not found with name: " + valueFma, this);
         }
-        @Deprecated
-        boolean doCacheClear = !"false".equals(doCacheClearFse.expandString(methodContext.getEnvMap()));
         try {
             value.getDelegator().store(value);
         } catch (GenericEntityException e) {
@@ -78,9 +72,6 @@
     public String toString() {
         StringBuilder sb = new StringBuilder("<store-value ");
         sb.append("value-field=\"").append(this.valueFma).append("\" ");
-        if (!doCacheClearFse.isEmpty()) {
-            sb.append("do-cache-clear=\"").append(this.doCacheClearFse).append("\" ");
-        }
         sb.append("/>");
         return sb.toString();
     }
diff --git a/framework/resources/fonts/NotoSans/NotoSans-Bold.ttf b/framework/resources/fonts/NotoSans/NotoSans-Bold.ttf
new file mode 100644
index 0000000..120ee53
--- /dev/null
+++ b/framework/resources/fonts/NotoSans/NotoSans-Bold.ttf
Binary files differ
diff --git a/framework/resources/fonts/NotoSans/NotoSans-BoldItalic.ttf b/framework/resources/fonts/NotoSans/NotoSans-BoldItalic.ttf
new file mode 100644
index 0000000..a35b9c4
--- /dev/null
+++ b/framework/resources/fonts/NotoSans/NotoSans-BoldItalic.ttf
Binary files differ
diff --git a/framework/resources/fonts/NotoSans/NotoSans-Italic.ttf b/framework/resources/fonts/NotoSans/NotoSans-Italic.ttf
new file mode 100644
index 0000000..7388e2b
--- /dev/null
+++ b/framework/resources/fonts/NotoSans/NotoSans-Italic.ttf
Binary files differ
diff --git a/framework/resources/fonts/NotoSans/NotoSans-Regular.ttf b/framework/resources/fonts/NotoSans/NotoSans-Regular.ttf
new file mode 100644
index 0000000..04a2f52
--- /dev/null
+++ b/framework/resources/fonts/NotoSans/NotoSans-Regular.ttf
Binary files differ
diff --git a/framework/security/src/org/ofbiz/security/SecurityFactory.java b/framework/security/src/org/ofbiz/security/SecurityFactory.java
index ece1b49..b1d86c5 100644
--- a/framework/security/src/org/ofbiz/security/SecurityFactory.java
+++ b/framework/security/src/org/ofbiz/security/SecurityFactory.java
@@ -38,6 +38,7 @@
 import org.ofbiz.entity.condition.EntityConditionList;
 import org.ofbiz.entity.condition.EntityExpr;
 import org.ofbiz.entity.condition.EntityOperator;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.entity.util.EntityUtil;
 
 /**
@@ -104,7 +105,7 @@
         @Override
         public Iterator<GenericValue> findUserLoginSecurityGroupByUserLoginId(String userLoginId) {
             try {
-                List<GenericValue> collection = EntityUtil.filterByDate(delegator.findByAnd("UserLoginSecurityGroup", UtilMisc.toMap("userLoginId", userLoginId), null, true));
+                List<GenericValue> collection = EntityUtil.filterByDate(EntityQuery.use(delegator).from("UserLoginSecurityGroup").where("userLoginId", userLoginId).cache(true).queryList());
                 return collection.iterator();
             } catch (GenericEntityException e) {
                 Debug.logWarning(e, module);
@@ -197,7 +198,7 @@
             if (hasEntityPermission(application + "_ROLE", action, userLogin)) {
                 // we have the permission now, we check to make sure we are allowed access
                 try {
-                    List<GenericValue> roleTest = delegator.findList(entityName, condition, null, null, null, false);
+                    List<GenericValue> roleTest = EntityQuery.use(delegator).from(entityName).where(condition).queryList();
                     if (!roleTest.isEmpty()) {
                         return true;
                     }
@@ -263,7 +264,7 @@
         @Override
         public boolean securityGroupPermissionExists(String groupId, String permission) {
             try {
-                return delegator.findOne("SecurityGroupPermission",  UtilMisc.toMap("groupId", groupId, "permissionId", permission), true) != null;
+                return EntityQuery.use(delegator).from("SecurityGroupPermission").where("groupId", groupId, "permissionId", permission).cache(true).queryOne() != null;
             } catch (GenericEntityException e) {
                 Debug.logWarning(e, module);
                 return false;
diff --git a/framework/service/src/org/ofbiz/service/ModelService.java b/framework/service/src/org/ofbiz/service/ModelService.java
index b3ec763..03f9916 100644
--- a/framework/service/src/org/ofbiz/service/ModelService.java
+++ b/framework/service/src/org/ofbiz/service/ModelService.java
@@ -63,7 +63,7 @@
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.GeneralException;
 import org.ofbiz.base.util.ObjectType;
-import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
 import org.ofbiz.base.util.UtilMisc;
 import org.ofbiz.base.util.UtilProperties;
 import org.ofbiz.base.util.UtilValidate;
@@ -584,7 +584,7 @@
                 if (context.get(modelParam.name) != null && ("String".equals(modelParam.type) || "java.lang.String".equals(modelParam.type)) 
                         && !"any".equals(modelParam.allowHtml) && ("INOUT".equals(modelParam.mode) || "IN".equals(modelParam.mode))) {
                     String value = (String) context.get(modelParam.name);
-                    StringUtil.checkStringForHtmlStrictNone(modelParam.name, value, errorMessageList);
+                    UtilCodec.checkStringForHtmlStrictNone(modelParam.name, value, errorMessageList);
                 }
             }
             if (errorMessageList.size() > 0) {
diff --git a/framework/service/src/org/ofbiz/service/ServiceUtil.java b/framework/service/src/org/ofbiz/service/ServiceUtil.java
index 4fab7c2..4b9ce81 100644
--- a/framework/service/src/org/ofbiz/service/ServiceUtil.java
+++ b/framework/service/src/org/ofbiz/service/ServiceUtil.java
@@ -45,7 +45,6 @@
 import org.ofbiz.entity.condition.EntityOperator;
 import org.ofbiz.entity.transaction.GenericTransactionException;
 import org.ofbiz.entity.transaction.TransactionUtil;
-import org.ofbiz.entity.util.EntityFindOptions;
 import org.ofbiz.entity.util.EntityListIterator;
 import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.security.Security;
@@ -399,12 +398,6 @@
         EntityCondition finished = EntityCondition.makeCondition(finExp);
 
         EntityCondition doneCond = EntityCondition.makeCondition(UtilMisc.toList(cancelled, finished), EntityOperator.OR);
-        EntityCondition mainCond = EntityCondition.makeCondition(UtilMisc.toList(doneCond, pool));
-
-        // configure the find options
-        EntityFindOptions findOptions = new EntityFindOptions();
-        findOptions.setResultSetType(EntityFindOptions.TYPE_SCROLL_INSENSITIVE);
-        findOptions.setMaxRows(1000);
 
         // always suspend the current transaction; use the one internally
         Transaction parent = null;
@@ -426,7 +419,13 @@
 
                     EntityListIterator foundJobs = null;
                     try {
-                        foundJobs = delegator.find("JobSandbox", mainCond, null, UtilMisc.toSet("jobId"), null, findOptions);
+                        foundJobs = EntityQuery.use(delegator)
+                                               .select("jobId")
+                                               .from("JobSandbox")
+                                               .where(EntityCondition.makeCondition(UtilMisc.toList(doneCond, pool)))
+                                               .cursorScrollInsensitive()
+                                               .maxRows(1000)
+                                               .queryIterator();
                         curList = foundJobs.getPartialList(1, 1000);
                     } finally {
                         if (foundJobs != null) {
@@ -486,12 +485,12 @@
                 // begin this transaction
                 beganTx3 = TransactionUtil.begin();
 
-                runTimeDataIt = delegator.find("RuntimeData", null, null, UtilMisc.toSet("runtimeDataId"), null, null);
+                runTimeDataIt = EntityQuery.use(delegator).select("runtimeDataId").from("RuntimeData").queryIterator();
                 try {
                     while ((runtimeData = runTimeDataIt.next()) != null) {
                         EntityCondition whereCondition = EntityCondition.makeCondition(UtilMisc.toList(EntityCondition.makeCondition("runtimeDataId", EntityOperator.NOT_EQUAL, null),
                                 EntityCondition.makeCondition("runtimeDataId", EntityOperator.EQUALS, runtimeData.getString("runtimeDataId"))), EntityOperator.AND);
-                        jobsandBoxCount = delegator.findCountByCondition("JobSandbox", whereCondition, null, null);
+                        jobsandBoxCount = EntityQuery.use(delegator).from("JobSandbox").where(whereCondition).queryCount();
                         if (BigDecimal.ZERO.compareTo(BigDecimal.valueOf(jobsandBoxCount)) == 0) {
                             runtimeDataToDelete.add(runtimeData);
                         }
@@ -548,7 +547,7 @@
 
         GenericValue job = null;
         try {
-            job = delegator.findOne("JobSandbox", fields, false);
+            job = EntityQuery.use(delegator).from("JobSandbox").where("jobId", jobId).queryOne();
             if (job != null) {
                 job.set("cancelDateTime", UtilDateTime.nowTimestamp());
                 job.set("statusId", "SERVICE_CANCELLED");
@@ -587,7 +586,7 @@
 
         GenericValue job = null;
         try {
-            job = delegator.findOne("JobSandbox", fields, false);
+            job = EntityQuery.use(delegator).from("JobSandbox").where("jobId", jobId).queryOne();
             if (job != null) {
                 job.set("maxRetry", Long.valueOf(0));
                 job.store();
@@ -666,10 +665,9 @@
         }
 
         String jobId = (String) context.get("jobId");
-        Map<String, ? extends Object> fields = UtilMisc.toMap("jobId", jobId);
         GenericValue job;
         try {
-            job = delegator.findOne("JobSandbox", fields, false);
+            job = EntityQuery.use(delegator).from("JobSandbox").where("jobId", jobId).cache().queryOne();
         } catch (GenericEntityException e) {
             Debug.logError(e, module);
             return ServiceUtil.returnError(e.getMessage());
diff --git a/framework/service/src/org/ofbiz/service/calendar/ExpressionUiHelper.java b/framework/service/src/org/ofbiz/service/calendar/ExpressionUiHelper.java
index f79e3a8..a6e03ec 100644
--- a/framework/service/src/org/ofbiz/service/calendar/ExpressionUiHelper.java
+++ b/framework/service/src/org/ofbiz/service/calendar/ExpressionUiHelper.java
@@ -32,6 +32,7 @@
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.condition.EntityCondition;
+import org.ofbiz.entity.util.EntityQuery;
 
 import com.ibm.icu.util.Calendar;
 
@@ -140,13 +141,17 @@
      * @return Set of candidate tempExprId Strings
      */
     public static Set<String> getCandidateIncludeIds(Delegator delegator, String tempExprId) throws GenericEntityException {
-        List<GenericValue> findList = delegator.findList("TemporalExpressionAssoc", EntityCondition.makeCondition("fromTempExprId", tempExprId), null, null, null, true);
+        List<GenericValue> findList = EntityQuery.use(delegator)
+                                                 .from("TemporalExpressionAssoc")
+                                                 .where("fromTempExprId", tempExprId)
+                                                 .cache(true)
+                                                 .queryList();
         Set<String> excludedIds = new HashSet<String>();
         for (GenericValue value : findList) {
             excludedIds.add(value.getString("toTempExprId"));
         }
         excludedIds.add(tempExprId);
-        findList = delegator.findList("TemporalExpression", null, null, null, null, true);
+        findList = EntityQuery.use(delegator).from("TemporalExpression").cache(true).queryList();
         Set<String> candidateIds = new HashSet<String>();
         for (GenericValue value : findList) {
             candidateIds.add(value.getString("tempExprId"));
diff --git a/framework/service/src/org/ofbiz/service/calendar/TemporalExpressionWorker.java b/framework/service/src/org/ofbiz/service/calendar/TemporalExpressionWorker.java
index 3aca4e2..f795f40 100644
--- a/framework/service/src/org/ofbiz/service/calendar/TemporalExpressionWorker.java
+++ b/framework/service/src/org/ofbiz/service/calendar/TemporalExpressionWorker.java
@@ -94,7 +94,7 @@
         } else if (DayOfWeekRange.equals(tempExprTypeId)) {
             return setExpressionId(exprValue, new TemporalExpressions.DayOfWeekRange(exprValue.getLong("integer1").intValue(), exprValue.getLong("integer2").intValue()));
         } else if (Difference.equals(tempExprTypeId)) {
-            List<GenericValue> childExpressions = delegator.findList("TemporalExpressionAssoc", EntityCondition.makeCondition("fromTempExprId", tempExprId), null, null, null, true);
+            List<GenericValue> childExpressions = EntityQuery.use(delegator).from("TemporalExpressionAssoc").where("fromTempExprId", tempExprId).cache(true).queryList();
             GenericValue inclAssoc = null;
             GenericValue exclAssoc = null;
             for (GenericValue childExpression : childExpressions) {
@@ -118,7 +118,7 @@
         } else if (MonthRange.equals(tempExprTypeId)) {
             return setExpressionId(exprValue, new TemporalExpressions.MonthRange(exprValue.getLong("integer1").intValue(), exprValue.getLong("integer2").intValue()));
         } else if (Substitution.equals(tempExprTypeId)) {
-            List<GenericValue> childExpressions = delegator.findList("TemporalExpressionAssoc", EntityCondition.makeCondition("fromTempExprId", tempExprId), null, null, null, true);
+            List<GenericValue> childExpressions = EntityQuery.use(delegator).from("TemporalExpressionAssoc").where("fromTempExprId", tempExprId).cache(true).queryList();
             GenericValue inclAssoc = null;
             GenericValue exclAssoc = null;
             GenericValue substAssoc = null;
@@ -141,7 +141,7 @@
     }
 
     protected static Set<TemporalExpression> getChildExpressions(Delegator delegator, String tempExprId) throws GenericEntityException {
-        List<GenericValue> valueList = delegator.findList("TemporalExpressionAssoc", EntityCondition.makeCondition("fromTempExprId", tempExprId), null, null, null, true);
+        List<GenericValue> valueList = EntityQuery.use(delegator).from("TemporalExpressionAssoc").where("fromTempExprId", tempExprId).cache(true).queryList();
         if (UtilValidate.isEmpty(valueList)) {
             throw new IllegalArgumentException("tempExprId argument invalid - no child expressions found");
         }
diff --git a/framework/service/src/org/ofbiz/service/job/JobManager.java b/framework/service/src/org/ofbiz/service/job/JobManager.java
index e8b45b4..d8d9b17 100644
--- a/framework/service/src/org/ofbiz/service/job/JobManager.java
+++ b/framework/service/src/org/ofbiz/service/job/JobManager.java
@@ -45,6 +45,7 @@
 import org.ofbiz.entity.serialize.XmlSerializer;
 import org.ofbiz.entity.transaction.TransactionUtil;
 import org.ofbiz.entity.util.EntityListIterator;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.LocalDispatcher;
 import org.ofbiz.service.ServiceContainer;
@@ -191,7 +192,7 @@
                 Debug.logWarning("Unable to poll JobSandbox for jobs; unable to begin transaction.", module);
                 return poll;
             }
-            jobsIterator = delegator.find("JobSandbox", mainCondition, null, null, UtilMisc.toList("runTime"), null);
+            jobsIterator = EntityQuery.use(delegator).from("JobSandbox").where(mainCondition).orderBy("runTime").queryIterator();
             GenericValue jobValue = jobsIterator.next();
             while (jobValue != null) {
                 // Claim ownership of this value. Using storeByCondition to avoid a race condition.
@@ -247,7 +248,7 @@
                     Debug.logWarning("Unable to poll JobSandbox for jobs; unable to begin transaction.", module);
                     return Collections.emptyList();
                 }
-                jobsIterator = delegator.find("JobSandbox", mainCondition, null, null, UtilMisc.toList("jobId"), null);
+                jobsIterator = EntityQuery.use(delegator).from("JobSandbox").where(mainCondition).orderBy("jobId").queryIterator();
                 GenericValue jobValue = jobsIterator.next();
                 while (jobValue != null) {
                     poll.add(new PurgeJob(jobValue));
@@ -291,7 +292,7 @@
         EntityCondition statusCondition = EntityCondition.makeCondition(statusExprList, EntityOperator.OR);
         EntityCondition mainCondition = EntityCondition.makeCondition(UtilMisc.toList(EntityCondition.makeCondition("runByInstanceId", instanceId), statusCondition));
         try {
-            crashed = delegator.findList("JobSandbox", mainCondition, null, UtilMisc.toList("startDateTime"), null, false);
+            crashed = EntityQuery.use(delegator).from("JobSandbox").where(mainCondition).orderBy("startDateTime").queryList();
         } catch (GenericEntityException e) {
             Debug.logWarning(e, "Unable to load crashed jobs", module);
         }
diff --git a/framework/service/src/org/ofbiz/service/job/PersistedServiceJob.java b/framework/service/src/org/ofbiz/service/job/PersistedServiceJob.java
index 6c748d2..9a9422a 100644
--- a/framework/service/src/org/ofbiz/service/job/PersistedServiceJob.java
+++ b/framework/service/src/org/ofbiz/service/job/PersistedServiceJob.java
@@ -39,6 +39,7 @@
 import org.ofbiz.entity.condition.EntityFieldMap;
 import org.ofbiz.entity.serialize.SerializeException;
 import org.ofbiz.entity.serialize.XmlSerializer;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.GenericRequester;
 import org.ofbiz.service.ServiceUtil;
@@ -321,8 +322,7 @@
         }
         long count = 0;
         try {
-            EntityFieldMap ecl = EntityCondition.makeConditionMap("parentJobId", pJobId, "statusId", "SERVICE_FAILED");
-            count = delegator.findCountByCondition("JobSandbox", ecl, null, null);
+            count = EntityQuery.use(delegator).from("JobSandbox").where("parentJobId", pJobId, "statusId", "SERVICE_FAILED").queryCount();
         } catch (GenericEntityException e) {
             Debug.logError(e, "Exception thrown while counting retries: ", module);
         }
diff --git a/framework/service/src/org/ofbiz/service/test/ServiceEntityAutoTests.java b/framework/service/src/org/ofbiz/service/test/ServiceEntityAutoTests.java
index df99add..2356c8f 100644
--- a/framework/service/src/org/ofbiz/service/test/ServiceEntityAutoTests.java
+++ b/framework/service/src/org/ofbiz/service/test/ServiceEntityAutoTests.java
@@ -26,6 +26,7 @@
 import org.ofbiz.base.util.UtilMisc;
 import org.ofbiz.base.util.UtilProperties;
 import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.service.ServiceUtil;
 import org.ofbiz.service.testtools.OFBizTestCase;
 
@@ -50,7 +51,7 @@
         testingPkPresentMap.put("testingName", "entity auto testing");
         Map<String, Object> results = dispatcher.runSync("testEntityAutoCreateTestingPkPresent", testingPkPresentMap);
         assertTrue(ServiceUtil.isSuccess(results));
-        GenericValue testing = delegator.findOne("Testing", false, "testingId", "TESTING_1");
+        GenericValue testing = EntityQuery.use(delegator).from("Testing").where("testingId", "TESTING_1").queryOne();
         assertNotNull(testing);
 
         //test create with auto sequence
@@ -58,7 +59,7 @@
         testingPkPresentMap.put("testingName", "entity auto testing without pk part in");
         results = dispatcher.runSync("testEntityAutoCreateTestingPkMissing", testingPkMissingMap);
         assertTrue(ServiceUtil.isSuccess(results));
-        testing = delegator.findOne("Testing", false, "testingId", results.get("testingId"));
+        testing = EntityQuery.use(delegator).from("Testing").where("testingId", results.get("testingId")).queryOne();
         assertNotNull(testing);
 
         //test collision
@@ -73,14 +74,20 @@
         Map<String, Object> testingItemPkPresentMap = UtilMisc.toMap("testingId", "TESTING_2", "testingSeqId", "00001");
         Map<String, Object> results = dispatcher.runSync("testEntityAutoCreateTestingItemPkPresent", testingItemPkPresentMap);
         assertTrue(ServiceUtil.isSuccess(results));
-        GenericValue testingItem = delegator.findOne("TestingItem", false, "testingId", "TESTING_2", "testingSeqId", "00001");
+        GenericValue testingItem = EntityQuery.use(delegator)
+                                              .from("TestingItem")
+                                              .where("testingId", "TESTING_2", "testingSeqId", "00001")
+                                              .queryOne();
         assertNotNull(testingItem);
 
         //test create with auto sub-sequence
         Map<String, Object> testingItemPkMissingMap = UtilMisc.toMap("testingId", "TESTING_2");
         results = dispatcher.runSync("testEntityAutoCreateTestingItemPkMissing", testingItemPkMissingMap);
         assertTrue(ServiceUtil.isSuccess(results));
-        testingItem = delegator.findOne("TestingItem", false, "testingId", "TESTING_2", "testingSeqId", results.get("testingSeqId"));
+        testingItem = EntityQuery.use(delegator)
+                                 .from("TestingItem")
+                                 .where("testingId", "TESTING_2", "testingSeqId", results.get("testingSeqId"))
+                                 .queryOne();
         assertNotNull(testingItem);
         assertEquals("00002", testingItem.get("testingSeqId"));
 
@@ -99,7 +106,10 @@
                 "testingNodeId", "NODE_1", "fromDate", UtilDateTime.toTimestamp("01/01/2010 00:00:00"));
         Map<String, Object> results = dispatcher.runSync("testEntityAutoCreateTestingNodeMemberPkPresent", testingNodeMemberPkPresentMap);
         assertTrue(ServiceUtil.isSuccess(results));
-        GenericValue testingNodeMember = delegator.findOne("TestingNodeMember", false, testingNodeMemberPkPresentMap);
+        GenericValue testingNodeMember = EntityQuery.use(delegator)
+                                                    .from("TestingNodeMember")
+                                                    .where(testingNodeMemberPkPresentMap)
+                                                    .queryOne();
         assertNotNull(testingNodeMember);
         testingNodeMember.remove();
 
@@ -117,7 +127,7 @@
         Map<String, Object> testingUpdateMap = UtilMisc.toMap("testingId", "TESTING_4", "testingName", "entity auto testing updated");
         Map<String, Object> results = dispatcher.runSync("testEntityAutoUpdateTesting", testingUpdateMap);
         assertTrue(ServiceUtil.isSuccess(results));
-        GenericValue testing = delegator.findOne("Testing", false, "testingId", "TESTING_4");
+        GenericValue testing = EntityQuery.use(delegator).from("Testing").where("testingId", "TESTING_4").queryOne();
         assertEquals("entity auto testing updated", testing.getString("testingName"));
 
         //test update with bad pk
@@ -134,7 +144,7 @@
         Map<String, Object> testingDeleteMap = UtilMisc.toMap("testingId", "TESTING_5");
         Map<String, Object> results = dispatcher.runSync("testEntityAutoRemoveTesting", testingDeleteMap);
         assertTrue(ServiceUtil.isSuccess(results));
-        GenericValue testing = delegator.findOne("Testing", false, "testingId", "TESTING_5");
+        GenericValue testing = EntityQuery.use(delegator).from("Testing").where("testingId", "TESTING_5").queryOne();
         assertNull(testing);
 
         //test create with bad pk
diff --git a/framework/testtools/src/org/ofbiz/testtools/EntityXmlAssertTest.java b/framework/testtools/src/org/ofbiz/testtools/EntityXmlAssertTest.java
index bd71d1d..f854721 100644
--- a/framework/testtools/src/org/ofbiz/testtools/EntityXmlAssertTest.java
+++ b/framework/testtools/src/org/ofbiz/testtools/EntityXmlAssertTest.java
@@ -58,8 +58,8 @@
         int testCaseCount = 0;
         try {
             URL entityXmlURL = FlexibleLocation.resolveLocation(entityXmlUrlString);
-            List<GenericValue> checkValueList = delegator.readXmlDocument(entityXmlURL);
-            testCaseCount = checkValueList.size();
+            EntitySaxReader reader = new EntitySaxReader(delegator);
+            testCaseCount += reader.parse(entityXmlURL);
         } catch (Exception e) {
             Debug.logError(e, "Error getting test case count", module);
         }
diff --git a/framework/webapp/config/fop.properties b/framework/webapp/config/fop.properties
index 97ffeb4..203b348 100644
--- a/framework/webapp/config/fop.properties
+++ b/framework/webapp/config/fop.properties
@@ -21,7 +21,7 @@
 fop.path=/framework/webapp/config
 
 #Set default font family
-fop.font.family=any
+fop.font.family=NotoSans
 
 #Set font base url
 fop.font.base.url=/framework/webapp/config/
diff --git a/framework/webapp/config/fop.xconf b/framework/webapp/config/fop.xconf
index fa9defe..f0603ae 100644
--- a/framework/webapp/config/fop.xconf
+++ b/framework/webapp/config/fop.xconf
@@ -95,6 +95,8 @@
           <font-triplet name="ArialMT" style="normal" weight="bold"/>
         </font>
         -->
+          <auto-detect/>
+          <directory>framework/resources/fonts/NotoSans</directory>
       </fonts>
 
       <!-- This option lets you specify additional options on an XML handler -->
diff --git a/framework/webapp/entitydef/entitygroup.xml b/framework/webapp/entitydef/entitygroup.xml
new file mode 100644
index 0000000..8c07b5f
--- /dev/null
+++ b/framework/webapp/entitydef/entitygroup.xml
@@ -0,0 +1,37 @@
+<?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.
+-->
+
+<entitygroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/entitygroup.xsd">
+
+    <entity-group group="org.ofbiz.stats" entity="BrowserType"/>
+    <entity-group group="org.ofbiz.stats" entity="PlatformType"/>
+    <entity-group group="org.ofbiz.stats" entity="ProtocolType"/>
+    <entity-group group="org.ofbiz.stats" entity="ServerHit"/>
+    <entity-group group="org.ofbiz.stats" entity="ServerHitBin"/>
+    <entity-group group="org.ofbiz.stats" entity="ServerHitType"/>
+    <entity-group group="org.ofbiz.stats" entity="UserAgent"/>
+    <entity-group group="org.ofbiz.stats" entity="UserAgentMethodType"/>
+    <entity-group group="org.ofbiz.stats" entity="UserAgentType"/>
+    <entity-group group="org.ofbiz.stats" entity="Visit"/>
+    <entity-group group="org.ofbiz.stats" entity="Visitor"/>
+
+</entitygroup>
+
diff --git a/framework/webapp/entitydef/entitymodel.xml b/framework/webapp/entitydef/entitymodel.xml
index e0a9b21..250c648 100644
--- a/framework/webapp/entitydef/entitymodel.xml
+++ b/framework/webapp/entitydef/entitymodel.xml
@@ -88,12 +88,6 @@
       <relation type="one" fk-name="SERVER_HIT_VISIT" rel-entity-name="Visit">
         <key-map field-name="visitId"/>
       </relation>
-      <relation type="one" fk-name="SERVER_HIT_STATUS" rel-entity-name="StatusItem">
-        <key-map field-name="statusId"/>
-      </relation>
-      <relation type="one" fk-name="SERVER_HIT_USER" rel-entity-name="UserLogin">
-        <key-map field-name="userLoginId"/>
-      </relation>
     </entity>
     <entity entity-name="ServerHitBin" package-name="org.ofbiz.webapp.visit" never-cache="true" title="Server Hit Bin Entity">
       <field name="serverHitBinId" type="id-ne"></field>
diff --git a/framework/webapp/ofbiz-component.xml b/framework/webapp/ofbiz-component.xml
index 2233949..4149aa1 100644
--- a/framework/webapp/ofbiz-component.xml
+++ b/framework/webapp/ofbiz-component.xml
@@ -30,6 +30,9 @@
     <classpath type="jar" location="build/lib/*"/>
 
     <entity-resource type="model" reader-name="main" loader="main" location="entitydef/entitymodel.xml"/>
+    <!--
+    <entity-resource type="group" reader-name="main" loader="main" location="entitydef/entitygroup.xml"/>
+    -->
 
 <!--<test-suite loader="main" location="testdef/webapptests.xml"/>-->
 </ofbiz-component>
diff --git a/framework/webapp/src/org/ofbiz/webapp/control/ContextFilter.java b/framework/webapp/src/org/ofbiz/webapp/control/ContextFilter.java
index 9029a2e..b17313a 100644
--- a/framework/webapp/src/org/ofbiz/webapp/control/ContextFilter.java
+++ b/framework/webapp/src/org/ofbiz/webapp/control/ContextFilter.java
@@ -47,6 +47,7 @@
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.condition.EntityCondition;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.entity.util.EntityUtil;
 import org.ofbiz.security.Security;
 import org.ofbiz.security.SecurityConfigurationException;
@@ -258,14 +259,14 @@
 
                 //Use base delegator for fetching data from entity of entityGroup org.ofbiz.tenant 
                 Delegator baseDelegator = DelegatorFactory.getDelegator(delegator.getDelegatorBaseName());
-                GenericValue tenantDomainName = baseDelegator.findOne("TenantDomainName", UtilMisc.toMap("domainName", serverName), false);
+                GenericValue tenantDomainName = EntityQuery.use(baseDelegator).from("TenantDomainName").where("domainName", serverName).queryOne();
 
                 if (UtilValidate.isNotEmpty(tenantDomainName)) {
                     String tenantId = tenantDomainName.getString("tenantId");
 
                     // if the request path is a root mount then redirect to the initial path
                     if (UtilValidate.isNotEmpty(requestPath) && requestPath.equals(contextUri)) {
-                        GenericValue tenant = baseDelegator.findOne("Tenant", UtilMisc.toMap("tenantId", tenantId), false);
+                        GenericValue tenant = EntityQuery.use(baseDelegator).from("Tenant").where("tenantId", tenantId).queryOne();
                         String initialPath = tenant.getString("initialPath");
                         if (UtilValidate.isNotEmpty(initialPath) && !"/".equals(initialPath)) {
                             ((HttpServletResponse)response).sendRedirect(initialPath);
diff --git a/framework/webapp/src/org/ofbiz/webapp/control/ControlServlet.java b/framework/webapp/src/org/ofbiz/webapp/control/ControlServlet.java
index d694010..a09c5e2 100644
--- a/framework/webapp/src/org/ofbiz/webapp/control/ControlServlet.java
+++ b/framework/webapp/src/org/ofbiz/webapp/control/ControlServlet.java
@@ -32,7 +32,7 @@
 
 import org.apache.bsf.BSFManager;
 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.UtilHttp;
 import org.ofbiz.base.util.UtilTimer;
@@ -217,8 +217,7 @@
                 if (Debug.verboseOn()) Debug.logVerbose(throwable, module);
             } else {
                 Debug.logError(throwable, "Error in request handler: ", module);
-                StringUtil.HtmlEncoder encoder = new StringUtil.HtmlEncoder();
-                request.setAttribute("_ERROR_MESSAGE_", encoder.encode(throwable.toString()));
+                request.setAttribute("_ERROR_MESSAGE_", UtilCodec.getEncoder("html").encode(throwable.toString()));
                 errorPage = requestHandler.getDefaultErrorPage(request);
             }
          } catch (RequestHandlerExceptionAllowExternalRequests e) {
@@ -226,8 +225,7 @@
               Debug.logInfo("Going to external page: " + request.getPathInfo(), module);
         } catch (Exception e) {
             Debug.logError(e, "Error in request handler: ", module);
-            StringUtil.HtmlEncoder encoder = new StringUtil.HtmlEncoder();
-            request.setAttribute("_ERROR_MESSAGE_", encoder.encode(e.toString()));
+            request.setAttribute("_ERROR_MESSAGE_", UtilCodec.getEncoder("html").encode(e.toString()));
             errorPage = requestHandler.getDefaultErrorPage(request);
         }
 
diff --git a/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java b/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java
index f9e4d19..252faa4 100644
--- a/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java
+++ b/framework/webapp/src/org/ofbiz/webapp/control/LoginWorker.java
@@ -237,7 +237,7 @@
         // check if they have permission for this login attempt; if not log them out
         if (userLogin != null) {
             List<Object> errorMessageList = UtilGenerics.checkList(request.getAttribute("_ERROR_MESSAGE_LIST"));
-            if (!hasBasePermission(userLogin, request) || isFlaggedLoggedOut(userLogin)) {
+            if (!hasBasePermission(userLogin, request) || isFlaggedLoggedOut(userLogin, userLogin.getDelegator())) {
                 if (errorMessageList == null) {
                     errorMessageList = new LinkedList<Object>();
                     request.setAttribute("_ERROR_MESSAGE_LIST", errorMessageList);
@@ -1020,7 +1020,7 @@
 
         EntityConditionList<EntityCondition> condition = EntityCondition.makeCondition(conds);
         Debug.logInfo("Doing issuer lookup: " + condition.toString(), module);
-        long count = delegator.findCountByCondition("X509IssuerProvision", condition, null, null);
+        long count = EntityQuery.use(delegator).from("X509IssuerProvision").where(condition).queryCount();
         return count > 0;
     }
 
@@ -1066,8 +1066,8 @@
         return "success";
     }
 
-    public static boolean isFlaggedLoggedOut(GenericValue userLogin) {
-        if ("true".equalsIgnoreCase(UtilProperties.getPropertyValue("security.properties", "login.disable.global.logout"))) {
+    public static boolean isFlaggedLoggedOut(GenericValue userLogin, Delegator delegator) {
+        if ("true".equalsIgnoreCase(EntityUtilProperties.getPropertyValue("security.properties", "login.disable.global.logout", delegator))) {
             return false;
         }
         if (userLogin == null || userLogin.get("userLoginId") == null) {
@@ -1180,7 +1180,7 @@
         if (reqToChangePwdInDays > 0) {
             List<GenericValue> passwordHistories = null;
             try {
-                passwordHistories = delegator.findByAnd("UserLoginPasswordHistory", UtilMisc.toMap("userLoginId", userName), null, false);
+                passwordHistories = EntityQuery.use(delegator).from("UserLoginPasswordHistory").where("userLoginId", userName).queryList();
             } catch (GenericEntityException e) {
                 Debug.logError(e, "Cannot get user's password history record: " + e.getMessage(), module);
             }
diff --git a/framework/webapp/src/org/ofbiz/webapp/control/ProtectViewWorker.java b/framework/webapp/src/org/ofbiz/webapp/control/ProtectViewWorker.java
index 8847f77..39c67c7 100644
--- a/framework/webapp/src/org/ofbiz/webapp/control/ProtectViewWorker.java
+++ b/framework/webapp/src/org/ofbiz/webapp/control/ProtectViewWorker.java
@@ -34,6 +34,7 @@
 import org.ofbiz.entity.Delegator;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.util.EntityQuery;
 
 /**
  * Common Workers
@@ -64,15 +65,21 @@
         if (userLogin != null) {
             String userLoginId = userLogin.getString("userLoginId");
             try {
-                List<GenericValue> protectedViews = delegator.findByAnd("UserLoginAndProtectedView",
-                        UtilMisc.toMap("userLoginId", userLoginId, "viewNameId", viewNameId), null, true);
+                List<GenericValue> protectedViews = EntityQuery.use(delegator)
+                                                               .from("UserLoginAndProtectedView")
+                                                               .where("userLoginId", userLoginId, "viewNameId", viewNameId)
+                                                               .cache(true)
+                                                               .queryList();
                 // Any views to deal with ?
                 if (UtilValidate.isNotEmpty(protectedViews)) {
                     Long now = System.currentTimeMillis(); // we are not in a margin of some milliseconds
 
                     // Is this login/view couple already tarpitted ? (ie denied access to view for login for a period of time)
-                    List<GenericValue> tarpittedLoginViews = delegator.findByAnd("TarpittedLoginView",
-                            UtilMisc.toMap("userLoginId", userLoginId, "viewNameId", viewNameId), null, true);
+                    List<GenericValue> tarpittedLoginViews = EntityQuery.use(delegator)
+                                                                        .from("TarpittedLoginView")
+                                                                        .where("userLoginId", userLoginId, "viewNameId", viewNameId)
+                                                                        .cache(true)
+                                                                        .queryList();
                     String  viewNameUserLoginId = viewNameId + userLoginId;
                     if (UtilValidate.isNotEmpty(tarpittedLoginViews)) {
                         GenericValue tarpittedLoginView = tarpittedLoginViews.get(0);
diff --git a/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java b/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java
index 26c49ea..6e8546c 100644
--- a/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java
+++ b/framework/webapp/src/org/ofbiz/webapp/control/RequestHandler.java
@@ -40,6 +40,7 @@
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.SSLUtil;
 import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
 import org.ofbiz.base.util.UtilFormatOut;
 import org.ofbiz.base.util.UtilGenerics;
 import org.ofbiz.base.util.UtilHttp;
@@ -62,7 +63,6 @@
 import org.ofbiz.webapp.view.ViewHandlerException;
 import org.ofbiz.webapp.website.WebSiteProperties;
 import org.ofbiz.webapp.website.WebSiteWorker;
-import org.owasp.esapi.errors.EncodingException;
 import org.python.modules.re;
 
 /**
@@ -71,8 +71,6 @@
 public class RequestHandler {
 
     public static final String module = RequestHandler.class.getName();
-    private static final boolean throwRequestHandlerExceptionOnMissingLocalRequest = UtilProperties.propertyValueEqualsIgnoreCase(
-            "requestHandler.properties", "throwRequestHandlerExceptionOnMissingLocalRequest", "Y");
     private final String defaultStatusCodeString = UtilProperties.getPropertyValue("requestHandler.properties", "status-code", "302");
     private final ViewFactory viewFactory;
     private final EventFactory eventFactory;
@@ -131,6 +129,8 @@
     public void doRequest(HttpServletRequest request, HttpServletResponse response, String chain,
             GenericValue userLogin, Delegator delegator) throws RequestHandlerException, RequestHandlerExceptionAllowExternalRequests {
 
+    	final boolean throwRequestHandlerExceptionOnMissingLocalRequest = EntityUtilProperties.propertyValueEqualsIgnoreCase(
+                "requestHandler.properties", "throwRequestHandlerExceptionOnMissingLocalRequest", "Y", delegator);
         long startTime = System.currentTimeMillis();
         HttpSession session = request.getSession();
 
@@ -280,7 +280,7 @@
                         }
                     }
                     if (enableHttps == null) {
-                        enableHttps = UtilProperties.propertyValueEqualsIgnoreCase("url.properties", "port.https.enabled", "Y");
+                        enableHttps = EntityUtilProperties.propertyValueEqualsIgnoreCase("url.properties", "port.https.enabled", "Y", delegator);
                     }
 
                     if (Boolean.FALSE.equals(enableHttps)) {
@@ -1023,11 +1023,11 @@
     @Deprecated
     public static String getDefaultServerRootUrl(HttpServletRequest request, boolean secure) {
     	Delegator delegator = (Delegator) request.getAttribute("delegator");
-        String httpsPort = UtilProperties.getPropertyValue("url.properties", "port.https", "443");
-        String httpsServer = UtilProperties.getPropertyValue("url.properties", "force.https.host");
-        String httpPort = UtilProperties.getPropertyValue("url.properties", "port.http", "80");
-        String httpServer = UtilProperties.getPropertyValue("url.properties", "force.http.host");
-        boolean useHttps = UtilProperties.propertyValueEqualsIgnoreCase("url.properties", "port.https.enabled", "Y");
+        String httpsPort = EntityUtilProperties.getPropertyValue("url.properties", "port.https", "443", delegator);
+        String httpsServer = EntityUtilProperties.getPropertyValue("url.properties", "force.https.host", delegator);
+        String httpPort = EntityUtilProperties.getPropertyValue("url.properties", "port.http", "80", delegator);
+        String httpServer = EntityUtilProperties.getPropertyValue("url.properties", "force.http.host", delegator);
+        boolean useHttps = EntityUtilProperties.propertyValueEqualsIgnoreCase("url.properties", "port.https.enabled", "Y", delegator);
 
         if (Start.getInstance().getConfig().portOffset != 0) {
             Integer httpPortValue = Integer.valueOf(httpPort);
@@ -1115,13 +1115,11 @@
             if (queryString.length() > 1) {
                 queryString.append("&");
             }
-
-            try {
-                queryString.append(StringUtil.defaultWebEncoder.encodeForURL(name));
+            String encodedName = UtilCodec.getEncoder("url").encode(name);
+            if (encodedName != null) {
+                queryString.append(encodedName);
                 queryString.append("=");
-                queryString.append(StringUtil.defaultWebEncoder.encodeForURL(value));
-            } catch (EncodingException e) {
-                Debug.logError(e, module);
+                queryString.append(UtilCodec.getEncoder("url").encode(value));
             }
         }
     }
diff --git a/framework/webapp/src/org/ofbiz/webapp/ftl/OfbizContentTransform.java b/framework/webapp/src/org/ofbiz/webapp/ftl/OfbizContentTransform.java
index 8c28119..d04a3a1 100644
--- a/framework/webapp/src/org/ofbiz/webapp/ftl/OfbizContentTransform.java
+++ b/framework/webapp/src/org/ofbiz/webapp/ftl/OfbizContentTransform.java
@@ -25,10 +25,9 @@
 import javax.servlet.http.HttpServletRequest;
 
 import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.webapp.taglib.ContentUrlTag;
-import org.owasp.esapi.errors.EncodingException;
 
 import freemarker.core.Environment;
 import freemarker.ext.beans.BeanModel;
@@ -93,11 +92,7 @@
                         return;
                     }
 
-                    try {
-                        requestUrl = StringUtil.defaultWebEncoder.decodeFromURL(requestUrl);
-                    } catch (EncodingException e) {
-                        Debug.logError(e, module);
-                    }
+                    requestUrl = UtilCodec.getDecoder("url").decode(requestUrl);
 
                     // make the link
                     StringBuilder newURL = new StringBuilder();
diff --git a/framework/webapp/src/org/ofbiz/webapp/stats/ServerHitBin.java b/framework/webapp/src/org/ofbiz/webapp/stats/ServerHitBin.java
index 0c63d79..a01bd86 100644
--- a/framework/webapp/src/org/ofbiz/webapp/stats/ServerHitBin.java
+++ b/framework/webapp/src/org/ofbiz/webapp/stats/ServerHitBin.java
@@ -37,6 +37,7 @@
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.model.ModelEntity;
 import org.ofbiz.entity.util.EntityQuery;
+import org.ofbiz.entity.util.EntityUtilProperties;
 
 import com.ibm.icu.util.Calendar;
 
@@ -213,7 +214,7 @@
             // put the copy at the first of the list, then put this object back on
             if (bin.getNumberHits() > 0) {
                 // persist each bin when time ends if option turned on
-                if (UtilProperties.propertyValueEqualsIgnoreCase("serverstats", "stats.persist." + ServerHitBin.typeIds[type] + ".bin", "true")) {
+                if (EntityUtilProperties.propertyValueEqualsIgnoreCase("serverstats", "stats.persist." + ServerHitBin.typeIds[type] + ".bin", "true", delegator)) {
                     GenericValue serverHitBin = delegator.makeValue("ServerHitBin");
                     serverHitBin.set("contentId", bin.id);
                     serverHitBin.set("hitTypeId", ServerHitBin.typeIds[bin.type]);
@@ -465,7 +466,8 @@
 
     private void saveHit(HttpServletRequest request, long startTime, long runningTime, GenericValue userLogin) throws GenericEntityException {
         // persist record of hit in ServerHit entity if option turned on
-        if (UtilProperties.propertyValueEqualsIgnoreCase("serverstats", "stats.persist." + ServerHitBin.typeIds[type] + ".hit", "true")) {
+    	Delegator delegator = (Delegator) request.getAttribute("delegator");
+        if (EntityUtilProperties.propertyValueEqualsIgnoreCase("serverstats", "stats.persist." + ServerHitBin.typeIds[type] + ".hit", "true", delegator)) {
             // if the hit type is ENTITY and the name contains "ServerHit" don't
             // persist; avoids the infinite loop and a bunch of annoying data
             if (this.type == ENTITY && this.id.indexOf("ServerHit") > 0) {
diff --git a/framework/webapp/src/org/ofbiz/webapp/stats/VisitHandler.java b/framework/webapp/src/org/ofbiz/webapp/stats/VisitHandler.java
index 5816db6..f47573e 100644
--- a/framework/webapp/src/org/ofbiz/webapp/stats/VisitHandler.java
+++ b/framework/webapp/src/org/ofbiz/webapp/stats/VisitHandler.java
@@ -36,6 +36,7 @@
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.model.ModelEntity;
 import org.ofbiz.entity.util.EntityQuery;
+import org.ofbiz.entity.util.EntityUtilProperties;
 
 /**
  * Handles saving and maintaining visit information
@@ -204,7 +205,8 @@
 
     public static GenericValue getVisitor(HttpServletRequest request, HttpServletResponse response) {
         // this defaults to true: ie if anything but "false" it will be true
-        if (!UtilProperties.propertyValueEqualsIgnoreCase("serverstats", "stats.persist.visitor", "false")) {
+    	Delegator delegator = (Delegator) request.getAttribute("delegator");
+        if (!EntityUtilProperties.propertyValueEqualsIgnoreCase("serverstats", "stats.persist.visitor", "false", delegator)) {
             HttpSession session = request.getSession();
 
             GenericValue visitor = (GenericValue) session.getAttribute("visitor");
@@ -212,7 +214,6 @@
                 synchronized (session) {
                     visitor = (GenericValue) session.getAttribute("visitor");
                     if (visitor == null) {
-                        Delegator delegator = (Delegator) request.getAttribute("delegator");
 
                         String delegatorName = (String) session.getAttribute("delegatorName");
                         if (delegator == null && UtilValidate.isNotEmpty(delegatorName)) {
diff --git a/framework/webapp/src/org/ofbiz/webapp/website/WebSiteWorker.java b/framework/webapp/src/org/ofbiz/webapp/website/WebSiteWorker.java
index 36d28e6..9d86761 100644
--- a/framework/webapp/src/org/ofbiz/webapp/website/WebSiteWorker.java
+++ b/framework/webapp/src/org/ofbiz/webapp/website/WebSiteWorker.java
@@ -26,6 +26,7 @@
 import org.ofbiz.entity.Delegator;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.util.EntityQuery;
 
 /**
  * WebSiteWorker - Worker class for web site related functionality
@@ -72,7 +73,7 @@
     public static GenericValue findWebSite(Delegator delegator, String webSiteId, boolean useCache) {
         GenericValue result = null;
         try {
-            result = delegator.findOne("WebSite", useCache, UtilMisc.toMap("webSiteId", webSiteId));
+            result = EntityQuery.use(delegator).from("WebSite").where("webSiteId", webSiteId).cache(useCache).queryOne();
         }
         catch (GenericEntityException e) {
             Debug.logError("Error looking up website with id " + webSiteId, module);
diff --git a/framework/webtools/src/org/ofbiz/webtools/GenericWebEvent.java b/framework/webtools/src/org/ofbiz/webtools/GenericWebEvent.java
index 0b3ae42..021a24b 100644
--- a/framework/webtools/src/org/ofbiz/webtools/GenericWebEvent.java
+++ b/framework/webtools/src/org/ofbiz/webtools/GenericWebEvent.java
@@ -39,6 +39,7 @@
 import org.ofbiz.entity.model.ModelField;
 import org.ofbiz.entity.model.ModelFieldType;
 import org.ofbiz.entity.model.ModelReader;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.security.Security;
 
 /**
@@ -206,7 +207,7 @@
             GenericValue tempEntity = null;
 
             try {
-                tempEntity = delegator.findOne(findByEntity.getEntityName(), findByEntity.getPrimaryKey(), false);
+                tempEntity = EntityQuery.use(delegator).from(findByEntity.getEntityName()).where(findByEntity.getPrimaryKey()).queryOne();
             } catch (GenericEntityException e) {
                 String errMsg = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.create_failed_by_check", locale) + ": " + e.toString();
                 Debug.logWarning(e, errMsg, module);
diff --git a/framework/webtools/src/org/ofbiz/webtools/WebToolsServices.java b/framework/webtools/src/org/ofbiz/webtools/WebToolsServices.java
index a01ba6b..e59c5ab 100644
--- a/framework/webtools/src/org/ofbiz/webtools/WebToolsServices.java
+++ b/framework/webtools/src/org/ofbiz/webtools/WebToolsServices.java
@@ -79,6 +79,7 @@
 import org.ofbiz.entity.util.EntityDataAssert;
 import org.ofbiz.entity.util.EntityDataLoader;
 import org.ofbiz.entity.util.EntityListIterator;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.entity.util.EntitySaxReader;
 import org.ofbiz.entityext.EntityGroupUtil;
 import org.ofbiz.security.Security;
@@ -512,7 +513,7 @@
                             if (UtilValidate.isNotEmpty(fromDate)) {
                                 conds.add(EntityCondition.makeCondition("createdStamp", EntityOperator.GREATER_THAN_EQUAL_TO, fromDate));
                             }
-                            values = delegator.find(curEntityName, EntityCondition.makeCondition(conds), null, null, me.getPkFieldNames(), null);
+                            values = EntityQuery.use(delegator).from(curEntityName).where(conds).orderBy(me.getPkFieldNames()).queryIterator();
                         } catch (Exception entityEx) {
                             results.add("["+fileNumber +"] [xxx] Error when writing " + curEntityName + ": " + entityEx);
                             continue;
diff --git a/framework/webtools/src/org/ofbiz/webtools/labelmanager/LabelManagerFactory.java b/framework/webtools/src/org/ofbiz/webtools/labelmanager/LabelManagerFactory.java
index 89b34b0..dde2baa 100644
--- a/framework/webtools/src/org/ofbiz/webtools/labelmanager/LabelManagerFactory.java
+++ b/framework/webtools/src/org/ofbiz/webtools/labelmanager/LabelManagerFactory.java
@@ -37,10 +37,9 @@
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.FileUtil;
 import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.base.util.UtilXml;
-import org.owasp.esapi.errors.EncodingException;
 import org.w3c.dom.Comment;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -103,7 +102,7 @@
         }
     }
 
-    public void findMatchingLabels(String component, String fileName, String key, String locale) throws MalformedURLException, SAXException, ParserConfigurationException, IOException, EncodingException, GeneralException {
+    public void findMatchingLabels(String component, String fileName, String key, String locale) throws MalformedURLException, SAXException, ParserConfigurationException, IOException, GeneralException {
         if (UtilValidate.isEmpty(component) && UtilValidate.isEmpty(fileName) && UtilValidate.isEmpty(key) && UtilValidate.isEmpty(locale)) {
             // Important! Don't allow unparameterized queries - doing so will result in loading the entire project into memory
             return;
@@ -124,7 +123,7 @@
             for (Node propertyNode : UtilXml.childNodeList(resourceElem.getFirstChild())) {
                 if (propertyNode instanceof Element) {
                     Element propertyElem = (Element) propertyNode;
-                    String labelKey = StringUtil.defaultWebEncoder.canonicalize(propertyElem.getAttribute("key"));
+                    String labelKey = UtilCodec.canonicalize(propertyElem.getAttribute("key"));
                     String labelComment = "";
                     for (Node valueNode : UtilXml.childNodeList(propertyElem.getFirstChild())) {
                         if (valueNode instanceof Element) {
@@ -135,7 +134,7 @@
                             if( localeName.contains("_")) {
                                 localeName = localeName.replace('_', '-');
                             }
-                            String labelValue = StringUtil.defaultWebEncoder.canonicalize(UtilXml.nodeValue(valueElem.getFirstChild()));
+                            String labelValue = UtilCodec.canonicalize(UtilXml.nodeValue(valueElem.getFirstChild()));
                             LabelInfo label = labels.get(labelKey + keySeparator + fileInfo.getFileName());
 
                             if (UtilValidate.isEmpty(label)) {
@@ -149,12 +148,12 @@
                             localesFound.add(localeName);
                             labelComment = "";
                         } else if (valueNode instanceof Comment) {
-                            labelComment = labelComment + StringUtil.defaultWebEncoder.canonicalize(valueNode.getNodeValue());
+                            labelComment = labelComment + UtilCodec.canonicalize(valueNode.getNodeValue());
                         }
                     }
                     labelKeyComment = "";
                 } else if (propertyNode instanceof Comment) {
-                    labelKeyComment = labelKeyComment + StringUtil.defaultWebEncoder.canonicalize(propertyNode.getNodeValue());
+                    labelKeyComment = labelKeyComment + UtilCodec.canonicalize(propertyNode.getNodeValue());
                 }
             }
         }
diff --git a/framework/webtools/webapp/webtools/WEB-INF/actions/service/AvailableServices.groovy b/framework/webtools/webapp/webtools/WEB-INF/actions/service/AvailableServices.groovy
index bcde15f..80ea2f8 100644
--- a/framework/webtools/webapp/webtools/WEB-INF/actions/service/AvailableServices.groovy
+++ b/framework/webtools/webapp/webtools/WEB-INF/actions/service/AvailableServices.groovy
@@ -28,6 +28,7 @@
 import org.ofbiz.service.ServiceContainer;
 import org.ofbiz.base.util.UtilHttp;
 import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.entity.util.EntityUtilProperties;
 
 List getEcaListForService(String selectedService) {
     ecaMap = org.ofbiz.service.eca.ServiceEcaUtil.getServiceEventMap(selectedService);
@@ -476,7 +477,7 @@
 
     if (showWsdl?.equals("true")) {
         try {
-            wsdl = curServiceModel.toWSDL("http://${request.getServerName()}:${UtilProperties.getPropertyValue("url.properties", "port.http", "80")}${parameters._CONTROL_PATH_}/SOAPService");
+            wsdl = curServiceModel.toWSDL("http://${request.getServerName()}:${EntityUtilProperties.getPropertyValue("url.properties", "port.http", "80", delegator)}${parameters._CONTROL_PATH_}/SOAPService");
             curServiceMap.wsdl = UtilXml.writeXmlDocument(wsdl);
         } catch (WSDLException ex) {
             curServiceMap.wsdl = ex.getLocalizedMessage();
diff --git a/framework/widget/dtd/widget-catalog.xml b/framework/widget/dtd/widget-catalog.xml
index 27ad202..b21babd 100644
--- a/framework/widget/dtd/widget-catalog.xml
+++ b/framework/widget/dtd/widget-catalog.xml
@@ -26,6 +26,7 @@
 <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
   <!-- <public publicId="-//W3C//DTD SVG 1.0//EN" uri="svg10.dtd"/> -->
 
+  <system systemId="http://ofbiz.apache.org/dtds/widget-common.xsd" uri="widget-common.xsd"/>
   <system systemId="http://ofbiz.apache.org/dtds/widget-form.xsd" uri="widget-form.xsd"/>
   <system systemId="http://ofbiz.apache.org/dtds/widget-menu.xsd" uri="widget-menu.xsd"/>
   <system systemId="http://ofbiz.apache.org/dtds/widget-screen.xsd" uri="widget-screen.xsd"/>
diff --git a/framework/widget/dtd/widget-common.xsd b/framework/widget/dtd/widget-common.xsd
new file mode 100644
index 0000000..1f14f5b
--- /dev/null
+++ b/framework/widget/dtd/widget-common.xsd
@@ -0,0 +1,519 @@
+<?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.

+-->

+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">

+

+    <xs:complexType name="ConditionRootType">

+        <xs:choice>

+            <xs:element ref="and" />

+            <xs:element ref="or" />

+            <xs:element ref="xor" />

+            <xs:element ref="not" />

+            <xs:element ref="if-service-permission" />

+            <xs:element ref="if-has-permission" />

+            <xs:element ref="if-entity-permission" />

+            <xs:element ref="if-validate-method" />

+            <xs:element ref="if-compare" />

+            <xs:element ref="if-compare-field" />

+            <xs:element ref="if-regexp" />

+            <xs:element ref="if-empty" />

+        </xs:choice>

+    </xs:complexType>

+    <xs:element name="AllConditionals" abstract="true" />

+    <xs:element name="and" substitutionGroup="AllConditionals">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element maxOccurs="unbounded" ref="AllConditionals" />

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="xor" substitutionGroup="AllConditionals">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element maxOccurs="unbounded" ref="AllConditionals" />

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="or" substitutionGroup="AllConditionals">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element maxOccurs="unbounded" ref="AllConditionals" />

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="not" substitutionGroup="AllConditionals">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element ref="AllConditionals" />

+            </xs:sequence>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="if-service-permission" substitutionGroup="AllConditionals">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="service-name" use="required" />

+            <xs:attribute type="xs:string" name="resource-description" use="optional" />

+            <xs:attribute type="xs:string" name="context-map" use="optional" />

+            <xs:attribute name="main-action" use="optional">

+                <xs:simpleType>

+                    <xs:restriction base="xs:token">

+                        <xs:enumeration value="CREATE" />

+                        <xs:enumeration value="UPDATE" />

+                        <xs:enumeration value="DELETE" />

+                        <xs:enumeration value="VIEW" />

+                    </xs:restriction>

+                </xs:simpleType>

+            </xs:attribute>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="if-has-permission" substitutionGroup="AllConditionals">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="permission" use="required" />

+            <xs:attribute type="xs:string" name="action" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="if-entity-permission" substitutionGroup="AllConditionals">

+        <xs:complexType>

+            <xs:choice minOccurs="0">

+                <xs:element minOccurs="0" maxOccurs="1" ref="permission-condition-getter" />

+                <xs:element minOccurs="0" maxOccurs="1" ref="related-role-getter" />

+                <xs:element minOccurs="0" maxOccurs="1" ref="auxiliary-value-getter" />

+            </xs:choice>

+            <xs:attribute type="xs:string" name="entity-name" use="required" />

+            <xs:attribute type="xs:string" name="entity-id" use="required">

+                <xs:annotation>

+                    <xs:documentation>Can have multiple pipe separated values, but don't use spaces.</xs:documentation>

+                </xs:annotation>

+            </xs:attribute>

+            <xs:attribute type="xs:string" name="target-operation" use="required">

+                <xs:annotation>

+                    <xs:documentation>Can have multiple pipe separated values, but don't use spaces.</xs:documentation>

+                </xs:annotation>

+            </xs:attribute>

+            <xs:attribute name="display-fail-cond" 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="permission-condition-getter">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="entity-name" />

+            <xs:attribute type="xs:string" name="operation-field-name" />

+            <xs:attribute type="xs:string" name="role-field-name" />

+            <xs:attribute type="xs:string" name="auxiliary-field-name" />

+            <xs:attribute type="xs:string" name="status-field-name" />

+            <xs:attribute type="xs:string" name="privilege-field-name" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="related-role-getter">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="entity-name" />

+            <xs:attribute type="xs:string" name="role-entity-name" />

+            <xs:attribute type="xs:string" name="role-type-field-name" />

+            <xs:attribute type="xs:string" name="party-field-name" />

+            <xs:attribute type="xs:string" name="owner-entity-field-name" />

+            <xs:attribute type="xs:string" name="entity-id-name" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="auxiliary-value-getter">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="entity-name" />

+            <xs:attribute type="xs:string" name="auxiliary-field-name" />

+            <xs:attribute type="xs:string" name="entity-id-name" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="if-validate-method" substitutionGroup="AllConditionals">

+        <xs:annotation>

+            <xs:documentation>Calls a static Java method that takes a String and returns a boolean.</xs:documentation>

+        </xs:annotation>

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="field" use="required" />

+            <xs:attribute type="xs:string" name="method" use="required" />

+            <xs:attribute type="xs:string" name="class" default="org.ofbiz.base.util.UtilValidate" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="if-compare" substitutionGroup="AllConditionals">

+        <xs:complexType>

+            <xs:attribute name="field" type="xs:string" use="required" />

+            <xs:attribute name="operator" use="required">

+                <xs:simpleType>

+                    <xs:restriction base="xs:token">

+                        <xs:enumeration value="less" />

+                        <xs:enumeration value="greater" />

+                        <xs:enumeration value="less-equals" />

+                        <xs:enumeration value="greater-equals" />

+                        <xs:enumeration value="equals" />

+                        <xs:enumeration value="not-equals" />

+                        <xs:enumeration value="contains" />

+                    </xs:restriction>

+                </xs:simpleType>

+            </xs:attribute>

+            <xs:attribute name="value" type="xs:string" use="required" />

+            <xs:attribute name="type" default="String">

+                <xs:simpleType>

+                    <xs:restriction base="xs:token">

+                        <xs:enumeration value="PlainString" />

+                        <xs:enumeration value="String" />

+                        <xs:enumeration value="BigDecimal" />

+                        <xs:enumeration value="Double" />

+                        <xs:enumeration value="Float" />

+                        <xs:enumeration value="Long" />

+                        <xs:enumeration value="Integer" />

+                        <xs:enumeration value="Date" />

+                        <xs:enumeration value="Time" />

+                        <xs:enumeration value="Timestamp" />

+                        <xs:enumeration value="Boolean" />

+                        <xs:enumeration value="Object" />

+                    </xs:restriction>

+                </xs:simpleType>

+            </xs:attribute>

+            <xs:attribute type="xs:string" name="format" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="if-compare-field" substitutionGroup="AllConditionals">

+        <xs:complexType>

+            <xs:attribute name="field" type="xs:string" use="required" />

+            <xs:attribute name="operator" use="required">

+                <xs:simpleType>

+                    <xs:restriction base="xs:token">

+                        <xs:enumeration value="less" />

+                        <xs:enumeration value="greater" />

+                        <xs:enumeration value="less-equals" />

+                        <xs:enumeration value="greater-equals" />

+                        <xs:enumeration value="equals" />

+                        <xs:enumeration value="not-equals" />

+                        <xs:enumeration value="contains" />

+                    </xs:restriction>

+                </xs:simpleType>

+            </xs:attribute>

+            <xs:attribute name="to-field" type="xs:string" />

+            <xs:attribute name="type" default="String">

+                <xs:simpleType>

+                    <xs:restriction base="xs:token">

+                        <xs:enumeration value="PlainString" />

+                        <xs:enumeration value="String" />

+                        <xs:enumeration value="BigDecimal" />

+                        <xs:enumeration value="Double" />

+                        <xs:enumeration value="Float" />

+                        <xs:enumeration value="Long" />

+                        <xs:enumeration value="Integer" />

+                        <xs:enumeration value="Date" />

+                        <xs:enumeration value="Time" />

+                        <xs:enumeration value="Timestamp" />

+                        <xs:enumeration value="Boolean" />

+                        <xs:enumeration value="Object" />

+                    </xs:restriction>

+                </xs:simpleType>

+            </xs:attribute>

+            <xs:attribute type="xs:string" name="format" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="if-regexp" substitutionGroup="AllConditionals">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="field" use="required" />

+            <xs:attribute type="xs:string" name="expr" use="required" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="if-empty" substitutionGroup="AllConditionals">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="field" use="required" />

+        </xs:complexType>

+    </xs:element>

+

+    <xs:element name="AllActions" abstract="true" />

+    <xs:element name="set" substitutionGroup="AllActions">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="field" use="required" />

+            <xs:attribute type="xs:string" name="from-field" />

+            <xs:attribute type="xs:string" name="value" />

+            <xs:attribute type="xs:string" name="default-value" />

+            <xs:attribute name="global" 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="type">

+                <xs:simpleType>

+                    <xs:restriction base="xs:token">

+                        <xs:enumeration value="PlainString" />

+                        <xs:enumeration value="String" />

+                        <xs:enumeration value="BigDecimal" />

+                        <xs:enumeration value="Double" />

+                        <xs:enumeration value="Float" />

+                        <xs:enumeration value="List" />

+                        <xs:enumeration value="Long" />

+                        <xs:enumeration value="Integer" />

+                        <xs:enumeration value="Date" />

+                        <xs:enumeration value="Time" />

+                        <xs:enumeration value="Timestamp" />

+                        <xs:enumeration value="Boolean" />

+                        <xs:enumeration value="Object" />

+                        <xs:enumeration value="NewList" />

+                        <xs:enumeration value="NewMap" />

+                    </xs:restriction>

+                </xs:simpleType>

+            </xs:attribute>

+            <xs:attribute name="to-scope" default="screen">

+                <xs:simpleType>

+                    <xs:restriction base="xs:token">

+                        <xs:enumeration value="screen" />

+                        <xs:enumeration value="user" />

+                        <xs:enumeration value="application" />

+                    </xs:restriction>

+                </xs:simpleType>

+            </xs:attribute>

+            <xs:attribute name="from-scope" default="screen">

+                <xs:simpleType>

+                    <xs:restriction base="xs:token">

+                        <xs:enumeration value="screen" />

+                        <xs:enumeration value="user" />

+                        <xs:enumeration value="application" />

+                    </xs:restriction>

+                </xs:simpleType>

+            </xs:attribute>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="property-map" substitutionGroup="AllActions">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="resource" use="required" />

+            <xs:attribute type="xs:string" name="map-name" use="required" />

+            <xs:attribute name="global" 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="property-to-field" substitutionGroup="AllActions">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="resource" use="required" />

+            <xs:attribute type="xs:string" name="property" use="required" />

+            <xs:attribute type="xs:string" name="field" use="required" />

+            <xs:attribute type="xs:string" name="default" />

+            <xs:attribute name="no-locale" 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 type="xs:string" name="arg-list-name" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="script" substitutionGroup="AllActions">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="location" use="required" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="entity-one" substitutionGroup="AllActions">

+        <xs:complexType>

+            <xs:sequence>

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="field-map" />

+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="select-field" />

+            </xs:sequence>

+            <xs:attribute name="entity-name" type="xs:string" use="required" />

+            <xs:attribute name="value-field" type="xs:string" use="required" />

+            <xs:attribute name="use-cache" 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="auto-field-map" 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="get-related-one" substitutionGroup="AllActions">

+        <xs:complexType>

+            <xs:attribute name="value-field" type="xs:string" use="required" />

+            <xs:attribute name="relation-name" type="xs:string" use="required" />

+            <xs:attribute name="use-cache" type="xs:string" default="false" />

+            <xs:attribute name="to-value-field" type="xs:string" use="required" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="get-related" substitutionGroup="AllActions">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="value-field" use="required" />

+            <xs:attribute type="xs:string" name="relation-name" use="required" />

+            <xs:attribute type="xs:string" name="map" />

+            <xs:attribute type="xs:string" name="order-by-list" />

+            <xs:attribute type="xs:string" name="use-cache" default="false" />

+            <xs:attribute type="xs:string" name="list" use="required" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="condition-list">

+        <xs:complexType>

+            <xs:choice maxOccurs="unbounded">

+                <xs:element ref="condition-expr" />

+                <xs:element ref="condition-list" />

+                <xs:element ref="condition-object" />

+            </xs:choice>

+            <xs:attribute name="combine" default="and">

+                <xs:simpleType>

+                    <xs:restriction base="xs:token">

+                        <xs:enumeration value="and" />

+                        <xs:enumeration value="or" />

+                    </xs:restriction>

+                </xs:simpleType>

+            </xs:attribute>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="having-condition-list">

+        <xs:complexType>

+            <xs:choice maxOccurs="unbounded">

+                <xs:element ref="condition-expr" />

+                <xs:element ref="condition-list" />

+                <xs:element ref="condition-object" />

+            </xs:choice>

+            <xs:attribute name="combine" default="and">

+                <xs:simpleType>

+                    <xs:restriction base="xs:token">

+                        <xs:enumeration value="and" />

+                        <xs:enumeration value="or" />

+                    </xs:restriction>

+                </xs:simpleType>

+            </xs:attribute>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="condition-expr">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="field-name" use="required" />

+            <xs:attribute name="operator" default="equals">

+                <xs:simpleType>

+                    <xs:restriction base="xs:token">

+                        <xs:enumeration value="less" />

+                        <xs:enumeration value="greater" />

+                        <xs:enumeration value="less-equals" />

+                        <xs:enumeration value="greater-equals" />

+                        <xs:enumeration value="equals" />

+                        <xs:enumeration value="not-equals" />

+                        <xs:enumeration value="in" />

+                        <xs:enumeration value="not-in" />

+                        <xs:enumeration value="between" />

+                        <xs:enumeration value="like" />

+                    </xs:restriction>

+                </xs:simpleType>

+            </xs:attribute>

+            <xs:attribute type="xs:string" name="from-field" />

+            <xs:attribute type="xs:string" name="value" />

+            <xs:attribute name="ignore-if-null" 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="ignore-if-empty" 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="ignore-case" 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="ignore" default="false">

+                <xs:annotation>

+                    <xs:documentation>

+                        Ignore the condition if flag is true.

+                        Defaults to false.

+                    </xs:documentation>

+                </xs:annotation>

+            </xs:attribute>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="condition-object">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="field" use="required" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="select-field">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="field-name" use="required" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="order-by">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="field-name" use="required" />

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="limit-range">

+        <xs:complexType>

+            <xs:attribute name="start" type="xs:string" use="required">

+                <xs:annotation>

+                    <xs:documentation>Should resolve into a non-negative integer.</xs:documentation>

+                </xs:annotation>

+            </xs:attribute>

+            <xs:attribute name="size" type="xs:string" use="required">

+                <xs:annotation>

+                    <xs:documentation>Should resolve into a non-negative integer.</xs:documentation>

+                </xs:annotation>

+            </xs:attribute>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="limit-view">

+        <xs:complexType>

+            <xs:attribute name="view-index" type="xs:string" use="required">

+                <xs:annotation>

+                    <xs:documentation>Should resolve into a non-negative integer.</xs:documentation>

+                </xs:annotation>

+            </xs:attribute>

+            <xs:attribute name="view-size" type="xs:string" use="required">

+                <xs:annotation>

+                    <xs:documentation>Should resolve into a positive integer.</xs:documentation>

+                </xs:annotation>

+            </xs:attribute>

+        </xs:complexType>

+    </xs:element>

+    <xs:element name="use-iterator" />

+    <xs:element name="field-map">

+        <xs:complexType>

+            <xs:attribute type="xs:string" name="field-name" use="required" />

+            <xs:attribute type="xs:string" name="from-field" />

+            <xs:attribute type="xs:string" name="value" />

+        </xs:complexType>

+    </xs:element>

+</xs:schema>

diff --git a/framework/widget/dtd/widget-form.xsd b/framework/widget/dtd/widget-form.xsd
index 5a35025..09889ac 100644
--- a/framework/widget/dtd/widget-form.xsd
+++ b/framework/widget/dtd/widget-form.xsd
@@ -18,6 +18,7 @@
 under the License.
 -->
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+    <xs:include schemaLocation="http://ofbiz.apache.org/dtds/widget-common.xsd" />
 
   <!-- ================== FORMS ==================== -->
     <xs:element name="forms">
@@ -1798,7 +1799,6 @@
     </xs:element>
 
   <!-- ================== ACTIONS ==================== -->
-    <xs:element name="AllActions" abstract="true"/>
     <xs:element name="actions">
         <xs:complexType>
             <xs:sequence>
@@ -1813,42 +1813,6 @@
             </xs:sequence>
         </xs:complexType>
     </xs:element>
-    <xs:element name="property-map" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="resource" use="required" />
-            <xs:attribute type="xs:string" name="map-name" use="required" />
-            <xs:attribute name="global" 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="property-to-field" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="resource" use="required" />
-            <xs:attribute type="xs:string" name="property" use="required" />
-            <xs:attribute type="xs:string" name="field" use="required" />
-            <xs:attribute type="xs:string" name="default" />
-            <xs:attribute name="no-locale" 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 type="xs:string" name="arg-list-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="script" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="location" use="required" />
-        </xs:complexType>
-    </xs:element>
     <xs:element name="service" substitutionGroup="AllActions">
         <xs:complexType>
             <xs:sequence>
@@ -1873,44 +1837,7 @@
             </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:element name="set" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field" use="required" />
-            <xs:attribute type="xs:string" name="from-field" />
-            <xs:attribute type="xs:string" name="value" />
-            <xs:attribute type="xs:string" name="default-value" />
-            <xs:attribute name="global" 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="type" default="String">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="PlainString" />
-                        <xs:enumeration value="String" />
-                        <xs:enumeration value="BigDecimal" />
-                        <xs:enumeration value="Double" />
-                        <xs:enumeration value="Float" />
-                        <xs:enumeration value="List" />
-                        <xs:enumeration value="Long" />
-                        <xs:enumeration value="Integer" />
-                        <xs:enumeration value="Date" />
-                        <xs:enumeration value="Time" />
-                        <xs:enumeration value="Timestamp" />
-                        <xs:enumeration value="Boolean" />
-                        <xs:enumeration value="Object" />
-                        <xs:enumeration value="NewList" />
-                        <xs:enumeration value="NewMap" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-
+    <xs:element name="call-parent-actions" substitutionGroup="AllActions" />
     <xs:element name="entity-and" substitutionGroup="AllActions">
         <xs:complexType>
             <xs:sequence>
@@ -1923,8 +1850,7 @@
                     <xs:element ref="use-iterator" />
                 </xs:choice>
             </xs:sequence>
-            <xs:attribute name="entity-name" type="xs:string" use="required" />
-            <xs:attribute name="list" type="xs:string" use="optional" />
+            <xs:attribute type="xs:string" name="entity-name" use="required" />
             <xs:attribute name="use-cache" default="false">
                 <xs:simpleType>
                     <xs:restriction base="xs:token">
@@ -1942,6 +1868,7 @@
                     </xs:restriction>
                 </xs:simpleType>
             </xs:attribute>
+            <xs:attribute type="xs:string" name="list" />
             <xs:attribute name="result-set-type" default="scroll">
                 <xs:simpleType>
                     <xs:restriction base="xs:token">
@@ -1969,8 +1896,7 @@
                     <xs:element ref="use-iterator" />
                 </xs:choice>
             </xs:sequence>
-            <xs:attribute name="entity-name" type="xs:string" use="required" />
-            <xs:attribute name="list" type="xs:string" use="optional" />
+            <xs:attribute type="xs:string" name="entity-name" use="required" />
             <xs:attribute name="use-cache" default="false">
                 <xs:simpleType>
                     <xs:restriction base="xs:token">
@@ -1996,7 +1922,8 @@
                     </xs:restriction>
                 </xs:simpleType>
             </xs:attribute>
-            <xs:attribute name="delegator-name" />
+            <xs:attribute type="xs:string" name="delegator-name" />
+            <xs:attribute type="xs:string" name="list" />
             <xs:attribute name="result-set-type" default="scroll">
                 <xs:simpleType>
                     <xs:restriction base="xs:token">
@@ -2007,172 +1934,4 @@
             </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:element name="entity-one" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="field-map" />
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="select-field" />
-            </xs:sequence>
-            <xs:attribute type="xs:string" name="entity-name" use="required" />
-            <xs:attribute type="xs:string" name="value-field" />
-            <xs:attribute name="use-cache" 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="auto-field-map" 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="condition-expr">
-        <xs:complexType>
-            <xs:attribute name="field-name" type="xs:string" use="required" />
-            <xs:attribute name="operator" default="equals">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="less" />
-                        <xs:enumeration value="greater" />
-                        <xs:enumeration value="less-equals" />
-                        <xs:enumeration value="greater-equals" />
-                        <xs:enumeration value="equals" />
-                        <xs:enumeration value="not-equals" />
-                        <xs:enumeration value="in" />
-                        <xs:enumeration value="between" />
-                        <xs:enumeration value="like" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="from-field" type="xs:string" />
-            <xs:attribute name="value" type="xs:string" />
-            <xs:attribute name="ignore-if-null" 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="ignore-if-empty" 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="ignore-case" 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="ignore" default="false">
-                <xs:annotation>
-                    <xs:documentation>
-                        Ignore the condition if flag is true.
-                        Defaults to false.
-                </xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="condition-list">
-        <xs:complexType>
-            <xs:choice maxOccurs="unbounded">
-                <xs:element ref="condition-expr" />
-                <xs:element ref="condition-list" />
-                <xs:element ref="condition-object" />
-            </xs:choice>
-            <xs:attribute name="combine" default="and">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="and" />
-                        <xs:enumeration value="or" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="condition-object">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field" use="required" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="field-map">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field-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="having-condition-list">
-        <xs:complexType>
-            <xs:choice maxOccurs="unbounded">
-                <xs:element ref="condition-expr" />
-                <xs:element ref="condition-list" />
-                <xs:element ref="condition-object" />
-            </xs:choice>
-            <xs:attribute name="combine" default="and">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="and" />
-                        <xs:enumeration value="or" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="limit-range">
-        <xs:complexType>
-            <xs:attribute name="start" type="xs:string" use="required">
-                <xs:annotation>
-                    <xs:documentation>Should resolve into a non-negative integer.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="size" type="xs:string" use="required">
-                <xs:annotation>
-                    <xs:documentation>Should resolve into a non-negative integer.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="limit-view">
-        <xs:complexType>
-            <xs:attribute name="view-index" type="xs:string" use="required">
-                <xs:annotation>
-                    <xs:documentation>Should resolve into a non-negative integer.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="view-size" type="xs:string" use="required">
-                <xs:annotation>
-                    <xs:documentation>Should resolve into a positive integer.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="use-iterator" />
-    <xs:element name="order-by">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field-name" use="required" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="select-field">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field-name" use="required" />
-        </xs:complexType>
-    </xs:element>
-
-    <xs:element name="call-parent-actions" substitutionGroup="AllActions" />
 </xs:schema>
diff --git a/framework/widget/dtd/widget-menu.xsd b/framework/widget/dtd/widget-menu.xsd
index 78b7aa3..2b66e58 100644
--- a/framework/widget/dtd/widget-menu.xsd
+++ b/framework/widget/dtd/widget-menu.xsd
@@ -18,6 +18,7 @@
 under the License.
 -->
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+    <xs:include schemaLocation="http://ofbiz.apache.org/dtds/widget-common.xsd" />
     <xs:element name="menus">
         <xs:complexType>
             <xs:sequence>
@@ -96,7 +97,32 @@
     <xs:element name="menu-item">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" ref="condition" />
+                <xs:element name="condition" minOccurs="0">
+                    <xs:complexType>
+                        <xs:complexContent>
+                            <xs:extension base="ConditionRootType">
+                                <xs:attribute type="xs:string" name="pass-style">
+                                    <xs:annotation>
+                                        <xs:documentation>
+                                            If a pass-style provided and the condition passes, the widget-style of
+                                            the parent menu-item is set with the pass-style. If no pass-style is given,
+                                            the widget-style is not changed.
+                                        </xs:documentation>
+                                    </xs:annotation>
+                                </xs:attribute>
+                                <xs:attribute type="xs:string" name="disabled-style">
+                                    <xs:annotation>
+                                        <xs:documentation>
+                                            If a disabled-style provided and the condition fails, the disabled-style of
+                                            the parent menu-item is set with the disabled-style and processing is allowed to continue.
+                                            If no disabled-style is given, the widget-style is not changed and the menu-item is not rendered.
+                                        </xs:documentation>
+                                    </xs:annotation>
+                                </xs:attribute>
+                            </xs:extension>
+                        </xs:complexContent>
+                    </xs:complexType>
+                </xs:element>
                 <xs:element minOccurs="0" ref="actions" />
                 <xs:element minOccurs="0" ref="link" />
                 <xs:element minOccurs="0" maxOccurs="unbounded" ref="menu-item" />
@@ -294,8 +320,6 @@
         </xs:complexType>
     </xs:element>
 
-    <!-- ================ ACTIONS ================ -->
-    <xs:element name="AllActions" abstract="true"/>
     <xs:element name="actions">
         <xs:complexType>
             <xs:sequence>
@@ -303,194 +327,20 @@
             </xs:sequence>
         </xs:complexType>
     </xs:element>
-    <xs:element name="property-map" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="resource" use="required" />
-            <xs:attribute type="xs:string" name="map-name" use="required" />
-            <xs:attribute name="global" 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="property-to-field" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="resource" use="required" />
-            <xs:attribute type="xs:string" name="property" use="required" />
-            <xs:attribute type="xs:string" name="field" use="required" />
-            <xs:attribute type="xs:string" name="default" />
-            <xs:attribute name="no-locale" 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 type="xs:string" name="arg-list-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="script" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="location" use="required" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="set" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field" use="required" />
-            <xs:attribute type="xs:string" name="from-field" />
-            <xs:attribute type="xs:string" name="value" />
-            <xs:attribute type="xs:string" name="default-value" />
-            <xs:attribute name="global" 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="type" default="String">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="PlainString" />
-                        <xs:enumeration value="String" />
-                        <xs:enumeration value="BigDecimal" />
-                        <xs:enumeration value="Double" />
-                        <xs:enumeration value="Float" />
-                        <xs:enumeration value="List" />
-                        <xs:enumeration value="Long" />
-                        <xs:enumeration value="Integer" />
-                        <xs:enumeration value="Date" />
-                        <xs:enumeration value="Time" />
-                        <xs:enumeration value="Timestamp" />
-                        <xs:enumeration value="Boolean" />
-                        <xs:enumeration value="Object" />
-                        <xs:enumeration value="NewList" />
-                        <xs:enumeration value="NewMap" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="to-scope" default="screen">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="screen" />
-                        <xs:enumeration value="user" />
-                        <xs:enumeration value="application" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="from-scope" default="screen">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="screen" />
-                        <xs:enumeration value="user" />
-                        <xs:enumeration value="application" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-
-    <!-- ================ CONDITIONS ================ -->
-    <xs:element name="AllConditionals" abstract="true"/>
-    <xs:element name="condition">
+    <xs:element name="entity-and" substitutionGroup="AllActions">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="1" maxOccurs="1" ref="AllConditionals" />
+                <xs:element maxOccurs="unbounded" ref="field-map" />
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="select-field" />
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="order-by" />
+                <xs:choice minOccurs="0">
+                    <xs:element ref="limit-range" />
+                    <xs:element ref="limit-view" />
+                    <xs:element ref="use-iterator" />
+                </xs:choice>
             </xs:sequence>
-            <xs:attribute type="xs:string" name="pass-style">
-                <xs:annotation>
-                    <xs:documentation>
-                        If a pass-style provided and the condition passes, the widget-style of
-                        the parent menu-item is set with the pass-style. If no pass-style is given,
-                        the widget-style is not changed.
-                </xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="disabled-style">
-                <xs:annotation>
-                    <xs:documentation>
-                        If a disabled-style provided and the condition fails, the disabled-style of
-                        the parent menu-item is set with the disabled-style and processing is allowed to continue.
-                        If no disabled-style is given, the widget-style is not changed and the menu-item is not rendered.
-                </xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="and" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="xor" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="or" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="not" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-service-permission" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="service-name" use="required" />
-            <xs:attribute type="xs:string" name="resource-description" use="optional" />
-            <xs:attribute name="main-action" use="optional">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="CREATE" />
-                        <xs:enumeration value="UPDATE" />
-                        <xs:enumeration value="DELETE" />
-                        <xs:enumeration value="VIEW" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-has-permission" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="permission" use="required" />
-            <xs:attribute type="xs:string" name="action" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-entity-permission" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:choice minOccurs="0">
-                <xs:element minOccurs="0" maxOccurs="1" ref="permission-condition-getter" />
-                <xs:element minOccurs="0" maxOccurs="1" ref="related-role-getter" />
-                <xs:element minOccurs="0" maxOccurs="1" ref="auxiliary-value-getter" />
-            </xs:choice>
             <xs:attribute type="xs:string" name="entity-name" use="required" />
-            <xs:attribute type="xs:string" name="entity-id" use="required">
-                <xs:annotation>
-                    <xs:documentation>Can have multiple pipe separated values, but don't use spaces.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="target-operation" use="required">
-                <xs:annotation>
-                    <xs:documentation>Can have multiple pipe separated values, but don't use spaces.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="display-fail-cond" default="false">
+            <xs:attribute name="use-cache" default="false">
                 <xs:simpleType>
                     <xs:restriction base="xs:token">
                         <xs:enumeration value="true" />
@@ -498,130 +348,79 @@
                     </xs:restriction>
                 </xs:simpleType>
             </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="permission-condition-getter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="entity-name" />
-            <xs:attribute type="xs:string" name="operation-field-name" />
-            <xs:attribute type="xs:string" name="role-field-name" />
-            <xs:attribute type="xs:string" name="auxiliary-field-name" />
-            <xs:attribute type="xs:string" name="status-field-name" />
-            <xs:attribute type="xs:string" name="privilege-field-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="related-role-getter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="entity-name" />
-            <xs:attribute type="xs:string" name="role-entity-name" />
-            <xs:attribute type="xs:string" name="role-type-field-name" />
-            <xs:attribute type="xs:string" name="party-field-name" />
-            <xs:attribute type="xs:string" name="owner-entity-field-name" />
-            <xs:attribute type="xs:string" name="entity-id-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="auxiliary-value-getter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="entity-name" />
-            <xs:attribute type="xs:string" name="auxiliary-field-name" />
-            <xs:attribute type="xs:string" name="entity-id-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-validate-method" substitutionGroup="AllConditionals">
-        <xs:annotation>
-            <xs:documentation>Calls a static Java method that takes a String and returns a boolean.</xs:documentation>
-        </xs:annotation>
-        <xs:complexType>
-            <xs:attribute name="field" use="required" />
-            <xs:attribute name="method" use="required" />
-            <xs:attribute name="class" default="org.ofbiz.base.util.UtilValidate" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-compare" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute name="field" use="required" />
-            <xs:attribute name="operator" use="required">
+            <xs:attribute name="filter-by-date" default="false">
                 <xs:simpleType>
                     <xs:restriction base="xs:token">
-                        <xs:enumeration value="less" />
-                        <xs:enumeration value="greater" />
-                        <xs:enumeration value="less-equals" />
-                        <xs:enumeration value="greater-equals" />
-                        <xs:enumeration value="equals" />
-                        <xs:enumeration value="not-equals" />
-                        <xs:enumeration value="contains" />
+                        <xs:enumeration value="true" />
+                        <xs:enumeration value="false" />
+                        <xs:enumeration value="by-name" />
                     </xs:restriction>
                 </xs:simpleType>
             </xs:attribute>
-            <xs:attribute name="value" use="required" />
-            <xs:attribute name="type" default="String">
+            <xs:attribute type="xs:string" name="list" use="required" />
+            <xs:attribute name="result-set-type" default="scroll">
                 <xs:simpleType>
                     <xs:restriction base="xs:token">
-                        <xs:enumeration value="PlainString" />
-                        <xs:enumeration value="String" />
-                        <xs:enumeration value="BigDecimal" />
-                        <xs:enumeration value="Double" />
-                        <xs:enumeration value="Float" />
-                        <xs:enumeration value="Long" />
-                        <xs:enumeration value="Integer" />
-                        <xs:enumeration value="Date" />
-                        <xs:enumeration value="Time" />
-                        <xs:enumeration value="Timestamp" />
-                        <xs:enumeration value="Boolean" />
-                        <xs:enumeration value="Object" />
+                        <xs:enumeration value="forward" />
+                        <xs:enumeration value="scroll" />
                     </xs:restriction>
                 </xs:simpleType>
             </xs:attribute>
-            <xs:attribute name="format" />
         </xs:complexType>
     </xs:element>
-    <xs:element name="if-compare-field" substitutionGroup="AllConditionals">
+    <xs:element name="entity-condition" substitutionGroup="AllActions">
         <xs:complexType>
-            <xs:attribute name="field" use="required" />
-            <xs:attribute name="operator" use="required">
+            <xs:sequence>
+                <xs:choice minOccurs="0">
+                    <xs:element ref="condition-expr" />
+                    <xs:element ref="condition-list" />
+                    <xs:element ref="condition-object" />
+                </xs:choice>
+                <xs:element minOccurs="0" ref="having-condition-list" />
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="select-field" />
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="order-by" />
+                <xs:choice minOccurs="0">
+                    <xs:element ref="limit-range" />
+                    <xs:element ref="limit-view" />
+                    <xs:element ref="use-iterator" />
+                </xs:choice>
+            </xs:sequence>
+            <xs:attribute type="xs:string" name="entity-name" use="required" />
+            <xs:attribute name="use-cache" default="false">
                 <xs:simpleType>
                     <xs:restriction base="xs:token">
-                        <xs:enumeration value="less" />
-                        <xs:enumeration value="greater" />
-                        <xs:enumeration value="less-equals" />
-                        <xs:enumeration value="greater-equals" />
-                        <xs:enumeration value="equals" />
-                        <xs:enumeration value="not-equals" />
-                        <xs:enumeration value="contains" />
+                        <xs:enumeration value="true" />
+                        <xs:enumeration value="false" />
                     </xs:restriction>
                 </xs:simpleType>
             </xs:attribute>
-            <xs:attribute name="to-field" />
-            <xs:attribute name="type" default="String">
+            <xs:attribute name="filter-by-date" default="false">
                 <xs:simpleType>
                     <xs:restriction base="xs:token">
-                        <xs:enumeration value="PlainString" />
-                        <xs:enumeration value="String" />
-                        <xs:enumeration value="BigDecimal" />
-                        <xs:enumeration value="Double" />
-                        <xs:enumeration value="Float" />
-                        <xs:enumeration value="Long" />
-                        <xs:enumeration value="Integer" />
-                        <xs:enumeration value="Date" />
-                        <xs:enumeration value="Time" />
-                        <xs:enumeration value="Timestamp" />
-                        <xs:enumeration value="Boolean" />
-                        <xs:enumeration value="Object" />
+                        <xs:enumeration value="true" />
+                        <xs:enumeration value="false" />
+                        <xs:enumeration value="by-name" />
                     </xs:restriction>
                 </xs:simpleType>
             </xs:attribute>
-            <xs:attribute name="format" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-regexp" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute name="field" use="required" />
-            <xs:attribute name="expr" use="required" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-empty" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute name="field" use="required" />
+            <xs:attribute name="distinct" 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 type="xs:string" name="delegator-name" />
+            <xs:attribute type="xs:string" name="list" use="required" />
+            <xs:attribute name="result-set-type" default="scroll">
+                <xs:simpleType>
+                    <xs:restriction base="xs:token">
+                        <xs:enumeration value="forward" />
+                        <xs:enumeration value="scroll" />
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
         </xs:complexType>
     </xs:element>
 </xs:schema>
diff --git a/framework/widget/dtd/widget-screen.xsd b/framework/widget/dtd/widget-screen.xsd
index 5a725d1..669ff38 100644
--- a/framework/widget/dtd/widget-screen.xsd
+++ b/framework/widget/dtd/widget-screen.xsd
@@ -18,10 +18,11 @@
 under the License.
 -->
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+    <xs:include schemaLocation="http://ofbiz.apache.org/dtds/widget-common.xsd" />
     <xs:element name="screens">
         <xs:complexType>
             <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="screen"/>
+                <xs:element maxOccurs="unbounded" ref="screen" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
@@ -57,7 +58,7 @@
     <xs:element name="section" substitutionGroup="AllWidgets">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" ref="condition" />
+                <xs:element name="condition" type="ScreenConditionRootType" minOccurs="0" />
                 <xs:element minOccurs="0" ref="actions" />
                 <xs:element minOccurs="0" ref="widgets" />
                 <xs:element minOccurs="0" ref="fail-widgets" />
@@ -67,217 +68,25 @@
     </xs:element>
 
     <!-- ================ CONDITIONS ================ -->
-    <xs:element name="AllConditionals" abstract="true"/>
-    <xs:element name="condition">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="1" maxOccurs="1" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="and" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="xor" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="or" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="not" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-service-permission" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="service-name" use="required" />
-            <xs:attribute type="xs:string" name="resource-description" use="optional" />
-            <xs:attribute type="xs:string" name="context-map" use="optional" />
-            <xs:attribute name="main-action" use="optional">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="CREATE" />
-                        <xs:enumeration value="UPDATE" />
-                        <xs:enumeration value="DELETE" />
-                        <xs:enumeration value="VIEW" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-has-permission" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="permission" use="required" />
-            <xs:attribute type="xs:string" name="action" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-entity-permission" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:choice minOccurs="0">
-                <xs:element minOccurs="0" maxOccurs="1" ref="permission-condition-getter" />
-                <xs:element minOccurs="0" maxOccurs="1" ref="related-role-getter" />
-                <xs:element minOccurs="0" maxOccurs="1" ref="auxiliary-value-getter" />
-            </xs:choice>
-            <xs:attribute type="xs:string" name="entity-name" use="required" />
-            <xs:attribute type="xs:string" name="entity-id" use="required">
-                <xs:annotation>
-                    <xs:documentation>Can have multiple pipe separated values, but don't use spaces.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="target-operation" use="required">
-                <xs:annotation>
-                    <xs:documentation>Can have multiple pipe separated values, but don't use spaces.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="display-fail-cond" 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="permission-condition-getter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="entity-name" />
-            <xs:attribute type="xs:string" name="operation-field-name" />
-            <xs:attribute type="xs:string" name="role-field-name" />
-            <xs:attribute type="xs:string" name="auxiliary-field-name" />
-            <xs:attribute type="xs:string" name="status-field-name" />
-            <xs:attribute type="xs:string" name="privilege-field-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="related-role-getter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="entity-name" />
-            <xs:attribute type="xs:string" name="role-entity-name" />
-            <xs:attribute type="xs:string" name="role-type-field-name" />
-            <xs:attribute type="xs:string" name="party-field-name" />
-            <xs:attribute type="xs:string" name="owner-entity-field-name" />
-            <xs:attribute type="xs:string" name="entity-id-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="auxiliary-value-getter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="entity-name" />
-            <xs:attribute type="xs:string" name="auxiliary-field-name" />
-            <xs:attribute type="xs:string" name="entity-id-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-validate-method" substitutionGroup="AllConditionals">
-        <xs:annotation>
-            <xs:documentation>Calls a static Java method that takes a String and returns a boolean.</xs:documentation>
-        </xs:annotation>
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field" use="required" />
-            <xs:attribute type="xs:string" name="method" use="required" />
-            <xs:attribute type="xs:string" name="class" default="org.ofbiz.base.util.UtilValidate" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-compare" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute name="field" type="xs:string" use="required" />
-            <xs:attribute name="operator" use="required">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="less" />
-                        <xs:enumeration value="greater" />
-                        <xs:enumeration value="less-equals" />
-                        <xs:enumeration value="greater-equals" />
-                        <xs:enumeration value="equals" />
-                        <xs:enumeration value="not-equals" />
-                        <xs:enumeration value="contains" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="value" type="xs:string" use="required" />
-            <xs:attribute name="type" default="String">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="PlainString" />
-                        <xs:enumeration value="String" />
-                        <xs:enumeration value="BigDecimal" />
-                        <xs:enumeration value="Double" />
-                        <xs:enumeration value="Float" />
-                        <xs:enumeration value="Long" />
-                        <xs:enumeration value="Integer" />
-                        <xs:enumeration value="Date" />
-                        <xs:enumeration value="Time" />
-                        <xs:enumeration value="Timestamp" />
-                        <xs:enumeration value="Boolean" />
-                        <xs:enumeration value="Object" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="format" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-compare-field" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute name="field" type="xs:string" use="required" />
-            <xs:attribute name="operator" use="required">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="less" />
-                        <xs:enumeration value="greater" />
-                        <xs:enumeration value="less-equals" />
-                        <xs:enumeration value="greater-equals" />
-                        <xs:enumeration value="equals" />
-                        <xs:enumeration value="not-equals" />
-                        <xs:enumeration value="contains" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="to-field" type="xs:string" />
-            <xs:attribute name="type" default="String">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="PlainString" />
-                        <xs:enumeration value="String" />
-                        <xs:enumeration value="BigDecimal" />
-                        <xs:enumeration value="Double" />
-                        <xs:enumeration value="Float" />
-                        <xs:enumeration value="Long" />
-                        <xs:enumeration value="Integer" />
-                        <xs:enumeration value="Date" />
-                        <xs:enumeration value="Time" />
-                        <xs:enumeration value="Timestamp" />
-                        <xs:enumeration value="Boolean" />
-                        <xs:enumeration value="Object" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="format" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-regexp" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field" use="required" />
-            <xs:attribute type="xs:string" name="expr" use="required" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-empty" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field" use="required" />
-        </xs:complexType>
-    </xs:element>
+
+    <xs:complexType name="ScreenConditionRootType">
+        <xs:choice>
+            <xs:element ref="and" />
+            <xs:element ref="or" />
+            <xs:element ref="xor" />
+            <xs:element ref="not" />
+            <xs:element ref="if-service-permission" />
+            <xs:element ref="if-has-permission" />
+            <xs:element ref="if-entity-permission" />
+            <xs:element ref="if-validate-method" />
+            <xs:element ref="if-compare" />
+            <xs:element ref="if-compare-field" />
+            <xs:element ref="if-regexp" />
+            <xs:element ref="if-empty" />
+            <xs:element ref="if-empty-section" />
+        </xs:choice>
+    </xs:complexType>
+
     <xs:element name="if-empty-section" substitutionGroup="AllConditionals">
         <xs:complexType>
             <xs:attribute type="xs:string" name="section-name" use="required" />
@@ -285,105 +94,14 @@
     </xs:element>
 
     <!-- ================ ACTIONS ================ -->
-    <xs:element name="AllActions" abstract="true"/>
+
     <xs:element name="actions">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllActions"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllActions" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
-    <xs:element name="set" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field" use="required" />
-            <xs:attribute type="xs:string" name="from-field" />
-            <xs:attribute type="xs:string" name="value" />
-            <xs:attribute type="xs:string" name="default-value" />
-            <xs:attribute name="global" 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="type">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="PlainString" />
-                        <xs:enumeration value="String" />
-                        <xs:enumeration value="BigDecimal" />
-                        <xs:enumeration value="Double" />
-                        <xs:enumeration value="Float" />
-                        <xs:enumeration value="List" />
-                        <xs:enumeration value="Long" />
-                        <xs:enumeration value="Integer" />
-                        <xs:enumeration value="Date" />
-                        <xs:enumeration value="Time" />
-                        <xs:enumeration value="Timestamp" />
-                        <xs:enumeration value="Boolean" />
-                        <xs:enumeration value="Object" />
-                        <xs:enumeration value="NewList" />
-                        <xs:enumeration value="NewMap" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="to-scope" default="screen">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="screen" />
-                        <xs:enumeration value="user" />
-                        <xs:enumeration value="application" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="from-scope" default="screen">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="screen" />
-                        <xs:enumeration value="user" />
-                        <xs:enumeration value="application" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="property-map" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="resource" use="required" />
-            <xs:attribute type="xs:string" name="map-name" use="required" />
-            <xs:attribute name="global" 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="property-to-field" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="resource" use="required" />
-            <xs:attribute type="xs:string" name="property" use="required" />
-            <xs:attribute type="xs:string" name="field" use="required" />
-            <xs:attribute type="xs:string" name="default" />
-            <xs:attribute name="no-locale" 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 type="xs:string" name="arg-list-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="script" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="location" use="required" />
-        </xs:complexType>
-    </xs:element>
     <xs:element name="service" substitutionGroup="AllActions">
         <xs:complexType>
             <xs:sequence>
@@ -398,7 +116,6 @@
             </xs:attribute>
         </xs:complexType>
     </xs:element>
-
     <xs:element name="entity-and" substitutionGroup="AllActions">
         <xs:complexType>
             <xs:sequence>
@@ -495,204 +212,21 @@
             </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:element name="entity-one" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="field-map" />
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="select-field" />
-            </xs:sequence>
-            <xs:attribute name="entity-name" type="xs:string" use="required" />
-            <xs:attribute name="value-field" type="xs:string" use="required" />
-            <xs:attribute name="use-cache" 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="auto-field-map" 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="get-related-one" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:attribute name="value-field" type="xs:string" use="required" />
-            <xs:attribute name="relation-name" type="xs:string" use="required" />
-            <xs:attribute name="use-cache" type="xs:string" default="false" />
-            <xs:attribute name="to-value-field" type="xs:string" use="required" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="get-related" substitutionGroup="AllActions">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="value-field" use="required" />
-            <xs:attribute type="xs:string" name="relation-name" use="required" />
-            <xs:attribute type="xs:string" name="map" />
-            <xs:attribute type="xs:string" name="order-by-list" />
-            <xs:attribute type="xs:string" name="use-cache" default="false" />
-            <xs:attribute type="xs:string" name="list" use="required" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="condition-list">
-        <xs:complexType>
-            <xs:choice maxOccurs="unbounded">
-                <xs:element ref="condition-expr" />
-                <xs:element ref="condition-list" />
-                <xs:element ref="condition-object" />
-            </xs:choice>
-            <xs:attribute name="combine" default="and">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="and" />
-                        <xs:enumeration value="or" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="having-condition-list">
-        <xs:complexType>
-            <xs:choice maxOccurs="unbounded">
-                <xs:element ref="condition-expr" />
-                <xs:element ref="condition-list" />
-                <xs:element ref="condition-object" />
-            </xs:choice>
-            <xs:attribute name="combine" default="and">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="and" />
-                        <xs:enumeration value="or" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="condition-expr">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field-name" use="required" />
-            <xs:attribute name="operator" default="equals">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="less" />
-                        <xs:enumeration value="greater" />
-                        <xs:enumeration value="less-equals" />
-                        <xs:enumeration value="greater-equals" />
-                        <xs:enumeration value="equals" />
-                        <xs:enumeration value="not-equals" />
-                        <xs:enumeration value="in" />
-                        <xs:enumeration value="not-in" />
-                        <xs:enumeration value="between" />
-                        <xs:enumeration value="like" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="from-field" />
-            <xs:attribute type="xs:string" name="value" />
-            <xs:attribute name="ignore-if-null" 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="ignore-if-empty" 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="ignore-case" 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="ignore" default="false">
-                <xs:annotation>
-                    <xs:documentation>
-                        Ignore the condition if flag is true.
-                        Defaults to false.
-                </xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="condition-object">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field" use="required" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="select-field">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field-name" use="required" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="order-by">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field-name" use="required" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="limit-range">
-        <xs:complexType>
-            <xs:attribute name="start" type="xs:string" use="required">
-                <xs:annotation>
-                    <xs:documentation>Should resolve into a non-negative integer.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="size" type="xs:string" use="required">
-                <xs:annotation>
-                    <xs:documentation>Should resolve into a non-negative integer.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="limit-view">
-        <xs:complexType>
-            <xs:attribute name="view-index" type="xs:string" use="required">
-                <xs:annotation>
-                    <xs:documentation>Should resolve into a non-negative integer.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="view-size" type="xs:string" use="required">
-                <xs:annotation>
-                    <xs:documentation>Should resolve into a positive integer.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="use-iterator" />
-    <xs:element name="field-map">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field-name" use="required" />
-            <xs:attribute type="xs:string" name="from-field" />
-            <xs:attribute type="xs:string" name="value" />
-        </xs:complexType>
-    </xs:element>
 
     <!-- ================ WIDGETS ================ -->
-    <xs:element name="AllWidgets" abstract="true"/>
+
+    <xs:element name="AllWidgets" abstract="true" />
     <xs:element name="widgets">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
     <xs:element name="fail-widgets">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllWidgets" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
@@ -725,7 +259,8 @@
             <xs:attribute type="xs:string" name="auto-update-target">
                 <xs:annotation>
                     <xs:documentation>The URL to be called for periodic asynchronous area updates.
-                        Some widget rendering environments support asynchronous updates.</xs:documentation>
+                        Some widget rendering environments support asynchronous updates.
+                    </xs:documentation>
                 </xs:annotation>
             </xs:attribute>
             <xs:attribute type="xs:string" name="auto-update-interval">
@@ -772,8 +307,8 @@
     <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" 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>
@@ -792,7 +327,7 @@
                         <xs:enumeration value="auto">
                             <xs:annotation>
                                 <xs:documentation>
-                                    If selected the hidden-form type will be used if the url-mode is intra-app 
+                                    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>
@@ -850,18 +385,18 @@
     <xs:element name="auto-parameters-service">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="exclude"/>
+                <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. If empty, use form defaultServiceName. Flexible string allowed.</xs:documentation>
-                 </xs:annotation>
+                <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:enumeration value="true" />
+                        <xs:enumeration value="false" />
                     </xs:restriction>
                 </xs:simpleType>
             </xs:attribute>
@@ -870,27 +405,27 @@
     <xs:element name="auto-parameters-entity">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="exclude"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="exclude" />
             </xs:sequence>
             <xs:attribute name="entity-name" type="xs:string" use="required">
-                 <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: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: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:enumeration value="true" />
+                        <xs:enumeration value="false" />
                     </xs:restriction>
                 </xs:simpleType>
             </xs:attribute>
@@ -898,7 +433,7 @@
     </xs:element>
     <xs:element name="exclude">
         <xs:complexType>
-            <xs:attribute name="field-name" type="xs:string" use="required"/>
+            <xs:attribute name="field-name" type="xs:string" use="required" />
         </xs:complexType>
     </xs:element>
 
@@ -968,6 +503,7 @@
     </xs:element>
 
     <!-- ================ WIDGETS - Includers ================ -->
+
     <xs:element name="content" substitutionGroup="AllWidgets">
         <xs:complexType>
             <xs:attribute type="xs:string" name="content-id" />
@@ -1148,57 +684,58 @@
     <xs:element name="platform-specific" substitutionGroup="AllWidgets">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" ref="html"/>
-                <xs:element minOccurs="0" ref="swing"/>
-                <xs:element minOccurs="0" ref="xsl-fo"/>
-                <xs:element minOccurs="0" ref="xml"/>
+                <xs:element minOccurs="0" ref="html" />
+                <xs:element minOccurs="0" ref="swing" />
+                <xs:element minOccurs="0" ref="xsl-fo" />
+                <xs:element minOccurs="0" ref="xml" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
     <!-- ============== HTML Specific Elements =============== -->
-    <xs:element name="HtmlWidgets" abstract="true"/>
+    <xs:element name="HtmlWidgets" abstract="true" />
     <xs:element name="html">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
     <xs:element name="xsl-fo">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
     <xs:element name="xml">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="HtmlWidgets" />
             </xs:sequence>
         </xs:complexType>
     </xs:element>
     <xs:element name="html-template" substitutionGroup="HtmlWidgets">
         <xs:complexType>
-            <xs:attributeGroup ref="attlist.html-template"/>
+            <xs:attributeGroup ref="attlist.html-template" />
         </xs:complexType>
     </xs:element>
     <xs:attributeGroup name="attlist.html-template">
-        <xs:attribute type="xs:string" name="location" use="required"/>
+        <xs:attribute type="xs:string" name="location" use="required" />
     </xs:attributeGroup>
     <xs:element name="html-template-decorator" substitutionGroup="HtmlWidgets">
         <xs:annotation>
             <xs:documentation>
                 We don't really want to encourage the use of the html-template-decorator, should be done on the screen level.
                 To include the sections in the decorator template just use the "render(sectionName)" method "sections" object, FTL example: ${sections.render("main")}.
-                For more efficient use the sections.render(sectionName, writer) method should be used, in FTL this would be in a transform or something.
+                For more
+                efficient use the sections.render(sectionName, writer) method should be used, in FTL this would be in a transform or something.
             </xs:documentation>
         </xs:annotation>
         <xs:complexType>
             <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="html-template-decorator-section"/>
+                <xs:element maxOccurs="unbounded" ref="html-template-decorator-section" />
             </xs:sequence>
-        <xs:attribute type="xs:string" name="location" use="required"/>
+            <xs:attribute type="xs:string" name="location" use="required" />
         </xs:complexType>
     </xs:element>
     <xs:element name="html-template-decorator-section">
@@ -1211,6 +748,6 @@
     </xs:element>
     <!-- ============== Swing Specific Elements =============== -->
     <xs:element name="swing">
-        <xs:complexType/>
+        <xs:complexType />
     </xs:element>
 </xs:schema>
diff --git a/framework/widget/dtd/widget-tree.xsd b/framework/widget/dtd/widget-tree.xsd
index 92457fc..1c59863 100644
--- a/framework/widget/dtd/widget-tree.xsd
+++ b/framework/widget/dtd/widget-tree.xsd
@@ -18,6 +18,7 @@
 under the License.
 -->
 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+    <xs:include schemaLocation="http://ofbiz.apache.org/dtds/widget-common.xsd" />
     <xs:element name="trees">
         <xs:complexType>
             <xs:sequence>
@@ -61,8 +62,9 @@
     <xs:element name="node">
         <xs:complexType>
             <xs:sequence>
-                <xs:element minOccurs="0" ref="condition" />
+                <xs:element name="condition" type="ConditionRootType" minOccurs="0" />
                 <xs:choice minOccurs="0">
+                    <xs:element ref="actions" />
                     <xs:element ref="entity-one" />
                     <xs:element ref="service" />
                 </xs:choice>
@@ -94,6 +96,7 @@
         <xs:complexType>
             <xs:sequence>
                 <xs:choice>
+                    <xs:element ref="actions" />
                     <xs:element ref="entity-and" />
                     <xs:element ref="service" />
                     <xs:element ref="entity-condition" />
@@ -103,7 +106,6 @@
             <xs:attribute type="xs:string" name="node-name" use="required" />
         </xs:complexType>
     </xs:element>
-
     <xs:element name="include-screen">
         <xs:complexType>
             <xs:attribute type="xs:string" name="name" use="required" />
@@ -201,7 +203,13 @@
         </xs:attribute>
         </xs:complexType>
     </xs:element>
-
+    <xs:element name="actions">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="AllActions"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
     <xs:element name="service">
         <xs:complexType>
             <xs:sequence>
@@ -215,12 +223,10 @@
                 </xs:annotation>
             </xs:attribute>
             <xs:attribute type="xs:string" name="result-map-list" />
-            <!-- deprecated, use result-map-list instead <xs:attribute type="xs:string" name="result-map-list-iterator-name"/> -->
             <xs:attribute type="xs:string" name="result-map-value" />
             <xs:attribute type="xs:string" name="value" />
         </xs:complexType>
     </xs:element>
-
     <xs:element name="entity-and">
         <xs:complexType>
             <xs:sequence>
@@ -311,355 +317,10 @@
             </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:element name="entity-one">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="field-map" />
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="select-field" />
-            </xs:sequence>
-            <xs:attribute name="entity-name" type="xs:string" use="required" />
-            <xs:attribute name="value-field" type="xs:string" />
-            <xs:attribute name="use-cache" 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="auto-field-map" 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="order-by">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field-name" use="required" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="select-field">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field-name" use="required" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="limit-range">
-        <xs:complexType>
-            <xs:attribute name="start" type="xs:string" use="required">
-                <xs:annotation>
-                    <xs:documentation>Should resolve into a non-negative integer.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="size" type="xs:string" use="required">
-                <xs:annotation>
-                    <xs:documentation>Should resolve into a non-negative integer.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="limit-view">
-        <xs:complexType>
-            <xs:attribute name="view-index" type="xs:string" use="required">
-                <xs:annotation>
-                    <xs:documentation>Should resolve into a non-negative integer.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="view-size" type="xs:string" use="required">
-                <xs:annotation>
-                    <xs:documentation>Should resolve into a positive integer.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="use-iterator" />
-    <xs:element name="field-map">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field-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="out-field-map">
         <xs:complexType>
             <xs:attribute type="xs:string" name="field-name" use="required" />
             <xs:attribute type="xs:string" name="to-field-name" />
         </xs:complexType>
     </xs:element>
-
-    <xs:element name="condition-list">
-        <xs:complexType>
-            <xs:choice maxOccurs="unbounded">
-                <xs:element ref="condition-expr" />
-                <xs:element ref="condition-list" />
-            </xs:choice>
-            <xs:attribute name="combine" default="and">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="and" />
-                        <xs:enumeration value="or" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="having-condition-list">
-        <xs:complexType>
-            <xs:choice maxOccurs="unbounded">
-                <xs:element ref="condition-expr" />
-                <xs:element ref="condition-list" />
-            </xs:choice>
-            <xs:attribute name="combine" default="and">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="and" />
-                        <xs:enumeration value="or" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="condition-expr">
-        <xs:complexType>
-            <xs:attribute name="field-name" type="xs:string" use="required" />
-            <xs:attribute name="operator" default="equals">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="less" />
-                        <xs:enumeration value="greater" />
-                        <xs:enumeration value="less-equals" />
-                        <xs:enumeration value="greater-equals" />
-                        <xs:enumeration value="equals" />
-                        <xs:enumeration value="not-equals" />
-                        <xs:enumeration value="in" />
-                        <xs:enumeration value="between" />
-                        <xs:enumeration value="like" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="from-field" type="xs:string" />
-            <xs:attribute name="value" type="xs:string" />
-            <xs:attribute name="ignore-if-null" 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="ignore-if-empty" 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="ignore-case" 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="ignore" default="false">
-                <xs:annotation>
-                    <xs:documentation>
-                        Ignore the condition if flag is true.
-                        Defaults to false.
-                </xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-
-    <!-- ================ CONDITIONS ================ -->
-    <xs:element name="AllConditionals" abstract="true"/>
-    <xs:element name="condition">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="1" maxOccurs="1" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="and" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="xor" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="or" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="not" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element ref="AllConditionals"/>
-            </xs:sequence>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-has-permission" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="permission" use="required" />
-            <xs:attribute type="xs:string" name="action" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-entity-permission" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:choice minOccurs="0">
-                <xs:element minOccurs="0" maxOccurs="1" ref="permission-condition-getter" />
-                <xs:element minOccurs="0" maxOccurs="1" ref="related-role-getter" />
-                <xs:element minOccurs="0" maxOccurs="1" ref="auxiliary-value-getter" />
-            </xs:choice>
-            <xs:attribute type="xs:string" name="entity-name" use="required" />
-            <xs:attribute type="xs:string" name="entity-id" use="required" />
-            <xs:attribute type="xs:string" name="target-operation" use="required" />
-            <xs:attribute name="display-fail-cond" 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="permission-condition-getter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="entity-name" />
-            <xs:attribute type="xs:string" name="operation-field-name" />
-            <xs:attribute type="xs:string" name="role-field-name" />
-            <xs:attribute type="xs:string" name="auxiliary-field-name" />
-            <xs:attribute type="xs:string" name="status-field-name" />
-            <xs:attribute type="xs:string" name="privilege-field-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="related-role-getter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="entity-name" />
-            <xs:attribute type="xs:string" name="role-entity-name" />
-            <xs:attribute type="xs:string" name="role-type-field-name" />
-            <xs:attribute type="xs:string" name="party-field-name" />
-            <xs:attribute type="xs:string" name="owner-entity-field-name" />
-            <xs:attribute type="xs:string" name="entity-id-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="auxiliary-value-getter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="entity-name" />
-            <xs:attribute type="xs:string" name="auxiliary-field-name" />
-            <xs:attribute type="xs:string" name="entity-id-name" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-validate-method" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field" use="required" />
-            <xs:attribute type="xs:string" name="method" use="required" />
-            <xs:attribute type="xs:string" name="class" default="org.ofbiz.base.util.UtilValidate" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-compare" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute name="field" type="xs:string" use="required" />
-            <xs:attribute name="operator" use="required">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="less" />
-                        <xs:enumeration value="greater" />
-                        <xs:enumeration value="less-equals" />
-                        <xs:enumeration value="greater-equals" />
-                        <xs:enumeration value="equals" />
-                        <xs:enumeration value="not-equals" />
-                        <xs:enumeration value="contains" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="value" use="required" />
-            <xs:attribute name="type" default="String">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="PlainString" />
-                        <xs:enumeration value="String" />
-                        <xs:enumeration value="BigDecimal" />
-                        <xs:enumeration value="Double" />
-                        <xs:enumeration value="Float" />
-                        <xs:enumeration value="Long" />
-                        <xs:enumeration value="Integer" />
-                        <xs:enumeration value="Date" />
-                        <xs:enumeration value="Time" />
-                        <xs:enumeration value="Timestamp" />
-                        <xs:enumeration value="Boolean" />
-                        <xs:enumeration value="Object" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="format" type="xs:string" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-compare-field" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute name="field" type="xs:string" use="required" />
-            <xs:attribute name="operator" use="required">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="less" />
-                        <xs:enumeration value="greater" />
-                        <xs:enumeration value="less-equals" />
-                        <xs:enumeration value="greater-equals" />
-                        <xs:enumeration value="equals" />
-                        <xs:enumeration value="not-equals" />
-                        <xs:enumeration value="contains" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="to-field" type="xs:string" />
-            <xs:attribute name="type" default="String">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="PlainString" />
-                        <xs:enumeration value="String" />
-                        <xs:enumeration value="BigDecimal" />
-                        <xs:enumeration value="Double" />
-                        <xs:enumeration value="Float" />
-                        <xs:enumeration value="Long" />
-                        <xs:enumeration value="Integer" />
-                        <xs:enumeration value="Date" />
-                        <xs:enumeration value="Time" />
-                        <xs:enumeration value="Timestamp" />
-                        <xs:enumeration value="Boolean" />
-                        <xs:enumeration value="Object" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="format" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-regexp" substitutionGroup="AllConditionals">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="field" use="required" />
-            <xs:attribute type="xs:string" name="expr" use="required" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="if-empty" substitutionGroup="AllConditionals">
-        <xs:complexType>
-        <xs:attribute type="xs:string" name="field" use="required"/>
-        </xs:complexType>
-    </xs:element>
 </xs:schema>
\ No newline at end of file
diff --git a/framework/widget/src/org/ofbiz/widget/ModelActionVisitor.java b/framework/widget/src/org/ofbiz/widget/ModelActionVisitor.java
index 0d456bd..a0bb5e0 100644
--- a/framework/widget/src/org/ofbiz/widget/ModelActionVisitor.java
+++ b/framework/widget/src/org/ofbiz/widget/ModelActionVisitor.java
@@ -51,10 +51,6 @@
 

     void visit(ModelFormAction.Service service);

 

-    void visit(ModelFormAction.EntityAnd entityAnd);

-

-    void visit(ModelFormAction.EntityCondition entityCondition);

-

     void visit(ModelMenuAction.SetField setField);

 

     void visit(ModelTreeAction.Script script);

diff --git a/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java b/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
index 91758b1..e12f3ca 100644
--- a/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
+++ b/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
@@ -60,24 +60,36 @@
 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();
 
-    protected ModelWidget modelWidget;
-
-    protected ModelWidgetAction() {}
-
-    public ModelWidgetAction(ModelWidget modelWidget, Element actionElement) {
-        this.modelWidget = modelWidget;
-        if (Debug.verboseOn()) Debug.logVerbose("Reading widget action with name: " + actionElement.getNodeName(), module);
-    }
-
-    public abstract void runAction(Map<String, Object> context) throws GeneralException;
-
-    public abstract void accept(ModelActionVisitor visitor);
-
-    public static ModelWidgetAction toModelWidgetAction(ModelWidget modelWidget, Element actionElement) {
+    /**
+     * 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())) {
@@ -102,18 +114,25 @@
             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(toModelWidgetAction(modelWidget, actionElement));
+        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;
+        if (actions == null)
+            return;
         for (ModelWidgetAction action : actions) {
             if (Debug.verboseOn())
                 Debug.logVerbose("Running action " + action.getClass().getName(), module);
@@ -125,193 +144,287 @@
         }
     }
 
-    public static class SetField extends ModelWidgetAction {
-        protected FlexibleMapAccessor<Object> field;
-        protected FlexibleMapAccessor<Object> fromField;
-        protected FlexibleStringExpander valueExdr;
-        protected FlexibleStringExpander defaultExdr;
-        protected FlexibleStringExpander globalExdr;
-        protected String type;
-        protected String toScope;
-        protected String fromScope;
+    private final ModelWidget modelWidget;
 
-        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");
-            }
-        }
+    protected ModelWidgetAction() {
+        // FIXME: This should not be null.
+        this.modelWidget = null;
+    }
 
-        @SuppressWarnings("rawtypes")
-        @Override
-        public void runAction(Map<String, Object> context) {
-            String globalStr = this.globalExdr.expandString(context);
-            // default to false
-            boolean global = "true".equals(globalStr);
+    protected ModelWidgetAction(ModelWidget modelWidget, Element actionElement) {
+        this.modelWidget = modelWidget;
+        if (Debug.verboseOn())
+            Debug.logVerbose("Reading widget action with name: " + actionElement.getNodeName(), module);
+    }
 
-            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);
-                }
-            }
+    public abstract void accept(ModelActionVisitor visitor);
 
-            // If newValue is still empty, use the default value
-            if (ObjectType.isEmpty(newValue) && !this.defaultExdr.isEmpty()) {
-                newValue = this.defaultExdr.expand(context);
-            }
+    /**
+     * 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;
+    }
 
-            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);
-                    }
-                }
-            }
+    /**
+     * Executes this action.
+     * 
+     * @param context
+     * @throws GeneralException
+     */
+    public abstract void runAction(Map<String, Object> context) throws GeneralException;
 
-            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);
-                }
-            }
+    /**
+     * Models the &lt;entity-and&gt; element.
+     * 
+     * @see <code>widget-screen.xsd</code>
+     */
+    public static class EntityAnd extends ModelWidgetAction {
+        private final ByAndFinder finder;
 
-            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 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;
+        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 {
-        protected FlexibleStringExpander resourceExdr;
-        protected FlexibleMapAccessor<ResourceBundleMapWrapper> mapNameAcsr;
-        protected FlexibleStringExpander globalExdr;
+        private final FlexibleStringExpander globalExdr;
+        private final FlexibleMapAccessor<ResourceBundleMapWrapper> mapNameAcsr;
+        private final FlexibleStringExpander resourceExdr;
 
         public PropertyMap(ModelWidget modelWidget, Element setElement) {
-            super (modelWidget, 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));
@@ -323,7 +436,6 @@
                     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) {
@@ -344,25 +456,24 @@
                 }
             }
         }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
     }
 
+    /**
+     * Models the &lt;property-to-field&gt; element.
+     * 
+     * @see <code>widget-common.xsd</code>
+     */
     public static class PropertyToField extends ModelWidgetAction {
-
-        protected FlexibleStringExpander resourceExdr;
-        protected FlexibleStringExpander propertyExdr;
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-        protected FlexibleStringExpander defaultExdr;
-        protected boolean noLocale;
-        protected FlexibleMapAccessor<List<? extends Object>> argListAcsr;
-        protected FlexibleStringExpander globalExdr;
+        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);
+            super(modelWidget, setElement);
             this.resourceExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
             this.propertyExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("property"));
             this.fieldAcsr = FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
@@ -373,15 +484,18 @@
         }
 
         @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));
@@ -391,12 +505,10 @@
             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)) {
@@ -405,23 +517,28 @@
             }
             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);
         }
-    }
-
-    public static class Script extends ModelWidgetAction {
-        protected String location;
-        protected 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 runAction(Map<String, Object> context) throws GeneralException {
@@ -440,26 +557,34 @@
                 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 static class Service extends ModelWidgetAction {
-        protected FlexibleStringExpander serviceNameExdr;
-        protected FlexibleMapAccessor<Map<String, Object>> resultMapNameAcsr;
-        protected FlexibleStringExpander autoFieldMapExdr;
-        protected Map<FlexibleMapAccessor<Object>, Object> fieldMap;
-
-        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"));
-            if (this.resultMapNameAcsr.isEmpty()) this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map-name"));
-            this.autoFieldMapExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
-            this.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement);
+        public FlexibleStringExpander getServiceNameExdr() {
+            return this.serviceNameExdr;
         }
 
         @Override
@@ -468,9 +593,7 @@
             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)) {
@@ -487,22 +610,20 @@
                     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);
+                        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");
+                    String queryString = (String) result.get("queryString");
                     context.put("queryString", queryString);
                     context.put("queryStringMap", result.get("queryStringMap"));
                     if (UtilValidate.isNotEmpty(queryString)) {
@@ -522,211 +643,182 @@
                 throw new IllegalArgumentException(errMsg);
             }
         }
-
-        public FlexibleStringExpander getServiceNameExdr() {
-            return this.serviceNameExdr;
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
     }
 
-    public static class EntityOne extends ModelWidgetAction {
-        protected PrimaryKeyFinder finder;
+    /**
+     * 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 EntityOne(ModelWidget modelWidget, Element entityOneElement) {
-            super (modelWidget, entityOneElement);
-            finder = new PrimaryKeyFinder(entityOneElement);
-        }
-
-        @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);
+        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");
             }
         }
 
-        public PrimaryKeyFinder getFinder() {
-            return this.finder;
-        }
-
         @Override
         public void accept(ModelActionVisitor visitor) {
             visitor.visit(this);
         }
-    }
 
-    public static class EntityAnd extends ModelWidgetAction {
-        protected ByAndFinder finder;
-
-        public EntityAnd(ModelWidget modelWidget, Element entityAndElement) {
-            super (modelWidget, entityAndElement);
-            finder = new ByAndFinder(entityAndElement);
+        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) {
-            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);
+            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);
+                }
             }
-        }
-
-        public ByAndFinder getFinder() {
-            return this.finder;
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-    }
-
-    public static class EntityCondition extends ModelWidgetAction {
-        ByConditionFinder finder;
-
-        public EntityCondition(ModelWidget modelWidget, Element entityConditionElement) {
-            super (modelWidget, entityConditionElement);
-            finder = new ByConditionFinder(entityConditionElement);
-        }
-
-        @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);
+            // If newValue is still empty, use the default value
+            if (ObjectType.isEmpty(newValue) && !this.defaultExdr.isEmpty()) {
+                newValue = this.defaultExdr.expand(context);
             }
-        }
-
-        public ByConditionFinder getFinder() {
-            return this.finder;
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-    }
-
-    public static class GetRelatedOne extends ModelWidgetAction {
-        protected FlexibleMapAccessor<Object> valueNameAcsr;
-        protected FlexibleMapAccessor<Object> toValueNameAcsr;
-        protected String relationName;
-        protected boolean useCache;
-
-        public GetRelatedOne(ModelWidget modelWidget, Element getRelatedOneElement) {
-            super (modelWidget, getRelatedOneElement);
-            this.valueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-field"));
-            if (this.valueNameAcsr.isEmpty()) this.valueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-name"));
-            this.toValueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-field"));
-            if (this.toValueNameAcsr.isEmpty()) this.toValueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-name"));
-            this.relationName = getRelatedOneElement.getAttribute("relation-name");
-            this.useCache = "true".equals(getRelatedOneElement.getAttribute("use-cache"));
-        }
-
-        @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 (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 (!(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);
+            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);
+                }
             }
-            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);
+            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);
+                }
             }
-        }
-
-        public String getRelationName() {
-            return this.relationName;
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-    }
-
-    public static class GetRelated extends ModelWidgetAction {
-        protected FlexibleMapAccessor<Object> valueNameAcsr;
-        protected FlexibleMapAccessor<List<GenericValue>> listNameAcsr;
-        protected FlexibleMapAccessor<Map<String, Object>> mapAcsr;
-        protected FlexibleMapAccessor<List<String>> orderByListAcsr;
-        protected String relationName;
-        protected boolean useCache;
-
-        public GetRelated(ModelWidget modelWidget, Element getRelatedElement) {
-            super (modelWidget, getRelatedElement);
-            this.valueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-field"));
-            if (this.valueNameAcsr.isEmpty()) this.valueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-name"));
-            this.listNameAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list"));
-            if (this.listNameAcsr.isEmpty()) this.listNameAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list-name"));
-            this.relationName = getRelatedElement.getAttribute("relation-name");
-            this.mapAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map"));
-            if (this.mapAcsr.isEmpty()) this.mapAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map-name"));
-            this.orderByListAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list"));
-            if (this.orderByListAcsr.isEmpty()) this.orderByListAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list-name"));
-            this.useCache = "true".equals(getRelatedElement.getAttribute("use-cache"));
-        }
-
-        @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;
+            // 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);
             }
-            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 String getRelationName() {
-            return this.relationName;
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
         }
     }
 }
diff --git a/framework/widget/src/org/ofbiz/widget/ModelWidgetCondition.java b/framework/widget/src/org/ofbiz/widget/ModelWidgetCondition.java
new file mode 100644
index 0000000..56feb69
--- /dev/null
+++ b/framework/widget/src/org/ofbiz/widget/ModelWidgetCondition.java
@@ -0,0 +1,650 @@
+/*******************************************************************************

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ * http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.lang.reflect.Method;

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.LinkedList;

+import java.util.List;

+import java.util.Locale;

+import java.util.Map;

+import java.util.TimeZone;

+

+import org.apache.oro.text.regex.MalformedPatternException;

+import org.apache.oro.text.regex.Pattern;

+import org.apache.oro.text.regex.PatternMatcher;

+import org.apache.oro.text.regex.Perl5Matcher;

+import org.ofbiz.base.util.Debug;

+import org.ofbiz.base.util.GeneralException;

+import org.ofbiz.base.util.ObjectType;

+import org.ofbiz.base.util.PatternFactory;

+import org.ofbiz.base.util.UtilGenerics;

+import org.ofbiz.base.util.UtilValidate;

+import org.ofbiz.base.util.UtilXml;

+import org.ofbiz.base.util.collections.FlexibleMapAccessor;

+import org.ofbiz.base.util.string.FlexibleStringExpander;

+import org.ofbiz.entity.GenericValue;

+import org.ofbiz.entityext.permission.EntityPermissionChecker;

+import org.ofbiz.minilang.operation.BaseCompare;

+import org.ofbiz.security.Security;

+import org.ofbiz.service.DispatchContext;

+import org.ofbiz.service.GenericServiceException;

+import org.ofbiz.service.LocalDispatcher;

+import org.ofbiz.service.ModelService;

+import org.ofbiz.service.ServiceUtil;

+import org.w3c.dom.Element;

+

+/**

+ * Abstract base class for the condition models.

+ */

+@SuppressWarnings("serial")

+public abstract class ModelWidgetCondition 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 = ModelWidgetCondition.class.getName();

+    public static final ConditionFactory 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 boolean eval(Map<String, Object> context) {

+        return rootCondition.eval(context);

+    }

+

+    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));

+        }

+        return Collections.unmodifiableList(condList);

+    }

+

+    /**

+     * Models the &lt;and&gt; element.

+     * 

+     * @see <code>widget-common.xsd</code>

+     */

+    public static class And extends ModelWidgetCondition implements Condition {

+        private final List<Condition> subConditions;

+

+        private And(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {

+            super(factory, modelWidget, condElement);

+            this.subConditions = readSubConditions(factory, modelWidget, condElement);

+        }

+

+        @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) {

+                if (!subCondition.eval(context)) {

+                    return false;

+                }

+            }

+            return true;

+        }

+    }

+

+    public static interface Condition {

+        boolean eval(Map<String, Object> context);

+    }

+

+    /**

+     * A factory for <code>Condition</code> instances.

+     *

+     */

+    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() {

+            @Override

+            public boolean eval(Map<String, Object> context) {

+                return true;

+            }

+        };

+        public static final Condition FALSE = new Condition() {

+            @Override

+            public boolean eval(Map<String, Object> context) {

+                return false;

+            }

+        };

+

+        public Condition newInstance(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);

+            } else {

+                throw new IllegalArgumentException("Condition element not supported with name: " + conditionElement.getNodeName());

+            }

+        }

+    }

+

+    /**

+     * Models the &lt;if-compare&gt; element.

+     * 

+     * @see <code>widget-common.xsd</code>

+     */

+    public static class IfCompare extends ModelWidgetCondition implements Condition {

+        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) {

+            super(factory, modelWidget, condElement);

+            String fieldAcsr = condElement.getAttribute("field");

+            if (fieldAcsr.isEmpty())

+                fieldAcsr = condElement.getAttribute("field-name");

+            this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr);

+            this.valueExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("value"));

+            this.operator = condElement.getAttribute("operator");

+            this.type = condElement.getAttribute("type");

+            this.formatExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("format"));

+        }

+

+        @Override

+        public boolean eval(Map<String, Object> context) {

+            String value = this.valueExdr.expandString(context);

+            String format = this.formatExdr.expandString(context);

+            Object fieldVal = this.fieldAcsr.get(context);

+            // always use an empty string by default

+            if (fieldVal == null) {

+                fieldVal = "";

+            }

+            List<Object> messages = new LinkedList<Object>();

+            Boolean resultBool = BaseCompare.doRealCompare(fieldVal, value, operator, type, format, messages, null, null, true);

+            if (messages.size() > 0) {

+                messages.add(0, "Error with comparison in if-compare between field [" + fieldAcsr.toString() + "] with value ["

+                        + fieldVal + "] and value [" + value + "] with operator [" + operator + "] and type [" + type + "]: ");

+

+                StringBuilder fullString = new StringBuilder();

+                for (Object item : messages) {

+                    fullString.append(item.toString());

+                }

+                Debug.logWarning(fullString.toString(), module);

+                throw new IllegalArgumentException(fullString.toString());

+            }

+            return resultBool.booleanValue();

+        }

+    }

+

+    /**

+     * Models the &lt;if-compare-field&gt; element.

+     * 

+     * @see <code>widget-common.xsd</code>

+     */

+    public static class IfCompareField extends ModelWidgetCondition implements Condition {

+        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) {

+            super(factory, modelWidget, condElement);

+            String fieldAcsr = condElement.getAttribute("field");

+            if (fieldAcsr.isEmpty())

+                fieldAcsr = condElement.getAttribute("field-name");

+            this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr);

+            String toFieldAcsr = condElement.getAttribute("to-field");

+            if (toFieldAcsr.isEmpty())

+                toFieldAcsr = condElement.getAttribute("to-field-name");

+            this.toFieldAcsr = FlexibleMapAccessor.getInstance(toFieldAcsr);

+            this.operator = condElement.getAttribute("operator");

+            this.type = condElement.getAttribute("type");

+            this.formatExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("format"));

+        }

+

+        @Override

+        public boolean eval(Map<String, Object> context) {

+            String format = this.formatExdr.expandString(context);

+            Object fieldVal = this.fieldAcsr.get(context);

+            Object toFieldVal = this.toFieldAcsr.get(context);

+            // always use an empty string by default

+            if (fieldVal == null) {

+                fieldVal = "";

+            }

+            List<Object> messages = new LinkedList<Object>();

+            Boolean resultBool = BaseCompare.doRealCompare(fieldVal, toFieldVal, operator, type, format, messages, null, null,

+                    false);

+            if (messages.size() > 0) {

+                messages.add(0, "Error with comparison in if-compare-field between field [" + fieldAcsr.toString()

+                        + "] with value [" + fieldVal + "] and to-field [" + toFieldAcsr.toString() + "] with value ["

+                        + toFieldVal + "] with operator [" + operator + "] and type [" + type + "]: ");

+

+                StringBuilder fullString = new StringBuilder();

+                for (Object item : messages) {

+                    fullString.append(item.toString());

+                }

+                Debug.logWarning(fullString.toString(), module);

+                throw new IllegalArgumentException(fullString.toString());

+            }

+            return resultBool.booleanValue();

+        }

+    }

+

+    /**

+     * Models the &lt;if-empty&gt; element.

+     * 

+     * @see <code>widget-common.xsd</code>

+     */

+    public static class IfEmpty extends ModelWidgetCondition implements Condition {

+        private final FlexibleMapAccessor<Object> fieldAcsr;

+

+        private IfEmpty(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {

+            super(factory, modelWidget, condElement);

+            String fieldAcsr = condElement.getAttribute("field");

+            if (fieldAcsr.isEmpty())

+                fieldAcsr = condElement.getAttribute("field-name");

+            this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr);

+        }

+

+        @Override

+        public boolean eval(Map<String, Object> context) {

+            Object fieldVal = this.fieldAcsr.get(context);

+            return ObjectType.isEmpty(fieldVal);

+        }

+    }

+

+    /**

+     * Models the &lt;if-entity-permission&gt; element.

+     * 

+     * @see <code>widget-common.xsd</code>

+     */

+    public static class IfEntityPermission extends ModelWidgetCondition implements Condition {

+        private final EntityPermissionChecker permissionChecker;

+

+        private IfEntityPermission(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {

+            super(factory, modelWidget, condElement);

+            this.permissionChecker = new EntityPermissionChecker(condElement);

+        }

+

+        @Override

+        public boolean eval(Map<String, Object> context) {

+            return permissionChecker.runPermissionCheck(context);

+        }

+    }

+

+    /**

+     * Models the &lt;if-has-permission&gt; element.

+     * 

+     * @see <code>widget-common.xsd</code>

+     */

+    public static class IfHasPermission extends ModelWidgetCondition implements Condition {

+        private final FlexibleStringExpander actionExdr;

+        private final FlexibleStringExpander permissionExdr;

+

+        private IfHasPermission(ConditionFactory 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 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");

+            if (userLogin != null) {

+                String permission = permissionExdr.expandString(context);

+                String action = actionExdr.expandString(context);

+                Security security = (Security) context.get("security");

+                if (UtilValidate.isNotEmpty(action)) {

+                    // run hasEntityPermission

+                    if (security.hasEntityPermission(permission, action, userLogin)) {

+                        return true;

+                    }

+                } else {

+                    // run hasPermission

+                    if (security.hasPermission(permission, userLogin)) {

+                        return true;

+                    }

+                }

+            }

+            return false;

+        }

+    }

+

+    /**

+     * Models the &lt;if-regexp&gt; element.

+     * 

+     * @see <code>widget-common.xsd</code>

+     */

+    public static class IfRegexp extends ModelWidgetCondition implements Condition {

+        private final FlexibleStringExpander exprExdr;

+        private final FlexibleMapAccessor<Object> fieldAcsr;

+

+        private IfRegexp(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {

+            super(factory, modelWidget, condElement);

+            String fieldAcsr = condElement.getAttribute("field");

+            if (fieldAcsr.isEmpty())

+                fieldAcsr = condElement.getAttribute("field-name");

+            this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr);

+            this.exprExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("expr"));

+        }

+

+        @Override

+        public boolean eval(Map<String, Object> context) {

+            Object fieldVal = this.fieldAcsr.get(context);

+            String expr = this.exprExdr.expandString(context);

+            Pattern pattern;

+            try {

+                pattern = PatternFactory.createOrGetPerl5CompiledPattern(expr, true);

+            } catch (MalformedPatternException e) {

+                String errMsg = "Error in evaluation in if-regexp in screen: " + e.toString();

+                Debug.logError(e, errMsg, module);

+                throw new IllegalArgumentException(errMsg);

+            }

+            String fieldString = null;

+            try {

+                fieldString = (String) ObjectType.simpleTypeConvert(fieldVal, "String", null, (TimeZone) context.get("timeZone"),

+                        (Locale) context.get("locale"), true);

+            } catch (GeneralException e) {

+                Debug.logError(e, "Could not convert object to String, using empty String", module);

+            }

+            // always use an empty string by default

+            if (fieldString == null)

+                fieldString = "";

+            PatternMatcher matcher = new Perl5Matcher();

+            return matcher.matches(fieldString, pattern);

+        }

+    }

+

+    /**

+     * Models the &lt;if-service-permission&gt; element.

+     * 

+     * @see <code>widget-common.xsd</code>

+     */

+    public static class IfServicePermission extends ModelWidgetCondition implements Condition {

+        private final FlexibleStringExpander actionExdr;

+        private final FlexibleStringExpander ctxMapExdr;

+        private final FlexibleStringExpander resExdr;

+        private final FlexibleStringExpander serviceExdr;

+

+        private IfServicePermission(ConditionFactory 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"));

+            this.ctxMapExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("context-map"));

+            this.resExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("resource-description"));

+        }

+

+        @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");

+            if (userLogin != null) {

+                String serviceName = serviceExdr.expandString(context);

+                String mainAction = actionExdr.expandString(context);

+                String contextMap = ctxMapExdr.expandString(context);

+                String resource = resExdr.expandString(context);

+                if (UtilValidate.isEmpty(resource)) {

+                    resource = serviceName;

+                }

+                if (UtilValidate.isEmpty(serviceName)) {

+                    Debug.logWarning("No permission service-name specified!", module);

+                    return false;

+                }

+                Map<String, Object> serviceContext = UtilGenerics.toMap(context.get(contextMap));

+                if (serviceContext != null) {

+                    // copy the required internal fields

+                    serviceContext.put("userLogin", context.get("userLogin"));

+                    serviceContext.put("locale", context.get("locale"));

+                } else {

+                    serviceContext = context;

+                }

+                // get the service engine objects

+                LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");

+                DispatchContext dctx = dispatcher.getDispatchContext();

+                // get the service

+                ModelService permService;

+                try {

+                    permService = dctx.getModelService(serviceName);

+                } catch (GenericServiceException e) {

+                    Debug.logError(e, module);

+                    return false;

+                }

+                if (permService != null) {

+                    // build the context

+                    Map<String, Object> svcCtx = permService.makeValid(serviceContext, ModelService.IN_PARAM);

+                    svcCtx.put("resourceDescription", resource);

+                    if (UtilValidate.isNotEmpty(mainAction)) {

+                        svcCtx.put("mainAction", mainAction);

+                    }

+                    // invoke the service

+                    Map<String, Object> resp;

+                    try {

+                        resp = dispatcher.runSync(permService.name, svcCtx, 300, true);

+                    } catch (GenericServiceException e) {

+                        Debug.logError(e, module);

+                        return false;

+                    }

+                    if (ServiceUtil.isError(resp) || ServiceUtil.isFailure(resp)) {

+                        Debug.logError(ServiceUtil.getErrorMessage(resp), module);

+                        return false;

+                    }

+                    Boolean hasPermission = (Boolean) resp.get("hasPermission");

+                    if (hasPermission != null) {

+                        return hasPermission.booleanValue();

+                    }

+                }

+            }

+            return false;

+        }

+    }

+

+    /**

+     * Models the &lt;if-validate-method&gt; element.

+     * 

+     * @see <code>widget-common.xsd</code>

+     */

+    public static class IfValidateMethod extends ModelWidgetCondition implements Condition {

+        private final FlexibleStringExpander classExdr;

+        private final FlexibleMapAccessor<Object> fieldAcsr;

+        private final FlexibleStringExpander methodExdr;

+

+        private IfValidateMethod(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {

+            super(factory, modelWidget, condElement);

+            String fieldAcsr = condElement.getAttribute("field");

+            if (fieldAcsr.isEmpty())

+                fieldAcsr = condElement.getAttribute("field-name");

+            this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr);

+            this.methodExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("method"));

+            this.classExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("class"));

+        }

+

+        @Override

+        public boolean eval(Map<String, Object> context) {

+            String methodName = this.methodExdr.expandString(context);

+            String className = this.classExdr.expandString(context);

+            Object fieldVal = this.fieldAcsr.get(context);

+            String fieldString = null;

+            if (fieldVal != null) {

+                try {

+                    fieldString = (String) ObjectType.simpleTypeConvert(fieldVal, "String", null,

+                            (TimeZone) context.get("timeZone"), (Locale) context.get("locale"), true);

+                } catch (GeneralException e) {

+                    Debug.logError(e, "Could not convert object to String, using empty String", module);

+                }

+            }

+            // always use an empty string by default

+            if (fieldString == null)

+                fieldString = "";

+            Class<?>[] paramTypes = new Class[] { String.class };

+            Object[] params = new Object[] { fieldString };

+            Class<?> valClass;

+            try {

+                valClass = ObjectType.loadClass(className);

+            } catch (ClassNotFoundException cnfe) {

+                Debug.logError("Could not find validation class: " + className, module);

+                return false;

+            }

+            Method valMethod;

+            try {

+                valMethod = valClass.getMethod(methodName, paramTypes);

+            } catch (NoSuchMethodException cnfe) {

+                Debug.logError("Could not find validation method: " + methodName + " of class " + className, module);

+                return false;

+            }

+            Boolean resultBool = Boolean.FALSE;

+            try {

+                resultBool = (Boolean) valMethod.invoke(null, params);

+            } catch (Exception e) {

+                Debug.logError(e, "Error in IfValidationMethod " + methodName + " of class " + className

+                        + ", defaulting to false ", module);

+            }

+            return resultBool.booleanValue();

+        }

+    }

+

+    /**

+     * Models the &lt;not&gt; element.

+     * 

+     * @see <code>widget-common.xsd</code>

+     */

+    public static class Not extends ModelWidgetCondition implements Condition {

+        private final Condition subCondition;

+

+        private Not(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {

+            super(factory, modelWidget, condElement);

+            Element firstChildElement = UtilXml.firstChildElement(condElement);

+            this.subCondition = factory.newInstance(modelWidget, firstChildElement);

+        }

+

+        @Override

+        public boolean eval(Map<String, Object> context) {

+            return !this.subCondition.eval(context);

+        }

+    }

+

+    /**

+     * Models the &lt;or&gt; element.

+     * 

+     * @see <code>widget-common.xsd</code>

+     */

+    public static class Or extends ModelWidgetCondition implements Condition {

+        private final List<Condition> subConditions;

+

+        private Or(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {

+            super(factory, modelWidget, condElement);

+            this.subConditions = readSubConditions(factory, modelWidget, condElement);

+        }

+

+        @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) {

+                if (subCondition.eval(context)) {

+                    return true;

+                }

+            }

+            return false;

+        }

+    }

+

+    /**

+     * Models the &lt;xor&gt; element.

+     * 

+     * @see <code>widget-common.xsd</code>

+     */

+    public static class Xor extends ModelWidgetCondition implements Condition {

+        private final List<Condition> subConditions;

+

+        private Xor(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {

+            super(factory, modelWidget, condElement);

+            this.subConditions = readSubConditions(factory, modelWidget, condElement);

+        }

+

+        @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) {

+                if (subCondition.eval(context)) {

+                    if (foundOneTrue) {

+                        // now found two true, so return false

+                        return false;

+                    } else {

+                        foundOneTrue = true;

+                    }

+                }

+            }

+            return foundOneTrue;

+        }

+    }

+}

diff --git a/framework/widget/src/org/ofbiz/widget/PortalPageWorker.java b/framework/widget/src/org/ofbiz/widget/PortalPageWorker.java
index 9eae8bb..5061208 100644
--- a/framework/widget/src/org/ofbiz/widget/PortalPageWorker.java
+++ b/framework/widget/src/org/ofbiz/widget/PortalPageWorker.java
@@ -32,6 +32,7 @@
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.condition.EntityCondition;
 import org.ofbiz.entity.condition.EntityOperator;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.entity.util.EntityUtil;
 import org.ofbiz.security.Security;
 
@@ -67,17 +68,16 @@
                                 EntityCondition.makeCondition("parentPortalPageId", EntityOperator.EQUALS, parentPortalPageId)),
                                 EntityOperator.OR)),
                         EntityOperator.AND);
-                portalPages = delegator.findList("PortalPage", cond, null, null, null, false);
+                portalPages = EntityQuery.use(delegator).from("PortalPage").where(cond).queryList();
                 List<GenericValue> userPortalPages = new ArrayList<GenericValue>();
                 if (UtilValidate.isNotEmpty(context.get("userLogin"))) { // check if a user is logged in
                     String userLoginId = ((GenericValue)context.get("userLogin")).getString("userLoginId");
                     // replace with private pages
                     for (GenericValue portalPage : portalPages) {
-                        cond = EntityCondition.makeCondition(UtilMisc.toList(
-                                EntityCondition.makeCondition("ownerUserLoginId", EntityOperator.EQUALS, userLoginId),
-                                EntityCondition.makeCondition("originalPortalPageId", EntityOperator.EQUALS, portalPage.getString("portalPageId"))),
-                                EntityOperator.AND);
-                        List <GenericValue> privatePortalPages = delegator.findList("PortalPage", cond, null, null, null, false);
+                        List<GenericValue> privatePortalPages = EntityQuery.use(delegator)
+                                                                           .from("PortalPage")
+                                                                           .where("ownerUserLoginId", userLoginId, "originalPortalPageId", portalPage.getString("portalPageId"))
+                                                                           .queryList();
                         if (UtilValidate.isNotEmpty(privatePortalPages)) {
                             userPortalPages.add(privatePortalPages.get(0));
                         } else {
@@ -85,12 +85,10 @@
                         }
                     }
                     // add any other created private pages
-                    cond = EntityCondition.makeCondition(UtilMisc.toList(
-                            EntityCondition.makeCondition("ownerUserLoginId", EntityOperator.EQUALS, userLoginId),
-                            EntityCondition.makeCondition("originalPortalPageId", EntityOperator.EQUALS, null),
-                            EntityCondition.makeCondition("parentPortalPageId", EntityOperator.EQUALS, parentPortalPageId)),
-                            EntityOperator.AND);
-                    userPortalPages.addAll(delegator.findList("PortalPage", cond, null, null, null, false));
+                    userPortalPages.addAll(EntityQuery.use(delegator)
+                                                      .from("PortalPage")
+                                                      .where("ownerUserLoginId", userLoginId, "originalPortalPageId", null, "parentPortalPageId", parentPortalPageId)
+                                                      .queryList());
                 }
                 portalPages = EntityUtil.orderBy(userPortalPages, UtilMisc.toList("sequenceNum"));
             } catch (GenericEntityException e) {
@@ -123,7 +121,7 @@
                         EntityCondition.makeCondition("ownerUserLoginId", EntityOperator.EQUALS, userLoginId)),
                         EntityOperator.OR)),
                     EntityOperator.AND);
-                List <GenericValue> portalPages = delegator.findList("PortalPage", cond, null, null, null, false);
+                List <GenericValue> portalPages = EntityQuery.use(delegator).from("PortalPage").where(cond).queryList();
                 if (UtilValidate.isNotEmpty(portalPages)) {
                     portalPage = EntityUtil.getFirst(portalPages);
                 }
@@ -133,7 +131,7 @@
                         EntityCondition.makeCondition("originalPortalPageId", EntityOperator.EQUALS, portalPageId),
                         EntityCondition.makeCondition("ownerUserLoginId", EntityOperator.EQUALS, userLoginId)),
                         EntityOperator.AND);
-                List <GenericValue> privateDerivedPortalPages = delegator.findList("PortalPage", cond, null, null, null, false);
+                List <GenericValue> privateDerivedPortalPages = EntityQuery.use(delegator).from("PortalPage").where(cond).queryList();
                 if (UtilValidate.isNotEmpty(privateDerivedPortalPages)) {
                     portalPage = EntityUtil.getFirst(privateDerivedPortalPages);
                 }
@@ -160,8 +158,7 @@
                 Boolean hasPortalAdminPermission = security.hasPermission("PORTALPAGE_ADMIN", userLogin);
                 try {
                     Delegator delegator = WidgetWorker.getDelegator(context);
-                    GenericValue portalPage = delegator.findOne("PortalPage", UtilMisc.toMap("portalPageId", portalPageId),false);
-
+                    GenericValue portalPage = EntityQuery.use(delegator).from("PortalPage").where("portalPageId", portalPageId).queryOne();
                     if (UtilValidate.isNotEmpty(portalPage)) {
                         String ownerUserLoginId = (String) portalPage.get("ownerUserLoginId");
                         // Users with PORTALPAGE_ADMIN permission can configure every Portal Page
diff --git a/framework/widget/src/org/ofbiz/widget/WidgetWorker.java b/framework/widget/src/org/ofbiz/widget/WidgetWorker.java
index 7cf7352..c4a7fc3 100644
--- a/framework/widget/src/org/ofbiz/widget/WidgetWorker.java
+++ b/framework/widget/src/org/ofbiz/widget/WidgetWorker.java
@@ -36,7 +36,7 @@
 import javax.servlet.http.HttpServletResponse;
 
 import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
 import org.ofbiz.base.util.UtilDateTime;
 import org.ofbiz.base.util.UtilGenerics;
 import org.ofbiz.base.util.UtilHttp;
@@ -71,7 +71,7 @@
         // We may get an encoded request like: &#47;projectmgr&#47;control&#47;EditTaskContents&#63;workEffortId&#61;10003
         // Try to reducing a possibly encoded string down to its simplest form: /projectmgr/control/EditTaskContents?workEffortId=10003
         // This step make sure the following appending externalLoginKey operation to work correctly
-        localRequestName = StringUtil.defaultWebEncoder.canonicalize(localRequestName);
+        localRequestName = UtilCodec.canonicalize(localRequestName);
         Appendable localWriter = new StringWriter();
 
         if ("intra-app".equals(targetType)) {
@@ -143,7 +143,7 @@
                 }
                 externalWriter.append(parameter.getKey());
                 externalWriter.append('=');
-                StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
+                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
                 if (simpleEncoder != null && parameterValue != null) {
                     externalWriter.append(simpleEncoder.encode(URLEncoder.encode(parameterValue, Charset.forName("UTF-8").displayName())));
                 } else {
@@ -300,7 +300,7 @@
                 writer.append("<input name=\"");
                 writer.append(parameter.getKey());
                 writer.append("\" value=\"");
-                writer.append(StringUtil.htmlEncoder.encode(parameter.getValue()));
+                writer.append(UtilCodec.getEncoder("html").encode(parameter.getValue()));
                 writer.append("\" type=\"hidden\"/>");
             }
         }
@@ -330,6 +330,11 @@
         }
     }
 
+    /**
+     * Models the &lt;parameter&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
     public static class Parameter {
         protected String name;
         protected FlexibleStringExpander value;
diff --git a/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java b/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java
index 5a58023..4eb506d 100644
--- a/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java
+++ b/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java
@@ -265,16 +265,6 @@
     }

 

     @Override

-    public void visit(ModelFormAction.EntityAnd entityAnd) {

-        infoContext.addEntityName(entityAnd.getFinder().getEntityName());

-    }

-

-    @Override

-    public void visit(ModelFormAction.EntityCondition entityCondition) {

-        infoContext.addEntityName(entityCondition.getFinder().getEntityName());

-    }

-

-    @Override

     public void visit(ModelFormAction.Service service) {

         infoContext.addServiceName(service.getServiceName());

         // TODO: Look for entityName in performFind service call

diff --git a/framework/widget/src/org/ofbiz/widget/form/FieldInfo.java b/framework/widget/src/org/ofbiz/widget/form/FieldInfo.java
index 85d48d9..1231fee 100644
--- a/framework/widget/src/org/ofbiz/widget/form/FieldInfo.java
+++ b/framework/widget/src/org/ofbiz/widget/form/FieldInfo.java
@@ -31,7 +31,6 @@
  */

 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;

diff --git a/framework/widget/src/org/ofbiz/widget/form/FormRenderer.java b/framework/widget/src/org/ofbiz/widget/form/FormRenderer.java
index 3be05b5..e87d601 100644
--- a/framework/widget/src/org/ofbiz/widget/form/FormRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/form/FormRenderer.java
@@ -206,10 +206,6 @@
      *   itemIndex (Integer, for lists only, otherwise null), bshInterpreter,

      *   formName (String, optional alternate name for form, defaults to the

      *   value of the name attribute)

-     * @param formStringRenderer An implementation of the FormStringRenderer

-     *   interface that is responsible for the actual text generation for

-     *   different form elements; implementing your own makes it possible to

-     *   use the same form definitions for many types of form UIs

      */

     public void render(Appendable writer, Map<String, Object> context)

             throws Exception {

@@ -237,13 +233,7 @@
                 positions = curPos;

             }

             FieldInfo currentFieldInfo = modelFormField.getFieldInfo();

-            if (currentFieldInfo != null) {

-                ModelFormField fieldInfoFormField = currentFieldInfo.getModelFormField();

-                if (fieldInfoFormField != null) {

-                    // FIXME

-                    //fieldInfoFormField.setModelForm(this);

-                }

-            } else {

+            if (currentFieldInfo == null) {

                 throw new IllegalArgumentException(

                         "Error rendering form, a field has no FieldInfo, ie no sub-element for the type of field for field named: "

                                 + modelFormField.getName());

diff --git a/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java b/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java
index 73c735e..3ef4e12 100644
--- a/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java
@@ -40,6 +40,7 @@
 
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
 import org.ofbiz.base.util.UtilFormatOut;
 import org.ofbiz.base.util.UtilGenerics;
 import org.ofbiz.base.util.UtilHttp;
@@ -92,7 +93,7 @@
     public static final String module = MacroFormRenderer.class.getName();
     private final Template macroLibrary;
     private final WeakHashMap<Appendable, Environment> environments = new WeakHashMap<Appendable, Environment>();
-    private final StringUtil.SimpleEncoder internalEncoder;
+    private final UtilCodec.SimpleEncoder internalEncoder;
     private final RequestHandler rh;
     private final HttpServletRequest request;
     private final HttpServletResponse response;
@@ -107,7 +108,7 @@
         ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
         this.rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
         this.javaScriptEnabled = UtilHttp.isJavaScriptEnabled(request);
-        internalEncoder = StringUtil.getEncoder("string");
+        internalEncoder = UtilCodec.getEncoder("string");
     }
 
     @Deprecated
@@ -157,7 +158,7 @@
         if (UtilValidate.isEmpty(value)) {
             return value;
         }
-        StringUtil.SimpleEncoder encoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
+        UtilCodec.SimpleEncoder encoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
         if (modelFormField.getEncodeOutput() && encoder != null) {
             value = encoder.encode(value);
         } else {
@@ -355,7 +356,7 @@
             mask = textField.getMask();
         }
         String ajaxUrl = createAjaxParamsFromUpdateAreas(updateAreas, "", context);
-        boolean disabled = textField.disabled;
+        boolean disabled = textField.getDisabled();
         StringWriter sr = new StringWriter();
         sr.append("<@renderTextField ");
         sr.append("name=\"");
@@ -541,17 +542,21 @@
                 localizedInputTitle = uiLabelMap.get("CommonFormatDateTime");
             }
         }
-        String contextValue = null;
-        // If time-dropdown deactivate encodingOutput for found hour and minutes
+        /*
+         * FIXME: Using a builder here is a hack. Replace the builder with appropriate code.
+         */
+        ModelFormFieldBuilder builder = new ModelFormFieldBuilder(modelFormField);
         boolean memEncodeOutput = modelFormField.getEncodeOutput();
         if (useTimeDropDown)
-            // FIXME: This is not thread-safe! Never modify a model's state!
-            modelFormField.setEncodeOutput(false);
+            // If time-dropdown deactivate encodingOutput for found hour and minutes
+            // FIXME: Encoding should be controlled by the renderer, not by the model.
+            builder.setEncodeOutput(false);
         // FIXME: modelFormField.getEntry ignores shortDateInput when converting Date objects to Strings.
-        // Object type conversion should be done by the renderer, not by the model.
-        contextValue = modelFormField.getEntry(context, dateTimeField.getDefaultValue(context));
-        if (useTimeDropDown)
-            modelFormField.setEncodeOutput(memEncodeOutput);
+        if (useTimeDropDown) {
+            builder.setEncodeOutput(memEncodeOutput);
+        }
+        modelFormField = builder.build();
+        String contextValue = modelFormField.getEntry(context, dateTimeField.getDefaultValue(context));
         String value = contextValue;
         if (UtilValidate.isNotEmpty(value)) {
             if (value.length() > maxlength) {
@@ -2024,7 +2029,7 @@
         }
         String event = modelFormField.getEvent();
         String action = modelFormField.getAction(context);
-        boolean readonly = lookupField.readonly;
+        boolean readonly = lookupField.getReadonly();
         // add lookup pop-up button
         String descriptionFieldName = lookupField.getDescriptionFieldName();
         ModelForm modelForm = modelFormField.getModelForm();
@@ -2937,9 +2942,9 @@
         String encodedDescription = encode(description, modelFormField, context);
         // get the parameterized pagination index and size fields
         int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
-        String viewIndexField = modelFormField.modelForm.getMultiPaginateIndexField(context);
-        String viewSizeField = modelFormField.modelForm.getMultiPaginateSizeField(context);
-        ModelForm modelForm = modelFormField.modelForm;
+        ModelForm modelForm = modelFormField.getModelForm();
+        String viewIndexField = modelForm.getMultiPaginateIndexField(context);
+        String viewSizeField = modelForm.getMultiPaginateSizeField(context);
         int viewIndex = Paginator.getViewIndex(modelForm, context);
         int viewSize = Paginator.getViewSize(modelForm, context);
         if (viewIndexField.equals("viewIndex" + "_" + paginatorNumber)) {
@@ -2951,7 +2956,7 @@
         if ("hidden-form".equals(realLinkType)) {
             parameterMap.put(viewIndexField, Integer.toString(viewIndex));
             parameterMap.put(viewSizeField, Integer.toString(viewSize));
-            if (modelFormField != null && "multi".equals(modelFormField.getModelForm().getType())) {
+            if (modelFormField != null && "multi".equals(modelForm.getType())) {
                 WidgetWorker.makeHiddenFormLinkAnchor(writer, linkStyle, encodedDescription, confirmation, modelFormField, request, response, context);
                 // this is a bit trickier, since we can't do a nested form we'll have to put the link to submit the form in place, but put the actual form def elsewhere, ie after the big form is closed
                 Map<String, Object> wholeFormContext = UtilGenerics.checkMap(context.get("wholeFormContext"));
@@ -3083,7 +3088,7 @@
             parameters.append(parameter.getName());
             parameters.append("'");
             parameters.append(",'value':'");
-            parameters.append(StringUtil.htmlEncoder.encode(parameter.getValue(context)));
+            parameters.append(UtilCodec.getEncoder("html").encode(parameter.getValue(context)));
             parameters.append("'}");
         }
         parameters.append("]");
diff --git a/framework/widget/src/org/ofbiz/widget/form/ModelForm.java b/framework/widget/src/org/ofbiz/widget/form/ModelForm.java
index 3b0709e..eb9421c 100644
--- a/framework/widget/src/org/ofbiz/widget/form/ModelForm.java
+++ b/framework/widget/src/org/ofbiz/widget/form/ModelForm.java
@@ -34,6 +34,7 @@
 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;
@@ -560,15 +561,15 @@
         if (parentModelForm != null) {
             useWhenFields.addAll(parentModelForm.useWhenFields);
         }
-        ArrayList<ModelFormField> fieldList = new ArrayList<ModelFormField>();
-        Map<String, ModelFormField> fieldMap = new HashMap<String, ModelFormField>();
+        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) {
-                ModelFormField childField = new ModelFormField(this);
-                childField.mergeOverrideModelFormField(parentChildField);
-                fieldList.add(childField);
-                fieldMap.put(childField.getName(), childField);
+                ModelFormFieldBuilder builder = new ModelFormFieldBuilder(parentChildField);
+                builder.setModelForm(this);
+                fieldBuilderList.add(builder);
+                fieldBuilderMap.put(builder.getName(), builder);
             }
         }
         Map<String, FieldGroupBase> fieldGroupMap = new HashMap<String, FieldGroupBase>();
@@ -731,7 +732,7 @@
             rowCountExdr = parentModelForm.rowCountExdr;
         }
         this.rowCountExdr = paginate;
-        ArrayList<ModelFormField> multiSubmitFields = new ArrayList<ModelFormField>();
+        ArrayList<ModelFormFieldBuilder> multiSubmitBuilders = new ArrayList<ModelFormFieldBuilder>();
         ArrayList<AutoFieldsService> autoFieldsServices = new ArrayList<AutoFieldsService>();
         ArrayList<AutoFieldsEntity> autoFieldsEntities = new ArrayList<AutoFieldsEntity>();
         ArrayList<SortField> sortOrderFields = new ArrayList<SortField>();
@@ -739,21 +740,21 @@
         for (Element autoFieldsServiceElement : UtilXml.childElementList(formElement, "auto-fields-service")) {
             AutoFieldsService autoFieldsService = new AutoFieldsService(autoFieldsServiceElement);
             autoFieldsServices.add(autoFieldsService);
-            addAutoFieldsFromService(autoFieldsService, entityModelReader, dispatchContext, useWhenFields, fieldList, fieldMap);
+            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, fieldList, fieldMap);
+            addAutoFieldsFromEntity(autoFieldsEntity, entityModelReader, useWhenFields, fieldBuilderList, fieldBuilderMap);
         }
         String thisType = this.getType();
         for (Element fieldElement : UtilXml.childElementList(formElement, "field")) {
-            ModelFormField modelFormField = new ModelFormField(fieldElement, this, entityModelReader, dispatchContext);
-            FieldInfo fieldInfo = modelFormField.getFieldInfo();
+            ModelFormFieldBuilder builder = new ModelFormFieldBuilder(fieldElement, this, entityModelReader, dispatchContext);
+            FieldInfo fieldInfo = builder.getFieldInfo();
             if (thisType.equals("multi") && fieldInfo instanceof ModelFormField.SubmitField) {
-                multiSubmitFields.add(modelFormField);
+                multiSubmitBuilders.add(builder);
             } else {
-                modelFormField = addUpdateField(modelFormField, useWhenFields, fieldList, fieldMap);
+                addUpdateField(builder, useWhenFields, fieldBuilderList, fieldBuilderMap);
             }
         }
         // get the sort-order
@@ -787,61 +788,67 @@
             }
         }
         if (sortOrderFields.size() > 0) {
-            ArrayList<ModelFormField> sortedFields = new ArrayList<ModelFormField>();
+            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<ModelFormField> fieldIter = fieldList.iterator();
+                Iterator<ModelFormFieldBuilder> fieldIter = fieldBuilderList.iterator();
                 while (fieldIter.hasNext()) {
-                    ModelFormField modelFormField = fieldIter.next();
-                    if (fieldName.equals(modelFormField.getName())) {
+                    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())) {
-                            modelFormField.setPosition(sortField.getPosition());
+                            builder.setPosition(sortField.getPosition());
                         }
                         fieldIter.remove();
-                        sortedFields.add(modelFormField);
+                        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(fieldList);
+            sortedFields.addAll(fieldBuilderList);
             // sortedFields all done, set fieldList
-            fieldList = sortedFields;
+            fieldBuilderList = sortedFields;
         }
         if (UtilValidate.isNotEmpty(lastOrderFields)) {
-            List<ModelFormField> lastedFields = new LinkedList<ModelFormField>();
+            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<ModelFormField> fieldIter = fieldList.iterator();
+                Iterator<ModelFormFieldBuilder> fieldIter = fieldBuilderList.iterator();
                 while (fieldIter.hasNext()) {
-                    ModelFormField modelFormField = fieldIter.next();
-                    if (fieldName.equals(modelFormField.getName())) {
+                    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(modelFormField);
+                        lastedFields.add(builder);
                     }
                 }
             }
             //now put all lastedFields at the field list end
-            fieldList.addAll(lastedFields);
+            fieldBuilderList.addAll(lastedFields);
         }
-        this.useWhenFields = Collections.unmodifiableSet(useWhenFields);
-        fieldList.trimToSize();
+        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);
-        multiSubmitFields.trimToSize();
-        this.multiSubmitFields = Collections.unmodifiableList(multiSubmitFields);
         autoFieldsServices.trimToSize();
         this.autoFieldsServices = Collections.unmodifiableList(autoFieldsServices);
         autoFieldsEntities.trimToSize();
@@ -866,7 +873,7 @@
     }
 
     private void addAutoFieldsFromEntity(AutoFieldsEntity autoFieldsEntity, ModelReader entityModelReader,
-            Set<String> useWhenFields, List<ModelFormField> fieldList, Map<String, ModelFormField> fieldMap) {
+            Set<String> useWhenFields, List<ModelFormFieldBuilder> fieldBuilderList, Map<String, ModelFormFieldBuilder> fieldBuilderMap) {
         // read entity def and auto-create fields
         ModelEntity modelEntity = null;
         try {
@@ -878,7 +885,6 @@
             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();
@@ -886,18 +892,23 @@
                 // don't ever auto-add these, should only be added if explicitly referenced
                 continue;
             }
-            ModelFormField modelFormField = this.addFieldFromEntityField(modelEntity, modelField,
-                    autoFieldsEntity.defaultFieldType, autoFieldsEntity.defaultPosition, useWhenFields, fieldList, fieldMap);
+            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)) {
-                modelFormField.setMapName(autoFieldsEntity.mapName);
+                builder.setMapName(autoFieldsEntity.mapName);
             }
+            addUpdateField(builder, useWhenFields, fieldBuilderList, fieldBuilderMap);
         }
     }
 
     private void addAutoFieldsFromService(AutoFieldsService autoFieldsService, ModelReader entityModelReader,
-            DispatchContext dispatchContext, Set<String> useWhenFields, List<ModelFormField> fieldList,
-            Map<String, ModelFormField> fieldMap) {
-
+            DispatchContext dispatchContext, Set<String> useWhenFields, List<ModelFormFieldBuilder> fieldBuilderList,
+            Map<String, ModelFormFieldBuilder> fieldBuilderMap) {
         // read service def and auto-create fields
         ModelService modelService = null;
         try {
@@ -908,11 +919,9 @@
             Debug.logError(e, errmsg, module);
             throw new IllegalArgumentException(errmsg);
         }
-
         for (ModelParam modelParam : modelService.getInModelParamList()) {
-            // skip auto params that the service engine populates...
-            if ("userLogin".equals(modelParam.name) || "locale".equals(modelParam.name) || "timeZone".equals(modelParam.name)
-                    || "login.username".equals(modelParam.name) || "login.password".equals(modelParam.name)) {
+            if (modelParam.internal) {
+                // skip auto params that the service engine populates...
                 continue;
             }
             if (modelParam.formDisplay) {
@@ -924,13 +933,17 @@
                             ModelField modelField = modelEntity.getField(modelParam.fieldName);
                             if (modelField != null) {
                                 // okay, populate using the entity field info...
-                                ModelFormField modelFormField = addFieldFromEntityField(modelEntity, modelField,
-                                        autoFieldsService.defaultFieldType, autoFieldsService.defaultPosition, useWhenFields,
-                                        fieldList, fieldMap);
+                                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)) {
-                                    modelFormField.setMapName(autoFieldsService.mapName);
+                                    builder.setMapName(autoFieldsService.mapName);
                                 }
-                                modelFormField.setRequiredField(!modelParam.optional);
+                                builder.setRequiredField(!modelParam.optional);
+                                addUpdateField(builder, useWhenFields, fieldBuilderList, fieldBuilderMap);
                                 // continue to skip creating based on service param
                                 continue;
                             }
@@ -939,79 +952,52 @@
                         Debug.logError(e, module);
                     }
                 }
-
-                ModelFormField modelFormField = this
-                        .addFieldFromServiceParam(modelService, modelParam, autoFieldsService.defaultFieldType,
-                                autoFieldsService.defaultPosition, useWhenFields, fieldList, fieldMap);
+                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)) {
-                    modelFormField.setMapName(autoFieldsService.mapName);
+                    builder.setMapName(autoFieldsService.mapName);
                 }
+                addUpdateField(builder, useWhenFields, fieldBuilderList, fieldBuilderMap);
             }
         }
     }
 
-    private ModelFormField addFieldFromEntityField(ModelEntity modelEntity, ModelField modelField, String defaultFieldType,
-            int defaultPosition, Set<String> useWhenFields, List<ModelFormField> fieldList, Map<String, ModelFormField> fieldMap) {
-        // create field def from entity field def
-        ModelFormField newFormField = new ModelFormField(this);
-        newFormField.setName(modelField.getName());
-        newFormField.setEntityName(modelEntity.getEntityName());
-        newFormField.setFieldName(modelField.getName());
-        newFormField.induceFieldInfoFromEntityField(modelEntity, modelField, defaultFieldType);
-        newFormField.setPosition(defaultPosition);
-        return this.addUpdateField(newFormField, useWhenFields, fieldList, fieldMap);
-    }
-
-    private ModelFormField addFieldFromServiceParam(ModelService modelService, ModelParam modelParam, String defaultFieldType,
-            int defaultPosition, Set<String> useWhenFields, List<ModelFormField> fieldList, Map<String, ModelFormField> fieldMap) {
-        // create field def from service param def
-        ModelFormField newFormField = new ModelFormField(this);
-        newFormField.setName(modelParam.name);
-        newFormField.setServiceName(modelService.name);
-        newFormField.setAttributeName(modelParam.name);
-        newFormField.setTitle(modelParam.formLabel);
-        newFormField.setRequiredField(!modelParam.optional);
-        newFormField.induceFieldInfoFromServiceParam(modelService, modelParam, defaultFieldType);
-        newFormField.setPosition(defaultPosition);
-        return this.addUpdateField(newFormField, useWhenFields, fieldList, fieldMap);
-    }
-
-    /**
-     * add/override modelFormField using the fieldList and fieldMap
-     *
-     * @return The same ModelFormField, or if merged with an existing field, the existing field.
-     */
-    private ModelFormField addUpdateField(ModelFormField modelFormField, Set<String> useWhenFields,
-            List<ModelFormField> fieldList, Map<String, ModelFormField> fieldMap) {
-        if (!modelFormField.isUseWhenEmpty() || useWhenFields.contains(modelFormField.getName())) {
-            useWhenFields.add(modelFormField.getName());
+    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 < fieldList.size(); i++) {
-                ModelFormField curField = fieldList.get(i);
-                if (curField.getName() != null && curField.getName().equals(modelFormField.getName())) {
-                    fieldList.add(i, modelFormField);
+            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) {
-                fieldList.add(modelFormField);
+                fieldBuilderList.add(builder);
             }
-            return modelFormField;
+            return;
         } else {
             // not a conditional field, see if a named field exists in Map
-            ModelFormField existingField = fieldMap.get(modelFormField.getName());
+            ModelFormFieldBuilder existingField = fieldBuilderMap.get(builder.getName());
             if (existingField != null) {
                 // does exist, update the field by doing a merge/override
-                existingField.mergeOverrideModelFormField(modelFormField);
-                return existingField;
+                existingField.mergeOverrideModelFormField(builder);
             } else {
                 // does not exist, add to List and Map
-                fieldList.add(modelFormField);
-                fieldMap.put(modelFormField.getName(), modelFormField);
-                return modelFormField;
+                fieldBuilderList.add(builder);
+                fieldBuilderMap.put(builder.getName(), builder);
             }
         }
     }
@@ -1518,7 +1504,6 @@
             Debug.logError(e, errmsg, module);
             throw new IllegalArgumentException(errmsg);
         }
-
         return styles;
     }
 
@@ -1531,11 +1516,10 @@
      */
     public String getTarget(Map<String, Object> context, String targetType) {
         Map<String, Object> expanderContext = context;
-        StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
+        UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
         if (simpleEncoder != null) {
-            expanderContext = StringUtil.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder);
+            expanderContext = UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder);
         }
-
         try {
             // use the same Interpreter (ie with the same context setup) for all evals
             Interpreter bsh = this.getBshInterpreter(context);
@@ -1561,7 +1545,6 @@
             Debug.logError(e, errmsg, module);
             throw new IllegalArgumentException(errmsg);
         }
-
         return target.expandString(expanderContext);
     }
 
diff --git a/framework/widget/src/org/ofbiz/widget/form/ModelFormAction.java b/framework/widget/src/org/ofbiz/widget/form/ModelFormAction.java
index fb7a328..303453b 100644
--- a/framework/widget/src/org/ofbiz/widget/form/ModelFormAction.java
+++ b/framework/widget/src/org/ofbiz/widget/form/ModelFormAction.java
@@ -27,14 +27,11 @@
 import java.util.regex.PatternSyntaxException;
 
 import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
 import org.ofbiz.base.util.UtilGenerics;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.base.util.UtilXml;
 import org.ofbiz.base.util.collections.FlexibleMapAccessor;
 import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.entity.finder.ByAndFinder;
-import org.ofbiz.entity.finder.ByConditionFinder;
 import org.ofbiz.entity.finder.EntityFinderUtil;
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.ModelService;
@@ -44,7 +41,7 @@
 import org.w3c.dom.Element;
 
 /**
- * Widget Library - Screen model class
+ * Abstract form action.
  */
 public abstract class ModelFormAction {
 
@@ -56,92 +53,166 @@
         for (Element actionElement : UtilXml.childElementList(parentElement)) {
             if ("service".equals(actionElement.getNodeName())) {
                 actions.add(new Service(modelForm, actionElement));
-            } else if ("entity-and".equals(actionElement.getNodeName())) {
-                actions.add(new EntityAnd(modelForm, actionElement));
-            } else if ("entity-condition".equals(actionElement.getNodeName())) {
-                actions.add(new EntityCondition(modelForm, actionElement));
+            } else if ("entity-and".equals(actionElement.getNodeName()) || "entity-condition".equals(actionElement.getNodeName())
+                    || "get-related".equals(actionElement.getNodeName())) {
+                if (!actionElement.hasAttribute("list")) {
+                    String listName = modelForm.getListName();
+                    if (UtilValidate.isEmpty(listName)) {
+                        listName = ModelForm.DEFAULT_FORM_RESULT_LIST_NAME;
+                    }
+                    actionElement.setAttribute("list", listName);
+                }
+                actions.add(ModelWidgetAction.newInstance(modelForm, actionElement));
             } else if ("call-parent-actions".equals(actionElement.getNodeName())) {
                 actions.add(new CallParentActions(modelForm, actionElement));
             } else {
-                actions.add(ModelWidgetAction.toModelWidgetAction(modelForm, actionElement));
+                actions.add(ModelWidgetAction.newInstance(modelForm, actionElement));
             }
         }
         return Collections.unmodifiableList(actions);
     }
 
+    /**
+     * Models the &lt;call-parent-actions&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    @SuppressWarnings("serial")
+    public static class CallParentActions extends ModelWidgetAction {
+        private final ActionsKind kind;;
+        private final ModelForm modelForm;
+
+        public CallParentActions(ModelForm modelForm, Element callParentActionsElement) {
+            super(modelForm, callParentActionsElement);
+            String parentName = callParentActionsElement.getParentNode().getNodeName();
+            if ("actions".equals(parentName)) {
+                kind = ActionsKind.ACTIONS;
+            } else if ("row-actions".equals(parentName)) {
+                kind = ActionsKind.ROW_ACTIONS;
+            } else {
+                throw new IllegalArgumentException("Action element not supported for call-parent-actions : " + parentName);
+            }
+            ModelForm parentModel = modelForm.getParentModelForm();
+            if (parentModel == null) {
+                throw new IllegalArgumentException("call-parent-actions can only be used with form extending another form");
+            }
+            this.modelForm = modelForm;
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            ModelForm parentModel = modelForm.getParentModelForm();
+            switch (kind) {
+            case ACTIONS:
+                parentModel.runFormActions(context);
+                break;
+            case ROW_ACTIONS:
+                ModelWidgetAction.runSubActions(parentModel.getRowActions(), context);
+                break;
+            }
+        }
+
+        protected static enum ActionsKind {
+            ACTIONS, ROW_ACTIONS
+        }
+    }
+
+    /**
+     * Models the &lt;service&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
     @SuppressWarnings("serial")
     public static class Service extends ModelWidgetAction {
-        protected FlexibleStringExpander serviceNameExdr;
-        protected FlexibleMapAccessor<Map<String, Object>> resultMapNameAcsr;
-        protected FlexibleStringExpander autoFieldMapExdr;
-        protected FlexibleStringExpander resultMapListNameExdr;
-        protected Map<FlexibleMapAccessor<Object>, Object> fieldMap;
-        protected boolean ignoreError = false;
+        private final FlexibleStringExpander autoFieldMapExdr;
+        private final Map<FlexibleMapAccessor<Object>, Object> fieldMap;
+        private final boolean ignoreError;
+        private final FlexibleStringExpander resultMapListNameExdr;
+        private final FlexibleMapAccessor<Map<String, Object>> resultMapNameAcsr;
+        private final FlexibleStringExpander serviceNameExdr;
 
         public Service(ModelForm modelForm, Element serviceElement) {
-            super (modelForm, serviceElement);
+            super(modelForm, serviceElement);
             this.serviceNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
             this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
-            if (this.resultMapNameAcsr.isEmpty()) this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map-name"));
             this.autoFieldMapExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
-            if (UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list")) && UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-name"))) {
-                if (UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-iterator")) && UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-iterator-name"))) {
+            FlexibleStringExpander resultMapListNameExdr = FlexibleStringExpander.getInstance("");
+            if (UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list"))
+                    && UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-name"))) {
+                if (UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-iterator"))
+                        && UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-iterator-name"))) {
                     String lstNm = modelForm.getListName();
                     if (UtilValidate.isEmpty(lstNm)) {
                         lstNm = ModelForm.DEFAULT_FORM_RESULT_LIST_NAME;
                     }
-                    this.resultMapListNameExdr = FlexibleStringExpander.getInstance(lstNm);
+                    resultMapListNameExdr = FlexibleStringExpander.getInstance(lstNm);
                 } else {
                     // this is deprecated, but support it for now anyway
-                    this.resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list-iterator"));
-                    if (this.resultMapListNameExdr.isEmpty()) this.resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list-iterator-name"));
+                    resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement
+                            .getAttribute("result-map-list-iterator"));
+                    if (resultMapListNameExdr.isEmpty())
+                        resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement
+                                .getAttribute("result-map-list-iterator-name"));
                 }
             } else {
-                this.resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list"));
-                if (this.resultMapListNameExdr.isEmpty()) this.resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list-name"));
+                resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list"));
+                if (resultMapListNameExdr.isEmpty())
+                    resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement
+                            .getAttribute("result-map-list-name"));
             }
-
+            this.resultMapListNameExdr = resultMapListNameExdr;
             this.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement);
             this.ignoreError = "true".equals(serviceElement.getAttribute("ignore-error"));
         }
 
         @Override
+        public void accept(ModelActionVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        public String getServiceName() {
+            return serviceNameExdr.getOriginal();
+        }
+
+        @Override
         public void runAction(Map<String, Object> context) {
             String serviceNameExpanded = this.serviceNameExdr.expandString(context);
             if (UtilValidate.isEmpty(serviceNameExpanded)) {
                 throw new IllegalArgumentException("Service name was empty, expanded from: " + this.serviceNameExdr.getOriginal());
             }
-
             String autoFieldMapString = this.autoFieldMapExdr.expandString(context);
             boolean autoFieldMapBool = !"false".equals(autoFieldMapString);
-
             try {
                 Map<String, Object> serviceContext = null;
                 if (autoFieldMapBool) {
-                    if (! "true".equals(autoFieldMapString)) {
+                    if (!"true".equals(autoFieldMapString)) {
                         Map<String, Object> autoFieldMap = UtilGenerics.checkMap(context.get(autoFieldMapString));
-                        serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext().makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, autoFieldMap);
+                        serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext()
+                                .makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, autoFieldMap);
                     } else {
-                        serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext().makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, context);
+                        serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext()
+                                .makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, context);
                     }
                 } else {
                     serviceContext = new HashMap<String, Object>();
                 }
-
                 if (this.fieldMap != null) {
                     EntityFinderUtil.expandFieldMapToContext(this.fieldMap, context, serviceContext);
                 }
-
                 Map<String, Object> result = null;
                 if (this.ignoreError) {
                     result = WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded, serviceContext, -1, true);
                 } else {
                     result = WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded, serviceContext);
                 }
-
                 if (!this.resultMapNameAcsr.isEmpty()) {
                     this.resultMapNameAcsr.put(context, result);
-                    String queryString = (String)result.get("queryString");
+                    String queryString = (String) result.get("queryString");
                     context.put("queryString", queryString);
                     context.put("queryStringMap", result.get("queryStringMap"));
                     if (UtilValidate.isNotEmpty(queryString)) {
@@ -159,189 +230,21 @@
                 Object listObj = result.get(listName);
                 if (listObj != null) {
                     if (!(listObj instanceof List<?>) && !(listObj instanceof ListIterator<?>)) {
-                        throw new IllegalArgumentException("Error in form [" + this.modelWidget.getName() + "] calling service with name [" + serviceNameExpanded + "]: the result that is supposed to be a List or ListIterator and is not.");
+                        throw new IllegalArgumentException("Error in form [" + this.getModelWidget().getName()
+                                + "] calling service with name [" + serviceNameExpanded
+                                + "]: the result that is supposed to be a List or ListIterator and is not.");
                     }
                     context.put("listName", listName);
                     context.put(listName, listObj);
                 }
             } catch (GenericServiceException e) {
-                String errMsg = "Error in form [" + this.modelWidget.getName() + "] calling service with name [" + serviceNameExpanded + "]: " + e.toString();
+                String errMsg = "Error in form [" + this.getModelWidget().getName() + "] calling service with name ["
+                        + serviceNameExpanded + "]: " + e.toString();
                 Debug.logError(e, errMsg, module);
                 if (!this.ignoreError) {
                     throw new IllegalArgumentException(errMsg);
                 }
             }
         }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        public String getServiceName() {
-            return serviceNameExdr.getOriginal();
-        }
-    }
-
-    @SuppressWarnings("serial")
-    public static class EntityAnd extends ModelWidgetAction {
-        protected ByAndFinder finder;
-
-        public EntityAnd(ModelForm modelForm, Element entityAndElement) {
-            super (modelForm, entityAndElement);
-
-            //don't want to default to the iterator, should be specified explicitly, not the default
-            // Document ownerDoc = entityAndElement.getOwnerDocument();
-            // boolean useCache = "true".equalsIgnoreCase(entityAndElement.getAttribute("use-cache"));
-            // if (!useCache) UtilXml.addChildElement(entityAndElement, "use-iterator", ownerDoc);
-
-            // make list-name optional
-            if (UtilValidate.isEmpty(entityAndElement.getAttribute("list")) && UtilValidate.isEmpty(entityAndElement.getAttribute("list-name"))) {
-                String lstNm = modelForm.getListName();
-                if (UtilValidate.isEmpty(lstNm)) {
-                    lstNm = ModelForm.DEFAULT_FORM_RESULT_LIST_NAME;
-                }
-                entityAndElement.setAttribute("list", lstNm);
-            }
-            finder = new ByAndFinder(entityAndElement);
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            try {
-                // don't want to do this: context.put("defaultFormResultList", null);
-                finder.runFind(context, WidgetWorker.getDelegator(context));
-                
-                /* NOTE DEJ20100925: this should not be running any more as it causes actions in a list or multi 
-                 * form definition to overwrite the desired list elsewhere, this was the really old way of doing 
-                 * it that was removed a long time ago and needs to stay gone to avoid issues; the form's list 
-                 * should be found by explicitly matching the name:
-                Object obj = context.get(this.actualListName);
-                if (obj != null && ((obj instanceof List) || (obj instanceof EntityListIterator))) {
-                    String modelFormListName = modelForm.getListName();
-                    context.put(modelFormListName, obj);
-                }
-                 */
-            } catch (GeneralException e) {
-                String errMsg = "Error doing entity query by condition: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        public ByAndFinder getFinder() {
-            return finder;
-        }
-    }
-
-    @SuppressWarnings("serial")
-    public static class EntityCondition extends ModelWidgetAction {
-        ByConditionFinder finder;
-        String actualListName;
-
-        public EntityCondition(ModelForm modelForm, Element entityConditionElement) {
-            super (modelForm, entityConditionElement);
-
-            //don't want to default to the iterator, should be specified explicitly, not the default
-            // Document ownerDoc = entityConditionElement.getOwnerDocument();
-            // boolean useCache = "true".equalsIgnoreCase(entityConditionElement.getAttribute("use-cache"));
-            // if (!useCache) UtilXml.addChildElement(entityConditionElement, "use-iterator", ownerDoc);
-
-            // make list-name optional
-            if (UtilValidate.isEmpty(entityConditionElement.getAttribute("list")) && UtilValidate.isEmpty(entityConditionElement.getAttribute("list-name"))) {
-                String lstNm = modelForm.getListName();
-                if (UtilValidate.isEmpty(lstNm)) {
-                    lstNm = ModelForm.DEFAULT_FORM_RESULT_LIST_NAME;
-                }
-                entityConditionElement.setAttribute("list", lstNm);
-            }
-            this.actualListName = entityConditionElement.getAttribute("list");
-            if (UtilValidate.isEmpty(this.actualListName)) this.actualListName = entityConditionElement.getAttribute("list-name");
-            finder = new ByConditionFinder(entityConditionElement);
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            try {
-                // don't want to do this: context.put("defaultFormResultList", null);
-                finder.runFind(context, WidgetWorker.getDelegator(context));
-                
-                /* NOTE DEJ20100925: this should not be running any more as it causes actions in a list or multi 
-                 * form definition to overwrite the desired list elsewhere, this was the really old way of doing 
-                 * it that was removed a long time ago and needs to stay gone to avoid issues; the form's list 
-                 * should be found by explicitly matching the name:
-                Object obj = context.get(this.actualListName);
-                if (obj != null && ((obj instanceof List) || (obj instanceof EntityListIterator))) {
-                    String modelFormListName = modelForm.getListName();
-                    context.put(modelFormListName, obj);
-                }
-                 */
-            } catch (GeneralException e) {
-                String errMsg = "Error doing entity query by condition: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        public ByConditionFinder getFinder() {
-            return finder;
-        }
-    }
-
-    @SuppressWarnings("serial")
-    public static class CallParentActions extends ModelWidgetAction {
-        protected static enum ActionsKind {
-            ACTIONS,
-            ROW_ACTIONS
-        };
-
-        protected ActionsKind kind;
-        private final ModelForm modelForm;
-
-        public CallParentActions(ModelForm modelForm, Element callParentActionsElement) {
-            super(modelForm, callParentActionsElement);
-            String parentName = callParentActionsElement.getParentNode().getNodeName();
-            if ("actions".equals(parentName)) {
-                kind = ActionsKind.ACTIONS;
-            } else if ("row-actions".equals(parentName)) {
-                kind = ActionsKind.ROW_ACTIONS;
-            } else {
-                throw new IllegalArgumentException("Action element not supported for call-parent-actions : " + parentName);
-            }
-
-            ModelForm parentModel = modelForm.getParentModelForm();
-            if (parentModel == null) {
-                throw new IllegalArgumentException("call-parent-actions can only be used with form extending another form");
-            }
-            this.modelForm = modelForm;
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            ModelForm parentModel = modelForm.getParentModelForm();
-            switch (kind) {
-                case ACTIONS:
-                    parentModel.runFormActions(context);
-                    break;
-                case ROW_ACTIONS:
-                    ModelWidgetAction.runSubActions(parentModel.getRowActions(), context);
-                    break;
-            }
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
     }
 }
diff --git a/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java b/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java
index 03a0da2..0f0cf53 100644
--- a/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java
+++ b/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java
@@ -24,6 +24,7 @@
 import java.text.DateFormat;
 import java.text.NumberFormat;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -41,6 +42,7 @@
 import org.ofbiz.base.util.GeneralException;
 import org.ofbiz.base.util.ObjectType;
 import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
 import org.ofbiz.base.util.UtilDateTime;
 import org.ofbiz.base.util.UtilFormatOut;
 import org.ofbiz.base.util.UtilGenerics;
@@ -58,13 +60,7 @@
 import org.ofbiz.entity.condition.EntityCondition;
 import org.ofbiz.entity.finder.EntityFinderUtil;
 import org.ofbiz.entity.model.ModelEntity;
-import org.ofbiz.entity.model.ModelField;
-import org.ofbiz.entity.model.ModelReader;
 import org.ofbiz.entity.util.EntityUtil;
-import org.ofbiz.service.DispatchContext;
-import org.ofbiz.service.GenericServiceException;
-import org.ofbiz.service.ModelParam;
-import org.ofbiz.service.ModelService;
 import org.ofbiz.widget.ModelFieldVisitor;
 import org.ofbiz.widget.WidgetWorker;
 import org.ofbiz.widget.form.ModelForm.UpdateArea;
@@ -74,534 +70,128 @@
 import bsh.Interpreter;
 
 /**
- * Widget Library - Form model class
+ * Models the &lt;field&gt; element.
+ * 
+ * @see <code>widget-form.xsd</code>
  */
 public class ModelFormField {
 
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     DEVELOPERS PLEASE READ
+     * ----------------------------------------------------------------------- *
+     * 
+     * This model is intended to be a read-only data structure that represents
+     * an XML element. Outside of object construction, the class should not
+     * have any behaviors. All behavior should be contained in model visitors.
+     * 
+     * Instances of this class will be shared by multiple threads - therefore
+     * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME!
+     * 
+     */
+
     public static final String module = ModelFormField.class.getName();
 
-    protected ModelForm modelForm;
-
-    protected String name;
-    protected FlexibleMapAccessor<Map<String, ? extends Object>> mapAcsr;
-    protected String entityName;
-    protected String serviceName;
-    protected FlexibleMapAccessor<Object> entryAcsr;
-    protected String parameterName;
-    protected String fieldName;
-    protected String attributeName;
-    protected FlexibleStringExpander title;
-    protected FlexibleStringExpander tooltip;
-    protected String titleAreaStyle;
-    protected String widgetAreaStyle;
-    protected String titleStyle;
-    protected String widgetStyle;
-    protected String tooltipStyle;
-    protected String requiredFieldStyle;
-    protected String sortFieldStyle;
-    protected String sortFieldAscStyle;
-    protected String sortFieldDescStyle;
-    protected Integer position = null;
-    protected String redWhen;
-    protected FlexibleStringExpander useWhen;
-    protected boolean encodeOutput = true;
-    protected String event;
-    protected FlexibleStringExpander action;
-
-    protected FieldInfo fieldInfo = null;
-    protected String idName;
-    protected boolean separateColumn = false;
-    protected Boolean requiredField = null;
-    protected Boolean sortField = null;
-    protected String sortFieldHelpText = "";
-    protected String headerLink;
-    protected String headerLinkStyle;
-
-    /** On Change Event areas to be updated. */
-    protected List<UpdateArea> onChangeUpdateAreas;
-    /** On Click Event areas to be updated. */
-    protected List<UpdateArea> onClickUpdateAreas;
-
-    // ===== CONSTRUCTORS =====
-    /** Default Constructor */
-    public ModelFormField(ModelForm modelForm) {
-        this.modelForm = modelForm;
+    public static ModelFormField from(ModelFormFieldBuilder builder) {
+        return new ModelFormField(builder);
     }
 
-    /** XML Constructor */
-    public ModelFormField(Element fieldElement, ModelForm modelForm, ModelReader entityModelReader,
-            DispatchContext dispatchContext) {
-        this.modelForm = modelForm;
-        this.name = fieldElement.getAttribute("name");
-        this.setMapName(fieldElement.getAttribute("map-name"));
-        this.entityName = fieldElement.getAttribute("entity-name");
-        this.serviceName = fieldElement.getAttribute("service-name");
-        this.setEntryName(UtilXml.checkEmpty(fieldElement.getAttribute("entry-name"), this.name));
-        this.parameterName = UtilXml.checkEmpty(fieldElement.getAttribute("parameter-name"), this.name);
-        this.fieldName = UtilXml.checkEmpty(fieldElement.getAttribute("field-name"), this.name);
-        this.attributeName = UtilXml.checkEmpty(fieldElement.getAttribute("attribute-name"), this.name);
-        this.setTitle(fieldElement.hasAttribute("title") ? fieldElement.getAttribute("title") : null);
-        this.setTooltip(fieldElement.getAttribute("tooltip"));
-        this.titleAreaStyle = fieldElement.getAttribute("title-area-style");
-        this.widgetAreaStyle = fieldElement.getAttribute("widget-area-style");
-        this.titleStyle = fieldElement.getAttribute("title-style");
-        this.widgetStyle = fieldElement.getAttribute("widget-style");
-        this.tooltipStyle = fieldElement.getAttribute("tooltip-style");
-        this.requiredFieldStyle = fieldElement.getAttribute("required-field-style");
-        this.sortFieldStyle = fieldElement.getAttribute("sort-field-style");
-        this.sortFieldAscStyle = fieldElement.getAttribute("sort-field-asc-style");
-        this.sortFieldDescStyle = fieldElement.getAttribute("sort-field-desc-style");
-        this.redWhen = fieldElement.getAttribute("red-when");
-        this.setUseWhen(fieldElement.getAttribute("use-when"));
-        this.encodeOutput = !"false".equals(fieldElement.getAttribute("encode-output"));
-        this.event = fieldElement.getAttribute("event");
-        this.setAction(fieldElement.hasAttribute("action") ? fieldElement.getAttribute("action") : null);
-        this.idName = fieldElement.getAttribute("id-name");
-        this.separateColumn = "true".equals(fieldElement.getAttribute("separate-column"));
-        this.requiredField = fieldElement.hasAttribute("required-field") ? "true".equals(fieldElement
-                .getAttribute("required-field")) : null;
-        this.sortField = fieldElement.hasAttribute("sort-field") ? "true".equals(fieldElement.getAttribute("sort-field")) : null;
-        this.sortFieldHelpText = fieldElement.getAttribute("sort-field-help-text");
-        this.headerLink = fieldElement.getAttribute("header-link");
-        this.headerLinkStyle = fieldElement.getAttribute("header-link-style");
+    private final FlexibleStringExpander action;
+    private final String attributeName;
+    private final boolean encodeOutput;
+    private final String entityName;
+    private final FlexibleMapAccessor<Object> entryAcsr;
+    private final String event;
+    private final FieldInfo fieldInfo;
+    private final String fieldName;
+    private final String headerLink;
+    private final String headerLinkStyle;
+    private final String idName;
+    private final FlexibleMapAccessor<Map<String, ? extends Object>> mapAcsr;
+    private final ModelForm modelForm;
+    private final String name;
+    private final List<UpdateArea> onChangeUpdateAreas;
+    private final List<UpdateArea> onClickUpdateAreas;
+    private final String parameterName;
+    private final Integer position;
+    private final String redWhen;
+    private final Boolean requiredField;
+    private final String requiredFieldStyle;
+    private final boolean separateColumn;
+    private final String serviceName;
+    private final Boolean sortField;
+    private final String sortFieldAscStyle;
+    private final String sortFieldDescStyle;
+    private final String sortFieldHelpText;
+    private final String sortFieldStyle;
+    private final FlexibleStringExpander title;
+    private final String titleAreaStyle;
+    private final String titleStyle;
+    private final FlexibleStringExpander tooltip;
+    private final String tooltipStyle;
+    private final FlexibleStringExpander useWhen;
+    private final String widgetAreaStyle;
+    private final String widgetStyle;
 
-        String positionStr = fieldElement.getAttribute("position");
-        try {
-            if (UtilValidate.isNotEmpty(positionStr))
-                position = Integer.valueOf(positionStr);
-        } catch (Exception e) {
-            Debug.logError(e, "Could not convert position attribute of the field element to an integer: [" + positionStr
-                    + "], using the default of the form renderer", module);
-        }
-
-        // get sub-element and set fieldInfo
-        List<? extends Element> subElements = UtilXml.childElementList(fieldElement);
-        for (Element subElement : subElements) {
-            String subElementName = subElement.getTagName();
-            if (Debug.verboseOn())
-                Debug.logVerbose("Processing field " + this.name + " with type info tag " + subElementName, module);
-
-            if (UtilValidate.isEmpty(subElementName)) {
-                this.fieldInfo = null;
-                this.induceFieldInfo(null, entityModelReader, dispatchContext); //no defaultFieldType specified here, will default to edit
-            } else if ("display".equals(subElementName))
-                this.fieldInfo = new DisplayField(subElement, this);
-            else if ("display-entity".equals(subElementName))
-                this.fieldInfo = new DisplayEntityField(subElement, this);
-            else if ("hyperlink".equals(subElementName))
-                this.fieldInfo = new HyperlinkField(subElement, this);
-            else if ("text".equals(subElementName))
-                this.fieldInfo = new TextField(subElement, this);
-            else if ("textarea".equals(subElementName))
-                this.fieldInfo = new TextareaField(subElement, this);
-            else if ("date-time".equals(subElementName))
-                this.fieldInfo = new DateTimeField(subElement, this);
-            else if ("drop-down".equals(subElementName))
-                this.fieldInfo = new DropDownField(subElement, this);
-            else if ("check".equals(subElementName))
-                this.fieldInfo = new CheckField(subElement, this);
-            else if ("radio".equals(subElementName))
-                this.fieldInfo = new RadioField(subElement, this);
-            else if ("submit".equals(subElementName))
-                this.fieldInfo = new SubmitField(subElement, this);
-            else if ("reset".equals(subElementName))
-                this.fieldInfo = new ResetField(subElement, this);
-            else if ("hidden".equals(subElementName))
-                this.fieldInfo = new HiddenField(subElement, this);
-            else if ("ignored".equals(subElementName))
-                this.fieldInfo = new IgnoredField(subElement, this);
-            else if ("text-find".equals(subElementName))
-                this.fieldInfo = new TextFindField(subElement, this);
-            else if ("date-find".equals(subElementName))
-                this.fieldInfo = new DateFindField(subElement, this);
-            else if ("range-find".equals(subElementName))
-                this.fieldInfo = new RangeFindField(subElement, this);
-            else if ("lookup".equals(subElementName))
-                this.fieldInfo = new LookupField(subElement, this);
-            else if ("file".equals(subElementName))
-                this.fieldInfo = new FileField(subElement, this);
-            else if ("password".equals(subElementName))
-                this.fieldInfo = new PasswordField(subElement, this);
-            else if ("image".equals(subElementName))
-                this.fieldInfo = new ImageField(subElement, this);
-            else if ("container".equals(subElementName))
-                this.fieldInfo = new ContainerField(subElement, this);
-            else if ("on-field-event-update-area".equals(subElementName))
-                addOnEventUpdateArea(new UpdateArea(subElement));
-            else
-                throw new IllegalArgumentException("The field sub-element with name " + subElementName + " is not supported");
-        }
-    }
-
-    private void addOnEventUpdateArea(UpdateArea updateArea) {
-        // Event types are sorted as a convenience for the rendering classes
-        Debug.logInfo(this.modelForm.getName() + ":" + this.name + " adding UpdateArea type " + updateArea.getEventType(), module);
-        if ("change".equals(updateArea.getEventType()))
-            addOnChangeUpdateArea(updateArea);
-        else if ("click".equals(updateArea.getEventType()))
-            addOnClickUpdateArea(updateArea);
-    }
-
-    private void addOnChangeUpdateArea(UpdateArea updateArea) {
-        if (onChangeUpdateAreas == null)
-            onChangeUpdateAreas = new ArrayList<UpdateArea>();
-        onChangeUpdateAreas.add(updateArea);
-        Debug.logInfo(this.modelForm.getName() + ":" + this.name + " onChangeUpdateAreas size = " + onChangeUpdateAreas.size(),
-                module);
-    }
-
-    private void addOnClickUpdateArea(UpdateArea updateArea) {
-        if (onClickUpdateAreas == null)
-            onClickUpdateAreas = new ArrayList<UpdateArea>();
-        onClickUpdateAreas.add(updateArea);
-    }
-
-    public void mergeOverrideModelFormField(ModelFormField overrideFormField) {
-        if (overrideFormField == null)
-            return;
-
-        // incorporate updates for values that are not empty in the overrideFormField
-        if (UtilValidate.isNotEmpty(overrideFormField.name))
-            this.name = overrideFormField.name;
-        if (UtilValidate.isNotEmpty(overrideFormField.mapAcsr))
-            this.mapAcsr = overrideFormField.mapAcsr; //Debug.logInfo("overriding mapAcsr, old=" + (this.mapAcsr==null?"null":this.mapAcsr.getOriginalName()) + ", new=" + overrideFormField.mapAcsr.getOriginalName(), module);
-        if (UtilValidate.isNotEmpty(overrideFormField.entityName))
-            this.entityName = overrideFormField.entityName;
-        if (UtilValidate.isNotEmpty(overrideFormField.serviceName))
-            this.serviceName = overrideFormField.serviceName;
-        if (UtilValidate.isNotEmpty(overrideFormField.entryAcsr))
-            this.entryAcsr = overrideFormField.entryAcsr;
-        if (UtilValidate.isNotEmpty(overrideFormField.parameterName))
-            this.parameterName = overrideFormField.parameterName;
-        if (UtilValidate.isNotEmpty(overrideFormField.fieldName))
-            this.fieldName = overrideFormField.fieldName;
-        if (UtilValidate.isNotEmpty(overrideFormField.attributeName))
-            this.attributeName = overrideFormField.attributeName;
-        if (UtilValidate.isNotEmpty(overrideFormField.title))
-            this.title = overrideFormField.title; // title="" can be used to override the original value
-        if (UtilValidate.isNotEmpty(overrideFormField.tooltip))
-            this.tooltip = overrideFormField.tooltip;
-        if (overrideFormField.requiredField != null)
-            this.requiredField = overrideFormField.requiredField;
-        if (overrideFormField.sortField != null)
-            this.sortField = overrideFormField.sortField;
-        if (UtilValidate.isNotEmpty(overrideFormField.sortFieldHelpText))
-            this.sortFieldHelpText = overrideFormField.sortFieldHelpText;
-        if (UtilValidate.isNotEmpty(overrideFormField.titleAreaStyle))
-            this.titleAreaStyle = overrideFormField.titleAreaStyle;
-        if (UtilValidate.isNotEmpty(overrideFormField.widgetAreaStyle))
-            this.widgetAreaStyle = overrideFormField.widgetAreaStyle;
-        if (UtilValidate.isNotEmpty(overrideFormField.titleStyle))
-            this.titleStyle = overrideFormField.titleStyle;
-        if (UtilValidate.isNotEmpty(overrideFormField.widgetStyle))
-            this.widgetStyle = overrideFormField.widgetStyle;
-        if (overrideFormField.position != null)
-            this.position = overrideFormField.position;
-        if (UtilValidate.isNotEmpty(overrideFormField.redWhen))
-            this.redWhen = overrideFormField.redWhen;
-        if (UtilValidate.isNotEmpty(overrideFormField.event))
-            this.event = overrideFormField.event;
-        if (UtilValidate.isNotEmpty(overrideFormField.action))
-            this.action = overrideFormField.action;
-        if (UtilValidate.isNotEmpty(overrideFormField.useWhen))
-            this.useWhen = overrideFormField.useWhen;
-        if (overrideFormField.fieldInfo != null)
-            this.setFieldInfo(overrideFormField.fieldInfo);
-        if (overrideFormField.headerLink != null)
-            this.setHeaderLink(overrideFormField.headerLink);
-        if (UtilValidate.isNotEmpty(overrideFormField.idName))
-            this.idName = overrideFormField.idName;
-        if (overrideFormField.onChangeUpdateAreas != null)
-            this.onChangeUpdateAreas = overrideFormField.onChangeUpdateAreas;
-        if (overrideFormField.onClickUpdateAreas != null)
-            this.onClickUpdateAreas = overrideFormField.onClickUpdateAreas;
-        this.encodeOutput = overrideFormField.encodeOutput;
-    }
-
-    private boolean induceFieldInfo(String defaultFieldType, ModelReader entityModelReader, DispatchContext dispatchContext) {
-        if (this.induceFieldInfoFromEntityField(defaultFieldType, entityModelReader))
-            return true;
-        if (this.induceFieldInfoFromServiceParam(defaultFieldType, entityModelReader, dispatchContext))
-            return true;
-        return false;
-    }
-
-    private boolean induceFieldInfoFromServiceParam(String defaultFieldType, ModelReader entityModelReader,
-            DispatchContext dispatchContext) {
-        if (UtilValidate.isEmpty(this.getServiceName()) || UtilValidate.isEmpty(this.getAttributeName()))
-            return false;
-        try {
-            ModelService modelService = dispatchContext.getModelService(this.getServiceName());
-            if (modelService != null) {
-                ModelParam modelParam = modelService.getParam(this.getAttributeName());
-                if (modelParam != null) {
-                    if (UtilValidate.isNotEmpty(modelParam.entityName) && UtilValidate.isNotEmpty(modelParam.fieldName)) {
-                        this.entityName = modelParam.entityName;
-                        this.fieldName = modelParam.fieldName;
-                        if (this.induceFieldInfoFromEntityField(defaultFieldType, entityModelReader)) {
-                            return true;
-                        }
-                    }
-
-                    this.induceFieldInfoFromServiceParam(modelService, modelParam, defaultFieldType);
-                    return true;
-                }
-            }
-        } catch (GenericServiceException e) {
-            Debug.logError(e,
-                    "error getting service parameter definition for auto-field with serviceName: " + this.getServiceName()
-                            + ", and attributeName: " + this.getAttributeName(), module);
-        }
-        return false;
-    }
-
-    public boolean induceFieldInfoFromServiceParam(ModelService modelService, ModelParam modelParam, String defaultFieldType) {
-        if (modelService == null || modelParam == null)
-            return false;
-
-        this.serviceName = modelService.name;
-        this.attributeName = modelParam.name;
-
-        if ("find".equals(defaultFieldType)) {
-            if (modelParam.type.indexOf("Double") != -1 || modelParam.type.indexOf("Float") != -1
-                    || modelParam.type.indexOf("Long") != -1 || modelParam.type.indexOf("Integer") != -1) {
-                ModelFormField.RangeFindField textField = new ModelFormField.RangeFindField(FieldInfo.SOURCE_AUTO_SERVICE, this);
-                textField.setSize(6);
-                this.setFieldInfo(textField);
-            } else if (modelParam.type.indexOf("Timestamp") != -1) {
-                ModelFormField.DateFindField dateTimeField = new ModelFormField.DateFindField(FieldInfo.SOURCE_AUTO_SERVICE, this);
-                dateTimeField.setType("timestamp");
-                this.setFieldInfo(dateTimeField);
-            } else if (modelParam.type.indexOf("Date") != -1) {
-                ModelFormField.DateFindField dateTimeField = new ModelFormField.DateFindField(FieldInfo.SOURCE_AUTO_SERVICE, this);
-                dateTimeField.setType("date");
-                this.setFieldInfo(dateTimeField);
-            } else if (modelParam.type.indexOf("Time") != -1) {
-                ModelFormField.DateFindField dateTimeField = new ModelFormField.DateFindField(FieldInfo.SOURCE_AUTO_SERVICE, this);
-                dateTimeField.setType("time");
-                this.setFieldInfo(dateTimeField);
-            } else {
-                ModelFormField.TextFindField textField = new ModelFormField.TextFindField(FieldInfo.SOURCE_AUTO_SERVICE, this);
-                this.setFieldInfo(textField);
-            }
-        } else if ("display".equals(defaultFieldType)) {
-            ModelFormField.DisplayField displayField = new ModelFormField.DisplayField(FieldInfo.SOURCE_AUTO_SERVICE, this);
-            this.setFieldInfo(displayField);
+    private ModelFormField(ModelFormFieldBuilder builder) {
+        this.action = builder.getAction();
+        this.attributeName = builder.getAttributeName();
+        this.encodeOutput = builder.getEncodeOutput();
+        this.entityName = builder.getEntityName();
+        this.entryAcsr = builder.getEntryAcsr();
+        this.event = builder.getEvent();
+        if (builder.getFieldInfo() != null) {
+            this.fieldInfo = builder.getFieldInfo().copy(this);
         } else {
-            // default to "edit"
-            if (modelParam.type.indexOf("Double") != -1 || modelParam.type.indexOf("Float") != -1
-                    || modelParam.type.indexOf("Long") != -1 || modelParam.type.indexOf("Integer") != -1) {
-                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_SERVICE, this);
-                textField.setSize(6);
-                this.setFieldInfo(textField);
-            } else if (modelParam.type.indexOf("Timestamp") != -1) {
-                ModelFormField.DateTimeField dateTimeField = new ModelFormField.DateTimeField(FieldInfo.SOURCE_AUTO_SERVICE, this);
-                dateTimeField.setType("timestamp");
-                this.setFieldInfo(dateTimeField);
-            } else if (modelParam.type.indexOf("Date") != -1) {
-                ModelFormField.DateTimeField dateTimeField = new ModelFormField.DateTimeField(FieldInfo.SOURCE_AUTO_SERVICE, this);
-                dateTimeField.setType("date");
-                this.setFieldInfo(dateTimeField);
-            } else if (modelParam.type.indexOf("Time") != -1) {
-                ModelFormField.DateTimeField dateTimeField = new ModelFormField.DateTimeField(FieldInfo.SOURCE_AUTO_SERVICE, this);
-                dateTimeField.setType("time");
-                this.setFieldInfo(dateTimeField);
-            } else {
-                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_SERVICE, this);
-                this.setFieldInfo(textField);
-            }
+            this.fieldInfo = null;
         }
-
-        return true;
-    }
-
-    private boolean induceFieldInfoFromEntityField(String defaultFieldType, ModelReader entityModelReader) {
-        if (UtilValidate.isEmpty(this.getEntityName()) || UtilValidate.isEmpty(this.getFieldName()))
-            return false;
-        try {
-            ModelEntity modelEntity = entityModelReader.getModelEntity(this.getEntityName());
-            if (modelEntity != null) {
-                ModelField modelField = modelEntity.getField(this.getFieldName());
-                if (modelField != null) {
-                    // okay, populate using the entity field info...
-                    this.induceFieldInfoFromEntityField(modelEntity, modelField, defaultFieldType);
-                    return true;
-                }
-            }
-        } catch (GenericEntityException e) {
-            Debug.logError(e, module);
-        }
-        return false;
-    }
-
-    public boolean induceFieldInfoFromEntityField(ModelEntity modelEntity, ModelField modelField, String defaultFieldType) {
-        if (modelEntity == null || modelField == null)
-            return false;
-
-        this.entityName = modelEntity.getEntityName();
-        this.fieldName = modelField.getName();
-
-        if ("find".equals(defaultFieldType)) {
-            if ("id".equals(modelField.getType()) || "id-ne".equals(modelField.getType())) {
-                ModelFormField.TextFindField textField = new ModelFormField.TextFindField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textField.setSize(20);
-                textField.setMaxlength(Integer.valueOf(20));
-                this.setFieldInfo(textField);
-            } else if ("id-long".equals(modelField.getType()) || "id-long-ne".equals(modelField.getType())) {
-                ModelFormField.TextFindField textField = new ModelFormField.TextFindField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textField.setSize(40);
-                textField.setMaxlength(Integer.valueOf(60));
-                this.setFieldInfo(textField);
-            } else if ("id-vlong".equals(modelField.getType()) || "id-vlong-ne".equals(modelField.getType())) {
-                ModelFormField.TextFindField textField = new ModelFormField.TextFindField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textField.setSize(60);
-                textField.setMaxlength(Integer.valueOf(250));
-                this.setFieldInfo(textField);
-            } else if ("very-short".equals(modelField.getType())) {
-                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textField.setSize(6);
-                textField.setMaxlength(Integer.valueOf(10));
-                this.setFieldInfo(textField);
-            } else if ("name".equals(modelField.getType()) || "short-varchar".equals(modelField.getType())) {
-                ModelFormField.TextFindField textField = new ModelFormField.TextFindField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textField.setSize(40);
-                textField.setMaxlength(Integer.valueOf(60));
-                this.setFieldInfo(textField);
-            } else if ("value".equals(modelField.getType()) || "comment".equals(modelField.getType())
-                    || "description".equals(modelField.getType()) || "long-varchar".equals(modelField.getType())
-                    || "url".equals(modelField.getType()) || "email".equals(modelField.getType())) {
-                ModelFormField.TextFindField textField = new ModelFormField.TextFindField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textField.setSize(60);
-                textField.setMaxlength(Integer.valueOf(250));
-                this.setFieldInfo(textField);
-            } else if ("floating-point".equals(modelField.getType()) || "currency-amount".equals(modelField.getType())
-                    || "numeric".equals(modelField.getType())) {
-                ModelFormField.RangeFindField textField = new ModelFormField.RangeFindField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textField.setSize(6);
-                this.setFieldInfo(textField);
-            } else if ("date-time".equals(modelField.getType()) || "date".equals(modelField.getType())
-                    || "time".equals(modelField.getType())) {
-                ModelFormField.DateFindField dateTimeField = new ModelFormField.DateFindField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                if ("date-time".equals(modelField.getType())) {
-                    dateTimeField.setType("timestamp");
-                } else if ("date".equals(modelField.getType())) {
-                    dateTimeField.setType("date");
-                } else if ("time".equals(modelField.getType())) {
-                    dateTimeField.setType("time");
-                }
-                this.setFieldInfo(dateTimeField);
-            } else {
-                ModelFormField.TextFindField textField = new ModelFormField.TextFindField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                this.setFieldInfo(textField);
-            }
-        } else if ("display".equals(defaultFieldType)) {
-            ModelFormField.DisplayField displayField = new ModelFormField.DisplayField(FieldInfo.SOURCE_AUTO_SERVICE, this);
-            this.setFieldInfo(displayField);
-        } else if ("hidden".equals(defaultFieldType)) {
-            ModelFormField.HiddenField hiddenField = new ModelFormField.HiddenField(FieldInfo.SOURCE_AUTO_SERVICE, this);
-            this.setFieldInfo(hiddenField);
+        this.fieldName = builder.getFieldName();
+        this.headerLink = builder.getHeaderLink();
+        this.headerLinkStyle = builder.getHeaderLinkStyle();
+        this.idName = builder.getIdName();
+        this.mapAcsr = builder.getMapAcsr();
+        this.modelForm = builder.getModelForm();
+        this.name = builder.getName();
+        if (builder.getOnChangeUpdateAreas().isEmpty()) {
+            this.onChangeUpdateAreas = Collections.emptyList();
         } else {
-            if ("id".equals(modelField.getType()) || "id-ne".equals(modelField.getType())) {
-                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textField.setSize(20);
-                textField.setMaxlength(Integer.valueOf(20));
-                this.setFieldInfo(textField);
-            } else if ("id-long".equals(modelField.getType()) || "id-long-ne".equals(modelField.getType())) {
-                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textField.setSize(40);
-                textField.setMaxlength(Integer.valueOf(60));
-                this.setFieldInfo(textField);
-            } else if ("id-vlong".equals(modelField.getType()) || "id-vlong-ne".equals(modelField.getType())) {
-                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textField.setSize(60);
-                textField.setMaxlength(Integer.valueOf(250));
-                this.setFieldInfo(textField);
-            } else if ("indicator".equals(modelField.getType())) {
-                ModelFormField.DropDownField dropDownField = new ModelFormField.DropDownField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                dropDownField.setAllowEmpty(false);
-                dropDownField.addOptionSource(new ModelFormField.SingleOption("Y", null, dropDownField));
-                dropDownField.addOptionSource(new ModelFormField.SingleOption("N", null, dropDownField));
-                this.setFieldInfo(dropDownField);
-                //ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                //textField.setSize(1);
-                //textField.setMaxlength(Integer.valueOf(1));
-                //this.setFieldInfo(textField);
-            } else if ("very-short".equals(modelField.getType())) {
-                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textField.setSize(6);
-                textField.setMaxlength(Integer.valueOf(10));
-                this.setFieldInfo(textField);
-            } else if ("very-long".equals(modelField.getType())) {
-                ModelFormField.TextareaField textareaField = new ModelFormField.TextareaField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textareaField.setCols(60);
-                textareaField.setRows(2);
-                this.setFieldInfo(textareaField);
-            } else if ("name".equals(modelField.getType()) || "short-varchar".equals(modelField.getType())) {
-                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textField.setSize(40);
-                textField.setMaxlength(Integer.valueOf(60));
-                this.setFieldInfo(textField);
-            } else if ("value".equals(modelField.getType()) || "comment".equals(modelField.getType())
-                    || "description".equals(modelField.getType()) || "long-varchar".equals(modelField.getType())
-                    || "url".equals(modelField.getType()) || "email".equals(modelField.getType())) {
-                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textField.setSize(60);
-                textField.setMaxlength(Integer.valueOf(250));
-                this.setFieldInfo(textField);
-            } else if ("floating-point".equals(modelField.getType()) || "currency-amount".equals(modelField.getType())
-                    || "numeric".equals(modelField.getType())) {
-                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                textField.setSize(6);
-                this.setFieldInfo(textField);
-            } else if ("date-time".equals(modelField.getType()) || "date".equals(modelField.getType())
-                    || "time".equals(modelField.getType())) {
-                ModelFormField.DateTimeField dateTimeField = new ModelFormField.DateTimeField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                if ("date-time".equals(modelField.getType())) {
-                    dateTimeField.setType("timestamp");
-                } else if ("date".equals(modelField.getType())) {
-                    dateTimeField.setType("date");
-                } else if ("time".equals(modelField.getType())) {
-                    dateTimeField.setType("time");
-                }
-                this.setFieldInfo(dateTimeField);
-            } else {
-                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, this);
-                this.setFieldInfo(textField);
-            }
+            this.onChangeUpdateAreas = Collections.unmodifiableList(new ArrayList<UpdateArea>(builder.getOnChangeUpdateAreas()));
         }
-
-        return true;
-    }
-
-    public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-            throws IOException {
-        this.fieldInfo.renderFieldString(writer, context, formStringRenderer);
-    }
-
-    public List<UpdateArea> getOnChangeUpdateAreas() {
-        return onChangeUpdateAreas;
-    }
-
-    public List<UpdateArea> getOnClickUpdateAreas() {
-        return onClickUpdateAreas;
-    }
-
-    public FieldInfo getFieldInfo() {
-        return fieldInfo;
-    }
-
-    public ModelForm getModelForm() {
-        return modelForm;
-    }
-
-    /**
-     * @param fieldInfo
-     */
-    public void setFieldInfo(FieldInfo fieldInfo) {
-        // field info is a little different, check source for priority
-        if (fieldInfo != null && (this.fieldInfo == null || (fieldInfo.getFieldSource() <= this.fieldInfo.getFieldSource()))) {
-            this.fieldInfo = fieldInfo.copy(this);
+        if (builder.getOnClickUpdateAreas().isEmpty()) {
+            this.onClickUpdateAreas = Collections.emptyList();
+        } else {
+            this.onClickUpdateAreas = Collections.unmodifiableList(new ArrayList<UpdateArea>(builder.getOnClickUpdateAreas()));
         }
+        this.parameterName = builder.getParameterName();
+        this.position = builder.getPosition();
+        this.redWhen = builder.getRedWhen();
+        this.requiredField = builder.getRequiredField();
+        this.requiredFieldStyle = builder.getRequiredFieldStyle();
+        this.separateColumn = builder.getSeparateColumn();
+        this.serviceName = builder.getServiceName();
+        this.sortField = builder.getSortField();
+        this.sortFieldAscStyle = builder.getSortFieldAscStyle();
+        this.sortFieldDescStyle = builder.getSortFieldDescStyle();
+        this.sortFieldHelpText = builder.getSortFieldHelpText();
+        this.sortFieldStyle = builder.getSortFieldStyle();
+        this.title = builder.getTitle();
+        this.titleAreaStyle = builder.getTitleAreaStyle();
+        this.titleStyle = builder.getTitleStyle();
+        this.tooltip = builder.getTooltip();
+        this.tooltipStyle = builder.getTooltipStyle();
+        this.useWhen = builder.getUseWhen();
+        this.widgetAreaStyle = builder.getWidgetAreaStyle();
+        this.widgetStyle = builder.getWidgetStyle();
+    }
+
+    public FlexibleStringExpander getAction() {
+        return action;
+    }
+
+    public String getAction(Map<String, ? extends Object> context) {
+        if (UtilValidate.isNotEmpty(this.action))
+            return action.expandString(context);
+        return null;
     }
 
     /**
@@ -617,22 +207,35 @@
         return this.name;
     }
 
+    public String getCurrentContainerId(Map<String, Object> context) {
+        ModelForm modelForm = this.getModelForm();
+        String idName = FlexibleStringExpander.expandString(this.getIdName(), context);
+
+        if (modelForm != null) {
+            Integer itemIndex = (Integer) context.get("itemIndex");
+            if ("list".equals(modelForm.getType()) || "multi".equals(modelForm.getType())) {
+                if (itemIndex != null) {
+                    return idName + modelForm.getItemIndexSeparator() + itemIndex.intValue();
+                }
+            }
+        }
+        return idName;
+    }
+
+    public boolean getEncodeOutput() {
+        return this.encodeOutput;
+    }
+
     public String getEntityName() {
         if (UtilValidate.isNotEmpty(this.entityName))
             return this.entityName;
         return this.modelForm.getDefaultEntityName();
     }
 
-    public String getEntryName() {
-        if (UtilValidate.isNotEmpty(this.entryAcsr))
-            return this.entryAcsr.getOriginalName();
-        return this.name;
-    }
-
     /**
      * Gets the entry from the context that corresponds to this field; if this
      * form is being rendered in an error condition (ie isError in the context
-     * is true) then the value will be retreived from the parameters Map in
+     * is true) then the value will be retrieved from the parameters Map in
      * the context.
      *
      * @param context the context
@@ -741,13 +344,58 @@
         }
 
         if (this.getEncodeOutput() && returnValue != null) {
-            StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
+            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
             if (simpleEncoder != null)
                 returnValue = simpleEncoder.encode(returnValue);
         }
         return returnValue;
     }
 
+    public FlexibleMapAccessor<Object> getEntryAcsr() {
+        return entryAcsr;
+    }
+
+    public String getEntryName() {
+        if (UtilValidate.isNotEmpty(this.entryAcsr))
+            return this.entryAcsr.getOriginalName();
+        return this.name;
+    }
+
+    public String getEvent() {
+        return event;
+    }
+
+    public FieldInfo getFieldInfo() {
+        return fieldInfo;
+    }
+
+    /**
+     * Gets the name of the Entity Field that corresponds
+     * with this field. This can be used to get additional information about the field.
+     * Use the getEntityName() method to get the Entity name that the field is in.
+     *
+     * @return return the name of the Entity Field that corresponds with this field
+     */
+    public String getFieldName() {
+        if (UtilValidate.isNotEmpty(this.fieldName))
+            return this.fieldName;
+        return this.name;
+    }
+
+    public String getHeaderLink() {
+        return headerLink;
+    }
+
+    public String getHeaderLinkStyle() {
+        return headerLinkStyle;
+    }
+
+    public String getIdName() {
+        if (UtilValidate.isNotEmpty(idName))
+            return idName;
+        return this.modelForm.getName() + "_" + this.getFieldName();
+    }
+
     public Map<String, ? extends Object> getMap(Map<String, ? extends Object> context) {
         if (UtilValidate.isEmpty(this.mapAcsr))
             return this.modelForm.getDefaultMap(context); //Debug.logInfo("Getting Map from default of the form because of no mapAcsr for field " + this.getName(), module);
@@ -765,17 +413,8 @@
         return result;
     }
 
-    /**
-     * Gets the name of the Entity Field that corresponds
-     * with this field. This can be used to get additional information about the field.
-     * Use the getEntityName() method to get the Entity name that the field is in.
-     *
-     * @return return the name of the Entity Field that corresponds with this field
-     */
-    public String getFieldName() {
-        if (UtilValidate.isNotEmpty(this.fieldName))
-            return this.fieldName;
-        return this.name;
+    public FlexibleMapAccessor<Map<String, ? extends Object>> getMapAcsr() {
+        return mapAcsr;
     }
 
     /** Get the name of the Map in the form context that contains the entry,
@@ -792,10 +431,26 @@
         return this.modelForm.getDefaultMapName();
     }
 
+    public ModelForm getModelForm() {
+        return modelForm;
+    }
+
     public String getName() {
         return name;
     }
 
+    public List<UpdateArea> getOnChangeUpdateAreas() {
+        return onChangeUpdateAreas;
+    }
+
+    public List<UpdateArea> getOnClickUpdateAreas() {
+        return onClickUpdateAreas;
+    }
+
+    public String getParameterName() {
+        return parameterName;
+    }
+
     /**
      * Get the name to use for the parameter for this field in the form interpreter.
      * For HTML forms this is the request parameter name.
@@ -827,14 +482,190 @@
         return redWhen;
     }
 
-    public String getEvent() {
-        return event;
+    public boolean getRequiredField() {
+        return this.requiredField != null ? this.requiredField : false;
     }
 
-    public String getAction(Map<String, ? extends Object> context) {
-        if (UtilValidate.isNotEmpty(this.action))
-            return action.expandString(context);
-        return null;
+    public String getRequiredFieldStyle() {
+        if (UtilValidate.isNotEmpty(this.requiredFieldStyle))
+            return this.requiredFieldStyle;
+        return this.modelForm.getDefaultRequiredFieldStyle();
+    }
+
+    public boolean getSeparateColumn() {
+        return this.separateColumn;
+    }
+
+    public String getServiceName() {
+        if (UtilValidate.isNotEmpty(this.serviceName))
+            return this.serviceName;
+        return this.modelForm.getDefaultServiceName();
+    }
+
+    public Boolean getSortField() {
+        return sortField;
+    }
+
+    public String getSortFieldAscStyle() {
+        return sortFieldAscStyle;
+    }
+
+    public String getSortFieldDescStyle() {
+        return sortFieldDescStyle;
+    }
+
+    public String getSortFieldHelpText() {
+        return sortFieldHelpText;
+    }
+
+    public String getSortFieldHelpText(Map<String, Object> context) {
+        return FlexibleStringExpander.expandString(this.sortFieldHelpText, context);
+    }
+
+    public String getSortFieldStyle() {
+        if (UtilValidate.isNotEmpty(this.sortFieldStyle))
+            return this.sortFieldStyle;
+        return this.modelForm.getDefaultSortFieldStyle();
+    }
+
+    public String getSortFieldStyleAsc() {
+        if (UtilValidate.isNotEmpty(this.sortFieldAscStyle))
+            return this.sortFieldAscStyle;
+        return this.modelForm.getDefaultSortFieldAscStyle();
+    }
+
+    public String getSortFieldStyleDesc() {
+        if (UtilValidate.isNotEmpty(this.sortFieldDescStyle))
+            return this.sortFieldDescStyle;
+        return this.modelForm.getDefaultSortFieldDescStyle();
+    }
+
+    public FlexibleStringExpander getTitle() {
+        return title;
+    }
+
+    public String getTitle(Map<String, Object> context) {
+        if (UtilValidate.isNotEmpty(this.title))
+            return title.expandString(context);
+
+        // create a title from the name of this field; expecting a Java method/field style name, ie productName or productCategoryId
+        if (UtilValidate.isEmpty(this.name))
+            return ""; // this should never happen, ie name is required
+
+        // search for a localized label for the field's name
+        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
+        if (uiLabelMap != null) {
+            String titleFieldName = "FormFieldTitle_" + this.name;
+            String localizedName = uiLabelMap.get(titleFieldName);
+            if (!localizedName.equals(titleFieldName)) {
+                return localizedName;
+            }
+        } else {
+            Debug.logWarning("Could not find uiLabelMap in context while rendering form " + this.modelForm.getName(), module);
+        }
+
+        // create a title from the name of this field; expecting a Java method/field style name, ie productName or productCategoryId
+        StringBuilder autoTitlewriter = new StringBuilder();
+
+        // always use upper case first letter...
+        autoTitlewriter.append(Character.toUpperCase(this.name.charAt(0)));
+
+        // just put spaces before the upper case letters
+        for (int i = 1; i < this.name.length(); i++) {
+            char curChar = this.name.charAt(i);
+            if (Character.isUpperCase(curChar)) {
+                autoTitlewriter.append(' ');
+            }
+            autoTitlewriter.append(curChar);
+        }
+
+        return autoTitlewriter.toString();
+    }
+
+    public String getTitleAreaStyle() {
+        if (UtilValidate.isNotEmpty(this.titleAreaStyle))
+            return this.titleAreaStyle;
+        return this.modelForm.getDefaultTitleAreaStyle();
+    }
+
+    public String getTitleStyle() {
+        if (UtilValidate.isNotEmpty(this.titleStyle))
+            return this.titleStyle;
+        return this.modelForm.getDefaultTitleStyle();
+    }
+
+    public FlexibleStringExpander getTooltip() {
+        return tooltip;
+    }
+
+    public String getTooltip(Map<String, Object> context) {
+        String tooltipString = "";
+        if (UtilValidate.isNotEmpty(tooltip))
+            tooltipString = tooltip.expandString(context);
+        if (this.getEncodeOutput()) {
+            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+            if (simpleEncoder != null)
+                tooltipString = simpleEncoder.encode(tooltipString);
+        }
+        return tooltipString;
+    }
+
+    public String getTooltipStyle() {
+        if (UtilValidate.isNotEmpty(this.tooltipStyle))
+            return this.tooltipStyle;
+        return this.modelForm.getDefaultTooltipStyle();
+    }
+
+    public FlexibleStringExpander getUseWhen() {
+        return useWhen;
+    }
+
+    public String getUseWhen(Map<String, Object> context) {
+        if (UtilValidate.isNotEmpty(this.useWhen))
+            return this.useWhen.expandString(context);
+        return "";
+    }
+
+    public String getWidgetAreaStyle() {
+        if (UtilValidate.isNotEmpty(this.widgetAreaStyle))
+            return this.widgetAreaStyle;
+        return this.modelForm.getDefaultWidgetAreaStyle();
+    }
+
+    public String getWidgetStyle() {
+        if (UtilValidate.isNotEmpty(this.widgetStyle))
+            return this.widgetStyle;
+        return this.modelForm.getDefaultWidgetStyle();
+    }
+
+    /**
+     * Checks if field is a row submit field.
+     */
+    public boolean isRowSubmit() {
+        if (!"multi".equals(getModelForm().getType()))
+            return false;
+        if (getFieldInfo().getFieldType() != FieldInfo.CHECK)
+            return false;
+        if (!CheckField.ROW_SUBMIT_FIELD_NAME.equals(getName()))
+            return false;
+        return true;
+    }
+
+    public boolean isSortField() {
+        return this.sortField != null && this.sortField.booleanValue();
+    }
+
+    public boolean isUseWhenEmpty() {
+        if (this.useWhen == null) {
+            return true;
+        }
+
+        return this.useWhen.isEmpty();
+    }
+
+    public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+            throws IOException {
+        this.fieldInfo.renderFieldString(writer, context, formStringRenderer);
     }
 
     /**
@@ -952,152 +783,6 @@
         return false;
     }
 
-    public String getServiceName() {
-        if (UtilValidate.isNotEmpty(this.serviceName))
-            return this.serviceName;
-        return this.modelForm.getDefaultServiceName();
-    }
-
-    public String getTitle(Map<String, Object> context) {
-        if (UtilValidate.isNotEmpty(this.title))
-            return title.expandString(context);
-
-        // create a title from the name of this field; expecting a Java method/field style name, ie productName or productCategoryId
-        if (UtilValidate.isEmpty(this.name))
-            return ""; // this should never happen, ie name is required
-
-        // search for a localized label for the field's name
-        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
-        if (uiLabelMap != null) {
-            String titleFieldName = "FormFieldTitle_" + this.name;
-            String localizedName = uiLabelMap.get(titleFieldName);
-            if (!localizedName.equals(titleFieldName)) {
-                return localizedName;
-            }
-        } else {
-            Debug.logWarning("Could not find uiLabelMap in context while rendering form " + this.modelForm.getName(), module);
-        }
-
-        // create a title from the name of this field; expecting a Java method/field style name, ie productName or productCategoryId
-        StringBuilder autoTitlewriter = new StringBuilder();
-
-        // always use upper case first letter...
-        autoTitlewriter.append(Character.toUpperCase(this.name.charAt(0)));
-
-        // just put spaces before the upper case letters
-        for (int i = 1; i < this.name.length(); i++) {
-            char curChar = this.name.charAt(i);
-            if (Character.isUpperCase(curChar)) {
-                autoTitlewriter.append(' ');
-            }
-            autoTitlewriter.append(curChar);
-        }
-
-        return autoTitlewriter.toString();
-    }
-
-    public String getTitleAreaStyle() {
-        if (UtilValidate.isNotEmpty(this.titleAreaStyle))
-            return this.titleAreaStyle;
-        return this.modelForm.getDefaultTitleAreaStyle();
-    }
-
-    public String getTitleStyle() {
-        if (UtilValidate.isNotEmpty(this.titleStyle))
-            return this.titleStyle;
-        return this.modelForm.getDefaultTitleStyle();
-    }
-
-    public String getRequiredFieldStyle() {
-        if (UtilValidate.isNotEmpty(this.requiredFieldStyle))
-            return this.requiredFieldStyle;
-        return this.modelForm.getDefaultRequiredFieldStyle();
-    }
-
-    public String getSortFieldStyle() {
-        if (UtilValidate.isNotEmpty(this.sortFieldStyle))
-            return this.sortFieldStyle;
-        return this.modelForm.getDefaultSortFieldStyle();
-    }
-
-    public String getSortFieldStyleAsc() {
-        if (UtilValidate.isNotEmpty(this.sortFieldAscStyle))
-            return this.sortFieldAscStyle;
-        return this.modelForm.getDefaultSortFieldAscStyle();
-    }
-
-    public String getSortFieldStyleDesc() {
-        if (UtilValidate.isNotEmpty(this.sortFieldDescStyle))
-            return this.sortFieldDescStyle;
-        return this.modelForm.getDefaultSortFieldDescStyle();
-    }
-
-    public String getTooltip(Map<String, Object> context) {
-        String tooltipString = "";
-        if (UtilValidate.isNotEmpty(tooltip))
-            tooltipString = tooltip.expandString(context);
-        if (this.getEncodeOutput()) {
-            StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
-            if (simpleEncoder != null)
-                tooltipString = simpleEncoder.encode(tooltipString);
-        }
-        return tooltipString;
-    }
-
-    public String getUseWhen(Map<String, Object> context) {
-        if (UtilValidate.isNotEmpty(this.useWhen))
-            return this.useWhen.expandString(context);
-        return "";
-    }
-
-    public boolean getEncodeOutput() {
-        return this.encodeOutput;
-    }
-
-    public String getIdName() {
-        if (UtilValidate.isNotEmpty(idName))
-            return idName;
-        return this.modelForm.getName() + "_" + this.getFieldName();
-    }
-
-    public String getCurrentContainerId(Map<String, Object> context) {
-        ModelForm modelForm = this.getModelForm();
-        String idName = FlexibleStringExpander.expandString(this.getIdName(), context);
-
-        if (modelForm != null) {
-            Integer itemIndex = (Integer) context.get("itemIndex");
-            if ("list".equals(modelForm.getType()) || "multi".equals(modelForm.getType())) {
-                if (itemIndex != null) {
-                    return idName + modelForm.getItemIndexSeparator() + itemIndex.intValue();
-                }
-            }
-        }
-        return idName;
-    }
-
-    public String getHeaderLink() {
-        return headerLink;
-    }
-
-    public String getHeaderLinkStyle() {
-        return headerLinkStyle;
-    }
-
-    /**
-     * @param string
-     */
-    public void setIdName(String string) {
-        idName = string;
-    }
-
-    public boolean isUseWhenEmpty() {
-        if (this.useWhen == null) {
-            return true;
-        }
-
-        return this.useWhen.isEmpty();
-    }
-
     public boolean shouldUse(Map<String, Object> context) {
         String useWhenStr = this.getUseWhen(context);
         if (UtilValidate.isEmpty(useWhenStr))
@@ -1128,455 +813,455 @@
     }
 
     /**
-     * Checks if field is a row submit field.
+     * Models the &lt;auto-complete&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
      */
-    public boolean isRowSubmit() {
-        if (!"multi".equals(getModelForm().getType()))
-            return false;
-        if (getFieldInfo().getFieldType() != FieldInfo.CHECK)
-            return false;
-        if (!CheckField.ROW_SUBMIT_FIELD_NAME.equals(getName()))
-            return false;
-        return true;
-    }
+    public static class AutoComplete {
+        private final String autoSelect;
+        private final String choices;
+        private final String frequency;
+        private final String fullSearch;
+        private final String ignoreCase;
+        private final String minChars;
+        private final String partialChars;
+        private final String partialSearch;
 
-    public String getWidgetAreaStyle() {
-        if (UtilValidate.isNotEmpty(this.widgetAreaStyle))
-            return this.widgetAreaStyle;
-        return this.modelForm.getDefaultWidgetAreaStyle();
-    }
+        public AutoComplete(Element element) {
+            this.autoSelect = element.getAttribute("auto-select");
+            this.frequency = element.getAttribute("frequency");
+            this.minChars = element.getAttribute("min-chars");
+            this.choices = element.getAttribute("choices");
+            this.partialSearch = element.getAttribute("partial-search");
+            this.partialChars = element.getAttribute("partial-chars");
+            this.ignoreCase = element.getAttribute("ignore-case");
+            this.fullSearch = element.getAttribute("full-search");
+        }
 
-    public String getWidgetStyle() {
-        if (UtilValidate.isNotEmpty(this.widgetStyle))
-            return this.widgetStyle;
-        return this.modelForm.getDefaultWidgetStyle();
-    }
+        public String getAutoSelect() {
+            return this.autoSelect;
+        }
 
-    public String getTooltipStyle() {
-        if (UtilValidate.isNotEmpty(this.tooltipStyle))
-            return this.tooltipStyle;
-        return this.modelForm.getDefaultTooltipStyle();
+        public String getChoices() {
+            return this.choices;
+        }
+
+        public String getFrequency() {
+            return this.frequency;
+        }
+
+        public String getFullSearch() {
+            return this.fullSearch;
+        }
+
+        public String getIgnoreCase() {
+            return this.ignoreCase;
+        }
+
+        public String getMinChars() {
+            return this.minChars;
+        }
+
+        public String getPartialChars() {
+            return this.partialChars;
+        }
+
+        public String getPartialSearch() {
+            return this.partialSearch;
+        }
     }
 
     /**
-     * @param string
+     * Models the &lt;check&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
      */
-    public void setAttributeName(String string) {
-        attributeName = string;
+    public static class CheckField extends FieldInfoWithOptions {
+        public final static String ROW_SUBMIT_FIELD_NAME = "_rowSubmit";
+        private final FlexibleStringExpander allChecked;
+
+        private CheckField(CheckField original, ModelFormField modelFormField) {
+            super(original, modelFormField);
+            this.allChecked = original.allChecked;
+        }
+
+        public CheckField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+            allChecked = FlexibleStringExpander.getInstance(element.getAttribute("all-checked"));
+        }
+
+        public CheckField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, FieldInfo.CHECK, modelFormField);
+            this.allChecked = FlexibleStringExpander.getInstance("");
+        }
+
+        public CheckField(ModelFormField modelFormField) {
+            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.CHECK, modelFormField);
+            this.allChecked = FlexibleStringExpander.getInstance("");
+        }
+
+        @Override
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new CheckField(this, modelFormField);
+        }
+
+        public FlexibleStringExpander getAllChecked() {
+            return allChecked;
+        }
+
+        public Boolean isAllChecked(Map<String, Object> context) {
+            String allCheckedStr = this.allChecked.expandString(context);
+            if (!allCheckedStr.isEmpty())
+                return Boolean.valueOf("true".equals(allCheckedStr));
+            else
+                return null;
+        }
+
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderCheckField(writer, context, this);
+        }
     }
 
     /**
-     * @param string
+     * Models the &lt;container&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
      */
-    public void setEntityName(String string) {
-        entityName = string;
-    }
+    public static class ContainerField extends FieldInfo {
 
-    /**
-     * @param string
-     */
-    public void setEntryName(String string) {
-        entryAcsr = FlexibleMapAccessor.getInstance(string);
-    }
+        private ContainerField(ContainerField original, ModelFormField modelFormField) {
+            super(original.getFieldSource(), original.getFieldType(), modelFormField);
+        }
 
-    /**
-     * @param string
-     */
-    public void setFieldName(String string) {
-        fieldName = string;
-    }
+        public ContainerField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+        }
 
-    /**
-     * @param string
-     */
-    public void setMapName(String string) {
-        this.mapAcsr = FlexibleMapAccessor.getInstance(string);
-    }
-
-    /**
-     * @param string
-     */
-    public void setName(String string) {
-        name = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setParameterName(String string) {
-        parameterName = string;
-    }
-
-    /**
-     * @param i
-     */
-    public void setPosition(int i) {
-        position = Integer.valueOf(i);
-    }
-
-    /**
-     * @param string
-     */
-    public void setRedWhen(String string) {
-        redWhen = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setEvent(String string) {
-        event = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setAction(String string) {
-        this.action = FlexibleStringExpander.getInstance(string);
-    }
-
-    /**
-     * @param string
-     */
-    public void setServiceName(String string) {
-        serviceName = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setTitle(String string) {
-        this.title = FlexibleStringExpander.getInstance(string);
-    }
-
-    /**
-     * @param string
-     */
-    public void setTitleAreaStyle(String string) {
-        this.titleAreaStyle = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setTitleStyle(String string) {
-        this.titleStyle = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setTooltip(String string) {
-        this.tooltip = FlexibleStringExpander.getInstance(string);
-    }
-
-    /**
-     * @param string
-     */
-    public void setUseWhen(String string) {
-        this.useWhen = FlexibleStringExpander.getInstance(string);
-    }
-
-    public void setEncodeOutput(boolean encodeOutput) {
-        this.encodeOutput = encodeOutput;
-    }
-
-    /**
-     * @param string
-     */
-    public void setWidgetAreaStyle(String string) {
-        this.widgetAreaStyle = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setWidgetStyle(String string) {
-        this.widgetStyle = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setTooltipStyle(String string) {
-        this.tooltipStyle = string;
-    }
-
-    public boolean getSeparateColumn() {
-        return this.separateColumn;
-    }
-
-    /**
-     * @param string
-     */
-    public void setHeaderLink(String string) {
-        this.headerLink = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setHeaderLinkStyle(String string) {
-        this.headerLinkStyle = string;
-    }
-
-    public boolean getRequiredField() {
-        return this.requiredField != null ? this.requiredField : false;
-    }
-
-    /**
-     * @param required the field is required 
-     */
-    public void setRequiredField(boolean required) {
-        this.requiredField = required;
-    }
-
-    public String getSortFieldHelpText(Map<String, Object> context) {
-        return FlexibleStringExpander.expandString(this.sortFieldHelpText, context);
-    }
-
-    public boolean isSortField() {
-        return this.sortField != null && this.sortField.booleanValue();
-    }
-
-    /**
-     * @param sort set as sort field
-     */
-    public void setSortField(boolean sort) {
-        this.sortField = Boolean.valueOf(sort);
-    }
-
-    /**
-     * @param modelForm the model form
-     */
-    public void setModelForm(ModelForm modelForm) {
-        this.modelForm = modelForm;
-    }
-
-    public static abstract class FieldInfoWithOptions extends FieldInfo {
-
-        protected FlexibleStringExpander noCurrentSelectedKey = null;
-        protected List<OptionSource> optionSources = new LinkedList<OptionSource>();
-
-        public FieldInfoWithOptions(int fieldSource, int fieldType, ModelFormField modelFormField) {
+        public ContainerField(int fieldSource, int fieldType, ModelFormField modelFormField) {
             super(fieldSource, fieldType, modelFormField);
         }
 
-        // Copy constructor.
-        protected FieldInfoWithOptions(FieldInfoWithOptions original, ModelFormField modelFormField) {
-            super(original.getFieldSource(), original.getFieldType(), modelFormField);
-            this.noCurrentSelectedKey = original.noCurrentSelectedKey;
-            this.optionSources.addAll(original.optionSources);
+        @Override
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
         }
 
-        public FieldInfoWithOptions(Element element, ModelFormField modelFormField) {
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new ContainerField(this, modelFormField);
+        }
+
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderContainerFindField(writer, context, this);
+        }
+    }
+
+    /**
+     * Models the &lt;date-find&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class DateFindField extends DateTimeField {
+        private final String defaultOptionFrom;
+        private final String defaultOptionThru;
+
+        private DateFindField(DateFindField original, ModelFormField modelFormField) {
+            super(original, modelFormField);
+            this.defaultOptionFrom = original.defaultOptionFrom;
+            this.defaultOptionThru = original.defaultOptionThru;
+        }
+
+        public DateFindField(Element element, ModelFormField modelFormField) {
             super(element, modelFormField);
+            this.defaultOptionFrom = element.getAttribute("default-option-from");
+            this.defaultOptionThru = element.getAttribute("default-option-thru");
+        }
 
-            noCurrentSelectedKey = FlexibleStringExpander.getInstance(element.getAttribute("no-current-selected-key"));
+        public DateFindField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, modelFormField);
+            this.defaultOptionFrom = "greaterThanEqualTo";
+            this.defaultOptionThru = "lessThanEqualTo";
+        }
 
-            // read all option and entity-options sub-elements, maintaining order
-            List<? extends Element> childElements = UtilXml.childElementList(element);
-            if (childElements.size() > 0) {
-                for (Element childElement : childElements) {
-                    if ("option".equals(childElement.getTagName())) {
-                        this.addOptionSource(new SingleOption(childElement, this));
-                    } else if ("list-options".equals(childElement.getTagName())) {
-                        this.addOptionSource(new ListOptions(childElement, this));
-                    } else if ("entity-options".equals(childElement.getTagName())) {
-                        this.addOptionSource(new EntityOptions(childElement, this));
-                    }
-                }
+        public DateFindField(int fieldSource, String type) {
+            super(fieldSource, type);
+            this.defaultOptionFrom = "greaterThanEqualTo";
+            this.defaultOptionThru = "lessThanEqualTo";
+        }
+
+        @Override
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new DateFindField(this, modelFormField);
+        }
+
+        public String getDefaultOptionFrom() {
+            return this.defaultOptionFrom;
+        }
+
+        public String getDefaultOptionThru() {
+            return this.defaultOptionThru;
+        }
+
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderDateFindField(writer, context, this);
+        }
+    }
+
+    /**
+     * Models the &lt;date-time&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class DateTimeField extends FieldInfo {
+        private final String clock;
+        private final FlexibleStringExpander defaultValue;
+        private final String inputMethod;
+        private final String mask;
+        private final String step;
+        private final String type;
+
+        protected DateTimeField(DateTimeField original, ModelFormField modelFormField) {
+            super(original.getFieldSource(), original.getFieldType(), modelFormField);
+            this.defaultValue = original.defaultValue;
+            this.type = original.type;
+            this.inputMethod = original.inputMethod;
+            this.clock = original.clock;
+            this.mask = original.mask;
+            this.step = original.step;
+        }
+
+        public DateTimeField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+            this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value"));
+            this.type = element.getAttribute("type");
+            this.inputMethod = element.getAttribute("input-method");
+            this.clock = element.getAttribute("clock");
+            this.mask = element.getAttribute("mask");
+            String step = element.getAttribute("step");
+            if (step.isEmpty()) {
+                step = "1";
+            }
+            this.step = step;
+        }
+
+        public DateTimeField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, FieldInfo.DATE_TIME, modelFormField);
+            this.defaultValue = FlexibleStringExpander.getInstance("");
+            this.type = "";
+            this.inputMethod = "";
+            this.clock = "";
+            this.mask = "";
+            this.step = "1";
+        }
+
+        public DateTimeField(int fieldSource, String type) {
+            super(fieldSource, FieldInfo.DATE_TIME, null);
+            this.defaultValue = FlexibleStringExpander.getInstance("");
+            this.type = type;
+            this.inputMethod = "";
+            this.clock = "";
+            this.mask = "";
+            this.step = "1";
+        }
+
+        public DateTimeField(ModelFormField modelFormField) {
+            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DATE_TIME, modelFormField);
+            this.defaultValue = FlexibleStringExpander.getInstance("");
+            this.type = "";
+            this.inputMethod = "";
+            this.clock = "";
+            this.mask = "";
+            this.step = "1";
+        }
+
+        @Override
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new DateTimeField(this, modelFormField);
+        }
+
+        public String getClock() {
+            return this.clock;
+        }
+
+        /**
+         * Returns the default-value if specified, otherwise the current date, time or timestamp
+         *
+         * @param context Context Map
+         * @return Default value string for date-time
+         */
+        public String getDefaultDateTimeString(Map<String, Object> context) {
+            if (UtilValidate.isNotEmpty(this.defaultValue))
+                return this.getDefaultValue(context);
+
+            if ("date".equals(this.type))
+                return (new java.sql.Date(System.currentTimeMillis())).toString();
+            else if ("time".equals(this.type))
+                return (new java.sql.Time(System.currentTimeMillis())).toString();
+            else
+                return UtilDateTime.nowTimestamp().toString();
+        }
+
+        public FlexibleStringExpander getDefaultValue() {
+            return defaultValue;
+        }
+
+        public String getDefaultValue(Map<String, Object> context) {
+            if (this.defaultValue != null) {
+                return this.defaultValue.expandString(context);
             } else {
-                // this must be added or the multi-form select box options would not show up
-                this.addOptionSource(new SingleOption("Y", " ", this));
-            }
-        }
-
-        public List<OptionSource> getOptionSources() {
-            return optionSources;
-        }
-
-        public List<OptionValue> getAllOptionValues(Map<String, Object> context, Delegator delegator) {
-            List<OptionValue> optionValues = new LinkedList<OptionValue>();
-            for (OptionSource optionSource : this.optionSources) {
-                optionSource.addOptionValues(optionValues, context, delegator);
-            }
-            return optionValues;
-        }
-
-        public static String getDescriptionForOptionKey(String key, List<OptionValue> allOptionValues) {
-            if (UtilValidate.isEmpty(key))
                 return "";
-
-            if (UtilValidate.isEmpty(allOptionValues))
-                return key;
-
-            for (OptionValue optionValue : allOptionValues) {
-                if (key.equals(optionValue.getKey())) {
-                    return optionValue.getDescription();
-                }
             }
-
-            // if we get here we didn't find a match, just return the key
-            return key;
         }
 
-        public String getNoCurrentSelectedKey(Map<String, Object> context) {
-            if (this.noCurrentSelectedKey == null) {
-                return null;
-            }
-            return this.noCurrentSelectedKey.expandString(context);
+        public String getInputMethod() {
+            return this.inputMethod;
         }
 
-        public void setNoCurrentSelectedKey(String string) {
-            this.noCurrentSelectedKey = FlexibleStringExpander.getInstance(string);
+        public String getMask() {
+            return this.mask;
         }
 
-        public void addOptionSource(OptionSource optionSource) {
-            this.optionSources.add(optionSource);
-        }
-    }
-
-    public static class OptionValue {
-        protected String key;
-        protected String description;
-
-        public OptionValue(String key, String description) {
-            this.key = key;
-            this.description = description;
+        public String getStep() {
+            return this.step;
         }
 
-        public String getKey() {
-            return key;
-        }
-
-        public String getDescription() {
-            return description;
-        }
-    }
-
-    public static abstract class OptionSource {
-        protected FieldInfo fieldInfo;
-
-        public abstract void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator);
-    }
-
-    public static class SingleOption extends OptionSource {
-        protected FlexibleStringExpander key;
-        protected FlexibleStringExpander description;
-
-        public SingleOption(String key, String description, FieldInfo fieldInfo) {
-            this.key = FlexibleStringExpander.getInstance(key);
-            this.description = FlexibleStringExpander.getInstance(UtilXml.checkEmpty(description, key));
-            this.fieldInfo = fieldInfo;
-        }
-
-        public SingleOption(Element optionElement, FieldInfo fieldInfo) {
-            this.key = FlexibleStringExpander.getInstance(optionElement.getAttribute("key"));
-            this.description = FlexibleStringExpander.getInstance(UtilXml.checkEmpty(optionElement.getAttribute("description"),
-                    optionElement.getAttribute("key")));
-            this.fieldInfo = fieldInfo;
+        public String getType() {
+            return type;
         }
 
         @Override
-        public void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator) {
-            optionValues.add(new OptionValue(key.expandString(context), description.expandString(context)));
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderDateTimeField(writer, context, this);
         }
     }
 
-    public static class ListOptions extends OptionSource {
-        protected FlexibleMapAccessor<List<? extends Object>> listAcsr;
-        protected String listEntryName;
-        protected FlexibleMapAccessor<Object> keyAcsr;
-        protected FlexibleStringExpander description;
+    /**
+     * Models the &lt;display-entity&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class DisplayEntityField extends DisplayField {
+        private final boolean cache;
+        private final String entityName;
+        private final String keyFieldName;
+        private final SubHyperlink subHyperlink;
 
-        public ListOptions(String listName, String listEntryName, String keyName, String description, FieldInfo fieldInfo) {
-            this.listAcsr = FlexibleMapAccessor.getInstance(listName);
-            this.listEntryName = listEntryName;
-            this.keyAcsr = FlexibleMapAccessor.getInstance(keyName);
-            this.description = FlexibleStringExpander.getInstance(description);
-            this.fieldInfo = fieldInfo;
+        private DisplayEntityField(DisplayEntityField original, ModelFormField modelFormField) {
+            super(original, modelFormField);
+            this.cache = original.cache;
+            this.entityName = original.entityName;
+            this.keyFieldName = original.keyFieldName;
+            if (original.subHyperlink != null) {
+                this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField);
+            } else {
+                this.subHyperlink = null;
+            }
         }
 
-        public ListOptions(Element optionElement, FieldInfo fieldInfo) {
-            this.listEntryName = optionElement.getAttribute("list-entry-name");
-            this.keyAcsr = FlexibleMapAccessor.getInstance(optionElement.getAttribute("key-name"));
-            this.listAcsr = FlexibleMapAccessor.getInstance(optionElement.getAttribute("list-name"));
-            this.listEntryName = optionElement.getAttribute("list-entry-name");
-            this.description = FlexibleStringExpander.getInstance(optionElement.getAttribute("description"));
-            this.fieldInfo = fieldInfo;
+        public DisplayEntityField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+            this.cache = !"false".equals(element.getAttribute("cache"));
+            this.entityName = element.getAttribute("entity-name");
+            this.keyFieldName = element.getAttribute("key-field-name");
+            Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink");
+            if (subHyperlinkElement != null) {
+                this.subHyperlink = new SubHyperlink(subHyperlinkElement, modelFormField);
+            } else {
+                this.subHyperlink = null;
+            }
+        }
+
+        public DisplayEntityField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, FieldInfo.DISPLAY_ENTITY, modelFormField);
+            this.cache = true;
+            this.entityName = "";
+            this.keyFieldName = "";
+            this.subHyperlink = null;
+        }
+
+        public DisplayEntityField(ModelFormField modelFormField) {
+            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DISPLAY_ENTITY, modelFormField);
+            this.cache = true;
+            this.entityName = "";
+            this.keyFieldName = "";
+            this.subHyperlink = null;
         }
 
         @Override
-        public void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator) {
-            List<? extends Object> dataList = UtilGenerics.checkList(this.listAcsr.get(context));
-            if (dataList != null && dataList.size() != 0) {
-                for (Object data : dataList) {
-                    Map<String, Object> localContext = new HashMap<String, Object>();
-                    localContext.putAll(context);
-                    if (UtilValidate.isNotEmpty(this.listEntryName)) {
-                        localContext.put(this.listEntryName, data);
-                    } else {
-                        Map<String, Object> dataMap = UtilGenerics.checkMap(data);
-                        localContext.putAll(dataMap);
-                    }
-                    Object keyObj = keyAcsr.get(localContext);
-                    String key = null;
-                    if (keyObj instanceof String) {
-                        key = (String) keyObj;
-                    } else {
-                        try {
-                            key = (String) ObjectType.simpleTypeConvert(keyObj, "String", null, null);
-                        } catch (GeneralException e) {
-                            String errMsg = "Could not convert field value for the field: [" + this.keyAcsr.toString()
-                                    + "] to String for the value [" + keyObj + "]: " + e.toString();
-                            Debug.logError(e, errMsg, module);
-                        }
-                    }
-                    optionValues.add(new OptionValue(key, description.expandString(localContext)));
-                }
-            }
-        }
-    }
-
-    public static class EntityOptions extends OptionSource {
-        protected String entityName;
-        protected String keyFieldName;
-        protected FlexibleStringExpander description;
-        protected boolean cache = true;
-        protected String filterByDate;
-
-        protected List<EntityFinderUtil.ConditionExpr> constraintList = null;
-        protected List<String> orderByList = null;
-
-        public EntityOptions(FieldInfo fieldInfo) {
-            this.fieldInfo = fieldInfo;
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
         }
 
-        public EntityOptions(Element entityOptionsElement, FieldInfo fieldInfo) {
-            this.entityName = entityOptionsElement.getAttribute("entity-name");
-            this.keyFieldName = entityOptionsElement.getAttribute("key-field-name");
-            this.description = FlexibleStringExpander.getInstance(entityOptionsElement.getAttribute("description"));
-            this.cache = !"false".equals(entityOptionsElement.getAttribute("cache"));
-            this.filterByDate = entityOptionsElement.getAttribute("filter-by-date");
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new DisplayEntityField(this, modelFormField);
+        }
 
-            List<? extends Element> constraintElements = UtilXml.childElementList(entityOptionsElement, "entity-constraint");
-            if (UtilValidate.isNotEmpty(constraintElements)) {
-                this.constraintList = new LinkedList<EntityFinderUtil.ConditionExpr>();
-                for (Element constraintElement : constraintElements) {
-                    constraintList.add(new EntityFinderUtil.ConditionExpr(constraintElement));
-                }
+        public boolean getCache() {
+            return cache;
+        }
+
+        @Override
+        public String getDescription(Map<String, Object> context) {
+            Locale locale = UtilMisc.ensureLocale(context.get("locale"));
+
+            // rather than using the context to expand the string, lookup the given entity and use it to expand the string
+            GenericValue value = null;
+            String fieldKey = this.keyFieldName;
+            if (UtilValidate.isEmpty(fieldKey))
+                fieldKey = getModelFormField().fieldName;
+
+            Delegator delegator = WidgetWorker.getDelegator(context);
+            String fieldValue = getModelFormField().getEntry(context);
+            try {
+                value = delegator.findOne(this.entityName, this.cache, fieldKey, fieldValue);
+            } catch (GenericEntityException e) {
+                String errMsg = "Error getting value from the database for display of field [" + getModelFormField().getName()
+                        + "] on form [" + getModelFormField().modelForm.getName() + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new IllegalArgumentException(errMsg);
             }
 
-            List<? extends Element> orderByElements = UtilXml.childElementList(entityOptionsElement, "entity-order-by");
-            if (UtilValidate.isNotEmpty(orderByElements)) {
-                this.orderByList = new LinkedList<String>();
-                for (Element orderByElement : orderByElements) {
-                    orderByList.add(orderByElement.getAttribute("field-name"));
-                }
-            }
+            String retVal = null;
+            if (value != null) {
+                // expanding ${} stuff, passing locale explicitly to expand value string because it won't be found in the Entity
+                MapStack<String> localContext = MapStack.create(context);
+                // Rendering code might try to modify the GenericEntity instance,
+                // so we make a copy of it.
+                Map<String, Object> genericEntityClone = UtilGenerics.cast(value.clone());
+                localContext.push(genericEntityClone);
 
-            this.fieldInfo = fieldInfo;
+                // expand with the new localContext, which is locale aware
+                retVal = this.getDescription().expandString(localContext, locale);
+            }
+            // try to get the entry for the field if description doesn't expand to anything
+            if (UtilValidate.isEmpty(retVal))
+                retVal = fieldValue;
+            if (UtilValidate.isEmpty(retVal))
+                retVal = "";
+            return retVal;
         }
 
         public String getEntityName() {
@@ -1584,419 +1269,136 @@
         }
 
         public String getKeyFieldName() {
-            if (UtilValidate.isNotEmpty(this.keyFieldName))
-                return this.keyFieldName;
-            return this.fieldInfo.getModelFormField().getFieldName(); // get the modelFormField fieldName
+            return keyFieldName;
         }
 
-        @Override
-        public void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator) {
-            // first expand any conditions that need expanding based on the current context
-            EntityCondition findCondition = null;
-            if (UtilValidate.isNotEmpty(this.constraintList)) {
-                List<EntityCondition> expandedConditionList = new LinkedList<EntityCondition>();
-                for (EntityFinderUtil.Condition condition : constraintList) {
-                    ModelEntity modelEntity = delegator.getModelEntity(this.entityName);
-                    if (modelEntity == null) {
-                        throw new IllegalArgumentException("Error in entity-options: could not find entity [" + this.entityName
-                                + "]");
-                    }
-                    EntityCondition createdCondition = condition.createCondition(context, modelEntity,
-                            delegator.getModelFieldTypeReader(modelEntity));
-                    if (createdCondition != null) {
-                        expandedConditionList.add(createdCondition);
-                    }
-                }
-                findCondition = EntityCondition.makeCondition(expandedConditionList);
-            }
-
-            try {
-                Locale locale = UtilMisc.ensureLocale(context.get("locale"));
-
-                List<GenericValue> values = null;
-                values = delegator.findList(this.entityName, findCondition, null, this.orderByList, null, this.cache);
-
-                // filter-by-date if requested
-                if ("true".equals(this.filterByDate)) {
-                    values = EntityUtil.filterByDate(values, true);
-                } else if (!"false".equals(this.filterByDate)) {
-                    // not explicitly true or false, check to see if has fromDate and thruDate, if so do the filter
-                    ModelEntity modelEntity = delegator.getModelEntity(this.entityName);
-                    if (modelEntity != null && modelEntity.isField("fromDate") && modelEntity.isField("thruDate")) {
-                        values = EntityUtil.filterByDate(values, true);
-                    }
-                }
-
-                for (GenericValue value : values) {
-                    // add key and description with string expansion, ie expanding ${} stuff, passing locale explicitly to expand value string because it won't be found in the Entity
-                    MapStack<String> localContext = MapStack.create(context);
-                    // Rendering code might try to modify the GenericEntity instance,
-                    // so we make a copy of it.
-                    Map<String, Object> genericEntityClone = UtilGenerics.cast(value.clone());
-                    localContext.push(genericEntityClone);
-
-                    // expand with the new localContext, which is locale aware
-                    String optionDesc = this.description.expandString(localContext, locale);
-
-                    Object keyFieldObject = value.get(this.getKeyFieldName());
-                    if (keyFieldObject == null) {
-                        throw new IllegalArgumentException(
-                                "The entity-options identifier (from key-name attribute, or default to the field name) ["
-                                        + this.getKeyFieldName() + "], may not be a valid key field name for the entity ["
-                                        + this.entityName + "].");
-                    }
-                    String keyFieldValue = keyFieldObject.toString();
-                    optionValues.add(new OptionValue(keyFieldValue, optionDesc));
-                }
-            } catch (GenericEntityException e) {
-                Debug.logError(e, "Error getting entity options in form", module);
-            }
+        public SubHyperlink getSubHyperlink() {
+            return this.subHyperlink;
         }
     }
 
-    public static class InPlaceEditor {
-        protected FlexibleStringExpander url;
-        protected String cancelControl;
-        protected String cancelText;
-        protected String clickToEditText;
-        protected String fieldPostCreation;
-        protected String formClassName;
-        protected String highlightColor;
-        protected String highlightEndColor;
-        protected String hoverClassName;
-        protected String htmlResponse;
-        protected String loadingClassName;
-        protected String loadingText;
-        protected String okControl;
-        protected String okText;
-        protected String paramName;
-        protected String savingClassName;
-        protected String savingText;
-        protected String submitOnBlur;
-        protected String textBeforeControls;
-        protected String textAfterControls;
-        protected String textBetweenControls;
-        protected String updateAfterRequestCall;
-        protected String rows;
-        protected String cols;
-        protected Map<FlexibleMapAccessor<Object>, Object> fieldMap;
-
-        public InPlaceEditor(Element element) {
-            this.setUrl(element.getAttribute("url"));
-            this.cancelControl = element.getAttribute("cancel-control");
-            this.cancelText = element.getAttribute("cancel-text");
-            this.clickToEditText = element.getAttribute("click-to-edit-text");
-            this.fieldPostCreation = element.getAttribute("field-post-creation");
-            this.formClassName = element.getAttribute("form-class-name");
-            this.highlightColor = element.getAttribute("highlight-color");
-            this.highlightEndColor = element.getAttribute("highlight-end-color");
-            this.hoverClassName = element.getAttribute("hover-class-name");
-            this.htmlResponse = element.getAttribute("html-response");
-            this.loadingClassName = element.getAttribute("loading-class-name");
-            this.loadingText = element.getAttribute("loading-text");
-            this.okControl = element.getAttribute("ok-control");
-            this.okText = element.getAttribute("ok-text");
-            this.paramName = element.getAttribute("param-name");
-            this.savingClassName = element.getAttribute("saving-class-name");
-            this.savingText = element.getAttribute("saving-text");
-            this.submitOnBlur = element.getAttribute("submit-on-blur");
-            this.textBeforeControls = element.getAttribute("text-before-controls");
-            this.textAfterControls = element.getAttribute("text-after-controls");
-            this.textBetweenControls = element.getAttribute("text-between-controls");
-            this.updateAfterRequestCall = element.getAttribute("update-after-request-call");
-
-            Element simpleElement = UtilXml.firstChildElement(element, "simple-editor");
-            this.rows = simpleElement.getAttribute("rows");
-            this.cols = simpleElement.getAttribute("cols");
-
-            this.fieldMap = EntityFinderUtil.makeFieldMap(element);
-        }
-
-        public String getUrl(Map<String, Object> context) {
-            if (this.url != null) {
-                return this.url.expandString(context);
-            } else {
-                return "";
-            }
-        }
-
-        public String getCancelControl() {
-            return this.cancelControl;
-        }
-
-        public String getCancelText() {
-            return this.cancelText;
-        }
-
-        public String getClickToEditText() {
-            return this.clickToEditText;
-        }
-
-        public String getFieldPostCreation() {
-            return this.fieldPostCreation;
-        }
-
-        public String getFormClassName() {
-            return this.formClassName;
-        }
-
-        public String getHighlightColor() {
-            return this.highlightColor;
-        }
-
-        public String getHighlightEndColor() {
-            return this.highlightEndColor;
-        }
-
-        public String getHoverClassName() {
-            return this.hoverClassName;
-        }
-
-        public String getHtmlResponse() {
-            return this.htmlResponse;
-        }
-
-        public String getLoadingClassName() {
-            return this.loadingClassName;
-        }
-
-        public String getLoadingText() {
-            return this.loadingText;
-        }
-
-        public String getOkControl() {
-            return this.okControl;
-        }
-
-        public String getOkText() {
-            return this.okText;
-        }
-
-        public String getParamName() {
-            return this.paramName;
-        }
-
-        public String getSavingClassName() {
-            return this.savingClassName;
-        }
-
-        public String getSavingText() {
-            return this.savingText;
-        }
-
-        public String getSubmitOnBlur() {
-            return this.submitOnBlur;
-        }
-
-        public String getTextBeforeControls() {
-            return this.textBeforeControls;
-        }
-
-        public String getTextAfterControls() {
-            return this.textAfterControls;
-        }
-
-        public String getTextBetweenControls() {
-            return this.textBetweenControls;
-        }
-
-        public String getUpdateAfterRequestCall() {
-            return this.updateAfterRequestCall;
-        }
-
-        public String getRows() {
-            return this.rows;
-        }
-
-        public String getCols() {
-            return this.cols;
-        }
-
-        public Map<String, Object> getFieldMap(Map<String, Object> context) {
-            Map<String, Object> inPlaceEditorContext = new HashMap<String, Object>();
-            EntityFinderUtil.expandFieldMapToContext(this.fieldMap, context, inPlaceEditorContext);
-            return inPlaceEditorContext;
-        }
-
-        public void setUrl(String url) {
-            this.url = FlexibleStringExpander.getInstance(url);
-        }
-
-        public void setCancelControl(String string) {
-            this.cancelControl = string;
-        }
-
-        public void setCancelText(String string) {
-            this.cancelText = string;
-        }
-
-        public void setClickToEditText(String string) {
-            this.clickToEditText = string;
-        }
-
-        public void setFieldPostCreation(String string) {
-            this.fieldPostCreation = string;
-        }
-
-        public void setFormClassName(String string) {
-            this.formClassName = string;
-        }
-
-        public void setHighlightColor(String string) {
-            this.highlightColor = string;
-        }
-
-        public void setHighlightEndColor(String string) {
-            this.highlightEndColor = string;
-        }
-
-        public void setHoverClassName(String string) {
-            this.hoverClassName = string;
-        }
-
-        public void setHtmlResponse(String string) {
-            this.htmlResponse = string;
-        }
-
-        public void setLoadingClassName(String string) {
-            this.loadingClassName = string;
-        }
-
-        public void setLoadingText(String string) {
-            this.loadingText = string;
-        }
-
-        public void setOkControl(String string) {
-            this.okControl = string;
-        }
-
-        public void setOkText(String string) {
-            this.okText = string;
-        }
-
-        public void setParamName(String string) {
-            this.paramName = string;
-        }
-
-        public void setSavingClassName(String string) {
-            this.savingClassName = string;
-        }
-
-        public void setSavingText(String string) {
-            this.savingText = string;
-        }
-
-        public void setSubmitOnBlur(String string) {
-            this.submitOnBlur = string;
-        }
-
-        public void setTextBeforeControls(String string) {
-            this.textBeforeControls = string;
-        }
-
-        public void setTextAfterControls(String string) {
-            this.textAfterControls = string;
-        }
-
-        public void setTextBetweenControls(String string) {
-            this.textBetweenControls = string;
-        }
-
-        public void setUpdateAfterRequestCall(String string) {
-            this.updateAfterRequestCall = string;
-        }
-
-        public void setRows(String string) {
-            this.rows = string;
-        }
-
-        public void setCols(String string) {
-            this.cols = string;
-        }
-
-        public void setFieldMap(Map<FlexibleMapAccessor<Object>, Object> fieldMap) {
-            this.fieldMap = fieldMap;
-        }
-    }
-
+    /**
+     * Models the &lt;display&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
     public static class DisplayField extends FieldInfo {
-        protected boolean alsoHidden = true;
-        protected FlexibleStringExpander description;
-        protected String type; // matches type of field, currently text or currency
-        protected String size; // maximum number of characters to display
-        protected FlexibleStringExpander imageLocation;
-        protected FlexibleStringExpander currency;
-        protected FlexibleStringExpander date;
-        protected InPlaceEditor inPlaceEditor;
-        protected FlexibleStringExpander defaultValue;
+        private final boolean alsoHidden;
+        private final FlexibleStringExpander currency;
+        private final FlexibleStringExpander date;
+        private final FlexibleStringExpander defaultValue;
+        private final FlexibleStringExpander description;
+        private final FlexibleStringExpander imageLocation;
+        private final InPlaceEditor inPlaceEditor;
+        private final String size; // maximum number of characters to display
+        private final String type; // matches type of field, currently text or currency
 
-        public DisplayField(ModelFormField modelFormField) {
-            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DISPLAY, modelFormField);
-        }
-
-        public DisplayField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, FieldInfo.DISPLAY, modelFormField);
-        }
-
-        public DisplayField(int fieldSource, int fieldType, ModelFormField modelFormField) {
-            super(fieldSource, fieldType, modelFormField);
+        protected DisplayField(DisplayField original, ModelFormField modelFormField) {
+            super(original.getFieldSource(), original.getFieldType(), modelFormField);
+            this.alsoHidden = original.alsoHidden;
+            this.currency = original.currency;
+            this.date = original.date;
+            this.defaultValue = original.defaultValue;
+            this.description = original.description;
+            this.imageLocation = original.imageLocation;
+            this.inPlaceEditor = original.inPlaceEditor;
+            this.size = original.size;
+            this.type = original.type;
         }
 
         public DisplayField(Element element, ModelFormField modelFormField) {
             super(element, modelFormField);
-            this.type = element.getAttribute("type");
-            this.size = element.getAttribute("size");
-            this.setImageLocation(element.getAttribute("image-location"));
-            this.setCurrency(element.getAttribute("currency"));
-            this.setDescription(element.getAttribute("description"));
-            this.setDate(element.getAttribute("date"));
             this.alsoHidden = !"false".equals(element.getAttribute("also-hidden"));
-            this.setDefaultValue(element.getAttribute("default-value"));
+            this.currency = FlexibleStringExpander.getInstance(element.getAttribute("currency"));
+            this.date = FlexibleStringExpander.getInstance(element.getAttribute("date"));
+            this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value"));
+            this.description = FlexibleStringExpander.getInstance(element.getAttribute("description"));
+            this.imageLocation = FlexibleStringExpander.getInstance(element.getAttribute("image-location"));
             Element inPlaceEditorElement = UtilXml.firstChildElement(element, "in-place-editor");
             if (inPlaceEditorElement != null) {
                 this.inPlaceEditor = new InPlaceEditor(inPlaceEditorElement);
+            } else {
+                this.inPlaceEditor = null;
             }
+            this.size = element.getAttribute("size");
+            this.type = element.getAttribute("type");
         }
 
-        protected DisplayField(DisplayField original, ModelFormField modelFormField) {
-            super(original.getFieldSource(), original.getFieldType(), modelFormField);
-            this.type = original.type;
-            this.size = original.size;
-            this.imageLocation = original.imageLocation;
-            this.currency = original.currency;
-            this.description = original.description;
-            this.date = original.date;
-            this.alsoHidden = original.alsoHidden;
-            this.defaultValue = original.defaultValue;
-            this.inPlaceEditor = original.inPlaceEditor;
+        public DisplayField(int fieldSource, int fieldType, ModelFormField modelFormField) {
+            super(fieldSource, fieldType, modelFormField);
+            this.alsoHidden = true;
+            this.currency = FlexibleStringExpander.getInstance("");
+            this.date = FlexibleStringExpander.getInstance("");
+            this.defaultValue = FlexibleStringExpander.getInstance("");
+            this.description = FlexibleStringExpander.getInstance("");
+            this.imageLocation = FlexibleStringExpander.getInstance("");
+            this.inPlaceEditor = null;
+            this.size = "";
+            this.type = "";
+        }
+
+        public DisplayField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, FieldInfo.DISPLAY, modelFormField);
+            this.alsoHidden = true;
+            this.currency = FlexibleStringExpander.getInstance("");
+            this.date = FlexibleStringExpander.getInstance("");
+            this.defaultValue = FlexibleStringExpander.getInstance("");
+            this.description = FlexibleStringExpander.getInstance("");
+            this.imageLocation = FlexibleStringExpander.getInstance("");
+            this.inPlaceEditor = null;
+            this.size = "";
+            this.type = "";
+        }
+
+        public DisplayField(ModelFormField modelFormField) {
+            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DISPLAY, modelFormField);
+            this.alsoHidden = true;
+            this.currency = FlexibleStringExpander.getInstance("");
+            this.date = FlexibleStringExpander.getInstance("");
+            this.defaultValue = FlexibleStringExpander.getInstance("");
+            this.description = FlexibleStringExpander.getInstance("");
+            this.imageLocation = FlexibleStringExpander.getInstance("");
+            this.inPlaceEditor = null;
+            this.size = "";
+            this.type = "";
         }
 
         @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderDisplayField(writer, context, this);
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new DisplayField(this, modelFormField);
         }
 
         public boolean getAlsoHidden() {
             return alsoHidden;
         }
 
-        public String getType() {
-            return this.type;
+        public FlexibleStringExpander getCurrency() {
+            return currency;
         }
 
-        public String getSize() {
-            return this.size;
+        public FlexibleStringExpander getDate() {
+            return date;
         }
 
-        public String setSize(String size) {
-            return this.size = size;
+        public FlexibleStringExpander getDefaultValue() {
+            return defaultValue;
         }
 
-        public String getImageLocation(Map<String, Object> context) {
-            if (this.imageLocation != null)
-                return this.imageLocation.expandString(context);
-            return "";
+        public String getDefaultValue(Map<String, Object> context) {
+            if (this.defaultValue != null) {
+                return this.defaultValue.expandString(context);
+            } else {
+                return "";
+            }
+        }
+
+        public FlexibleStringExpander getDescription() {
+            return description;
         }
 
         public String getDescription(Map<String, Object> context) {
@@ -2088,7 +1490,7 @@
                 }
             }
             if (UtilValidate.isNotEmpty(this.description) && retVal != null && this.getModelFormField().getEncodeOutput()) {
-                StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
+                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
                 if (simpleEncoder != null) {
                     retVal = simpleEncoder.encode(retVal);
                 }
@@ -2096,1230 +1498,146 @@
             return retVal;
         }
 
-        public InPlaceEditor getInPlaceEditor() {
-            return this.inPlaceEditor;
-        }
-
-        /**
-         * @param b the field is also hidden true/false
-         */
-        public void setAlsoHidden(boolean b) {
-            alsoHidden = b;
-        }
-
-        /**
-         * @param value the value of the image location
-         */
-        public void setImageLocation(String value) {
-            this.imageLocation = FlexibleStringExpander.getInstance(value);
-        }
-
-        /**
-         * @param string the description of the field
-         */
-        public void setDescription(String string) {
-            description = FlexibleStringExpander.getInstance(string);
-        }
-
-        /**
-         * @param string the currency of the field
-         */
-        public void setCurrency(String string) {
-            currency = FlexibleStringExpander.getInstance(string);
-        }
-
-        /**
-         * @param string the date of the field
-         */
-        public void setDate(String string) {
-            date = FlexibleStringExpander.getInstance(string);
-        }
-
-        public void setInPlaceEditor(InPlaceEditor newInPlaceEditor) {
-            this.inPlaceEditor = newInPlaceEditor;
-        }
-
-        /**
-         * @param str the default value
-         */
-        public void setDefaultValue(String str) {
-            this.defaultValue = FlexibleStringExpander.getInstance(str);
-        }
-
-        public String getDefaultValue(Map<String, Object> context) {
-            if (this.defaultValue != null) {
-                return this.defaultValue.expandString(context);
-            } else {
-                return "";
-            }
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new DisplayField(this, modelFormField);
-        }
-    }
-
-    public static class DisplayEntityField extends DisplayField {
-        protected String entityName;
-        protected String keyFieldName;
-        protected boolean cache = true;
-        protected SubHyperlink subHyperlink;
-
-        public DisplayEntityField(ModelFormField modelFormField) {
-            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DISPLAY_ENTITY, modelFormField);
-        }
-
-        public DisplayEntityField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, FieldInfo.DISPLAY_ENTITY, modelFormField);
-        }
-
-        public DisplayEntityField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-            this.entityName = element.getAttribute("entity-name");
-            this.keyFieldName = element.getAttribute("key-field-name");
-            this.cache = !"false".equals(element.getAttribute("cache"));
-            this.size = element.getAttribute("size");
-            if (UtilValidate.isEmpty(this.description))
-                this.setDescription("${description}");
-            Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink");
-            if (subHyperlinkElement != null) {
-                this.subHyperlink = new SubHyperlink(subHyperlinkElement, modelFormField);
-            }
-        }
-
-        private DisplayEntityField(DisplayEntityField original, ModelFormField modelFormField) {
-            super(original, modelFormField);
-            this.entityName = original.entityName;
-            this.keyFieldName = original.keyFieldName;
-            this.cache = original.cache;
-            this.size = original.size;
-            this.description = original.description;
-            if (original.subHyperlink != null) {
-                this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField);
-            }
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new DisplayEntityField(this, modelFormField);
-        }
-
-        @Override
-        public String getDescription(Map<String, Object> context) {
-            Locale locale = UtilMisc.ensureLocale(context.get("locale"));
-
-            // rather than using the context to expand the string, lookup the given entity and use it to expand the string
-            GenericValue value = null;
-            String fieldKey = this.keyFieldName;
-            if (UtilValidate.isEmpty(fieldKey))
-                fieldKey = getModelFormField().fieldName;
-
-            Delegator delegator = WidgetWorker.getDelegator(context);
-            String fieldValue = getModelFormField().getEntry(context);
-            try {
-                value = delegator.findOne(this.entityName, this.cache, fieldKey, fieldValue);
-            } catch (GenericEntityException e) {
-                String errMsg = "Error getting value from the database for display of field [" + getModelFormField().getName()
-                        + "] on form [" + getModelFormField().modelForm.getName() + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-
-            String retVal = null;
-            if (value != null) {
-                // expanding ${} stuff, passing locale explicitly to expand value string because it won't be found in the Entity
-                MapStack<String> localContext = MapStack.create(context);
-                // Rendering code might try to modify the GenericEntity instance,
-                // so we make a copy of it.
-                Map<String, Object> genericEntityClone = UtilGenerics.cast(value.clone());
-                localContext.push(genericEntityClone);
-
-                // expand with the new localContext, which is locale aware
-                retVal = this.description.expandString(localContext, locale);
-            }
-            // try to get the entry for the field if description doesn't expand to anything
-            if (UtilValidate.isEmpty(retVal))
-                retVal = fieldValue;
-            if (UtilValidate.isEmpty(retVal))
-                retVal = "";
-            return retVal;
-        }
-
-        public String getEntityName() {
-            return entityName;
-        }
-
-        public SubHyperlink getSubHyperlink() {
-            return this.subHyperlink;
-        }
-
-        public void setSubHyperlink(SubHyperlink newSubHyperlink) {
-            this.subHyperlink = newSubHyperlink;
-        }
-    }
-
-    public static class HyperlinkField extends FieldInfo {
-        public static String DEFAULT_TARGET_TYPE = "intra-app";
-
-        protected boolean alsoHidden = true;
-        protected String linkType;
-        protected String targetType;
-        protected String size;
-        protected FlexibleStringExpander target;
-        protected FlexibleStringExpander description;
-        protected FlexibleStringExpander alternate;
-        protected FlexibleStringExpander imageLocation;
-        protected FlexibleStringExpander imageTitle;
-        protected FlexibleStringExpander targetWindowExdr;
-        protected FlexibleMapAccessor<Map<String, String>> parametersMapAcsr;
-        protected List<WidgetWorker.Parameter> parameterList = new ArrayList<WidgetWorker.Parameter>();
-        protected WidgetWorker.AutoServiceParameters autoServiceParameters;
-        protected WidgetWorker.AutoEntityParameters autoEntityParameters;
-
-        protected boolean requestConfirmation = false;
-        protected FlexibleStringExpander confirmationMsgExdr;
-
-        public HyperlinkField(ModelFormField modelFormField) {
-            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.HYPERLINK, modelFormField);
-        }
-
-        public HyperlinkField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, FieldInfo.HYPERLINK, modelFormField);
-        }
-
-        public HyperlinkField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-            this.setDescription(element.getAttribute("description"));
-            this.setAlternate(element.getAttribute("alternate"));
-            this.setImageLocation(element.getAttribute("image-location"));
-            this.setImageTitle(element.getAttribute("image-title"));
-            this.setTarget(element.getAttribute("target"));
-            this.alsoHidden = !"false".equals(element.getAttribute("also-hidden"));
-            this.linkType = element.getAttribute("link-type");
-            this.targetType = element.getAttribute("target-type");
-            this.targetWindowExdr = FlexibleStringExpander.getInstance(element.getAttribute("target-window"));
-            this.parametersMapAcsr = FlexibleMapAccessor.getInstance(element.getAttribute("parameters-map"));
-            this.size = element.getAttribute("size");
-            this.setRequestConfirmation("true".equals(element.getAttribute("request-confirmation")));
-            this.setConfirmationMsg(element.getAttribute("confirmation-message"));
-            List<? extends Element> parameterElementList = UtilXml.childElementList(element, "parameter");
-            for (Element parameterElement : parameterElementList) {
-                this.parameterList.add(new WidgetWorker.Parameter(parameterElement));
-            }
-            Element autoServiceParamsElement = UtilXml.firstChildElement(element, "auto-parameters-service");
-            if (autoServiceParamsElement != null) {
-                autoServiceParameters = new WidgetWorker.AutoServiceParameters(autoServiceParamsElement);
-            }
-            Element autoEntityParamsElement = UtilXml.firstChildElement(element, "auto-parameters-entity");
-            if (autoEntityParamsElement != null) {
-                autoEntityParameters = new WidgetWorker.AutoEntityParameters(autoEntityParamsElement);
-            }
-        }
-
-        private HyperlinkField(HyperlinkField original, ModelFormField modelFormField) {
-            super(original.getFieldSource(), original.getFieldType(), modelFormField);
-            this.description = original.description;
-            this.alternate = original.alternate;
-            this.imageLocation = original.imageLocation;
-            this.imageTitle = original.imageTitle;
-            this.target = original.target;
-            this.alsoHidden = original.alsoHidden;
-            this.linkType = original.linkType;
-            this.targetType = original.targetType;
-            this.targetWindowExdr = original.targetWindowExdr;
-            this.parametersMapAcsr = original.parametersMapAcsr;
-            this.size = original.size;
-            this.requestConfirmation = original.requestConfirmation;
-            this.confirmationMsgExdr = original.confirmationMsgExdr;
-            this.parameterList.addAll(original.parameterList);
-            this.autoEntityParameters = original.autoEntityParameters;
-            this.autoServiceParameters = original.autoServiceParameters;
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new HyperlinkField(this, modelFormField);
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderHyperlinkField(writer, context, this);
-        }
-
-        public boolean getAlsoHidden() {
-            return this.alsoHidden;
-        }
-
-        public boolean getRequestConfirmation() {
-            return this.requestConfirmation;
-        }
-
-        public String getConfirmation(Map<String, Object> context) {
-            String message = getConfirmationMsg(context);
-            if (UtilValidate.isNotEmpty(message))
-                return message;
-
-            if (getRequestConfirmation()) {
-                String defaultMessage = UtilProperties.getPropertyValue("general", "default.confirmation.message",
-                        "${uiLabelMap.CommonConfirm}");
-                setConfirmationMsg(defaultMessage);
-                return getConfirmationMsg(context);
-            }
-            return "";
-        }
-
-        public String getConfirmationMsg(Map<String, Object> context) {
-            return this.confirmationMsgExdr.expandString(context);
-        }
-
-        public String getLinkType() {
-            return this.linkType;
-        }
-
-        public String getTargetType() {
-            if (UtilValidate.isNotEmpty(this.targetType))
-                return this.targetType;
-            return HyperlinkField.DEFAULT_TARGET_TYPE;
-        }
-
-        public String getTargetWindow(Map<String, Object> context) {
-            String targetWindow = this.targetWindowExdr.expandString(context);
-            return targetWindow;
-        }
-
-        public String getDescription(Map<String, Object> context) {
-            return this.description.expandString(context);
-        }
-
-        public String getAlternate(Map<String, Object> context) {
-            return this.alternate.expandString(context);
+        public FlexibleStringExpander getImageLocation() {
+            return imageLocation;
         }
 
         public String getImageLocation(Map<String, Object> context) {
-            return this.imageLocation.expandString(context);
+            if (this.imageLocation != null)
+                return this.imageLocation.expandString(context);
+            return "";
         }
 
-        public String getImageTitle(Map<String, Object> context) {
-            return this.imageTitle.expandString(context);
-        }
-
-        public String getTarget(Map<String, Object> context) {
-            return this.target.expandString(context);
-        }
-
-        public Map<String, String> getParameterMap(Map<String, Object> context) {
-            Map<String, String> fullParameterMap = new HashMap<String, String>();
-
-            Map<String, String> addlParamMap = this.parametersMapAcsr.get(context);
-            if (addlParamMap != null) {
-                fullParameterMap.putAll(addlParamMap);
-            }
-
-            for (WidgetWorker.Parameter parameter : this.parameterList) {
-                fullParameterMap.put(parameter.getName(), parameter.getValue(context));
-            }
-
-            if (autoServiceParameters != null) {
-                fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, this.getModelFormField().getModelForm()
-                        .getDefaultServiceName()));
-            }
-
-            if (autoEntityParameters != null) {
-                fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, this.getModelFormField().getModelForm()
-                        .getDefaultEntityName()));
-            }
-
-            return fullParameterMap;
+        public InPlaceEditor getInPlaceEditor() {
+            return this.inPlaceEditor;
         }
 
         public String getSize() {
             return this.size;
         }
 
-        public String setSize(String size) {
-            return this.size = size;
+        public String getType() {
+            return this.type;
         }
 
-        /**
-         * @param b
-         */
-        public void setAlsoHidden(boolean b) {
-            this.alsoHidden = b;
-        }
-
-        /**
-         * @param string
-         */
-        public void setTargetType(String string) {
-            this.targetType = string;
-        }
-
-        /**
-         * @param string
-         */
-        public void setDescription(String string) {
-            this.description = FlexibleStringExpander.getInstance(string);
-        }
-
-        /**
-         * @param string
-         */
-        public void setImageLocation(String string) {
-            this.imageLocation = FlexibleStringExpander.getInstance(string);
-        }
-
-        /**
-         * @param string
-         */
-        public void setImageTitle(String string) {
-            this.imageTitle = FlexibleStringExpander.getInstance(string);
-        }
-
-        /**
-         * @param string
-         */
-        public void setAlternate(String string) {
-            this.alternate = FlexibleStringExpander.getInstance(string);
-        }
-
-        /**
-         * @param string
-         */
-        public void setTarget(String string) {
-            this.target = FlexibleStringExpander.getInstance(string);
-        }
-
-        public void setRequestConfirmation(boolean val) {
-            this.requestConfirmation = val;
-        }
-
-        public void setConfirmationMsg(String val) {
-            this.confirmationMsgExdr = FlexibleStringExpander.getInstance(val);
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderDisplayField(writer, context, this);
         }
     }
 
-    public static class SubHyperlink {
-        protected FlexibleStringExpander useWhen;
-        protected String linkType;
-        protected String linkStyle;
-        protected String targetType;
-        protected FlexibleStringExpander target;
-        protected FlexibleStringExpander description;
-        protected FlexibleStringExpander targetWindowExdr;
-        protected List<WidgetWorker.Parameter> parameterList = new ArrayList<WidgetWorker.Parameter>();
-        protected boolean requestConfirmation = false;
-        protected FlexibleStringExpander confirmationMsgExdr;
-        protected ModelFormField modelFormField;
-        protected WidgetWorker.AutoServiceParameters autoServiceParameters;
-        protected WidgetWorker.AutoEntityParameters autoEntityParameters;
+    /**
+     * Models the &lt;drop-down&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class DropDownField extends FieldInfoWithOptions {
+        private final boolean allowEmpty;
+        private final boolean allowMulti;
+        private final AutoComplete autoComplete;
+        private final String current;
+        private final FlexibleStringExpander currentDescription;
+        private final int otherFieldSize;
+        private final String size;
+        private final SubHyperlink subHyperlink;
+        private final String textSize;
 
-        public SubHyperlink(Element element, ModelFormField modelFormField) {
-            this.setDescription(element.getAttribute("description"));
-            this.setTarget(element.getAttribute("target"));
-            this.setUseWhen(element.getAttribute("use-when"));
-            this.linkType = element.getAttribute("link-type");
-            this.linkStyle = element.getAttribute("link-style");
-            this.targetType = element.getAttribute("target-type");
-            this.targetWindowExdr = FlexibleStringExpander.getInstance(element.getAttribute("target-window"));
-            List<? extends Element> parameterElementList = UtilXml.childElementList(element, "parameter");
-            for (Element parameterElement : parameterElementList) {
-                this.parameterList.add(new WidgetWorker.Parameter(parameterElement));
-            }
-            setRequestConfirmation("true".equals(element.getAttribute("request-confirmation")));
-            setConfirmationMsg(element.getAttribute("confirmation-message"));
-            Element autoServiceParamsElement = UtilXml.firstChildElement(element, "auto-parameters-service");
-            if (autoServiceParamsElement != null) {
-                autoServiceParameters = new WidgetWorker.AutoServiceParameters(autoServiceParamsElement);
-            }
-            Element autoEntityParamsElement = UtilXml.firstChildElement(element, "auto-parameters-entity");
-            if (autoEntityParamsElement != null) {
-                autoEntityParameters = new WidgetWorker.AutoEntityParameters(autoEntityParamsElement);
-            }
-            this.modelFormField = modelFormField;
-        }
-
-        public SubHyperlink(SubHyperlink original, ModelFormField modelFormField) {
-            this.description = original.description;
-            this.target = original.target;
-            this.useWhen = original.useWhen;
-            this.linkType = original.linkType;
-            this.linkStyle = original.linkStyle;
-            this.targetType = original.targetType;
-            this.targetWindowExdr = original.targetWindowExdr;
-            this.parameterList.addAll(original.parameterList);
-            this.requestConfirmation = original.requestConfirmation;
-            this.confirmationMsgExdr = original.confirmationMsgExdr;
-            this.autoEntityParameters = original.autoEntityParameters;
-            this.autoServiceParameters = original.autoServiceParameters;
-            this.modelFormField = modelFormField;
-        }
-
-        public String getLinkStyle() {
-            return this.linkStyle;
-        }
-
-        public String getTargetType() {
-            if (UtilValidate.isNotEmpty(this.targetType))
-                return this.targetType;
-            return HyperlinkField.DEFAULT_TARGET_TYPE;
-        }
-
-        public String getDescription(Map<String, Object> context) {
-            if (this.description != null) {
-                return this.description.expandString(context);
-            } else {
-                return "";
-            }
-        }
-
-        public String getTargetWindow(Map<String, Object> context) {
-            String targetWindow = this.targetWindowExdr.expandString(context);
-            return targetWindow;
-        }
-
-        public String getTarget(Map<String, Object> context) {
-            if (this.target != null) {
-                return this.target.expandString(context);
-            } else {
-                return "";
-            }
-        }
-
-        public String getLinkType() {
-            return this.linkType;
-        }
-
-        public Map<String, String> getParameterMap(Map<String, Object> context) {
-            Map<String, String> fullParameterMap = new HashMap<String, String>();
-
-            /* leaving this here... may want to add it at some point like the hyperlink element:
-            Map<String, String> addlParamMap = this.parametersMapAcsr.get(context);
-            if (addlParamMap != null) {
-                fullParameterMap.putAll(addlParamMap);
-            }
-            */
-
-            for (WidgetWorker.Parameter parameter : this.parameterList) {
-                fullParameterMap.put(parameter.getName(), parameter.getValue(context));
-            }
-
-            if (autoServiceParameters != null) {
-                fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, getModelFormField().getModelForm()
-                        .getDefaultServiceName()));
-            }
-            if (autoEntityParameters != null) {
-                fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, this.getModelFormField().getModelForm()
-                        .getDefaultEntityName()));
-            }
-
-            return fullParameterMap;
-        }
-
-        public String getUseWhen(Map<String, Object> context) {
-            if (this.useWhen != null) {
-                return this.useWhen.expandString(context);
-            } else {
-                return "";
-            }
-        }
-
-        public boolean getRequestConfirmation() {
-            return this.requestConfirmation;
-        }
-
-        public String getConfirmationMsg(Map<String, Object> context) {
-            return this.confirmationMsgExdr.expandString(context);
-        }
-
-        public String getConfirmation(Map<String, Object> context) {
-            String message = getConfirmationMsg(context);
-            if (UtilValidate.isNotEmpty(message))
-                return message;
-
-            if (getRequestConfirmation()) {
-                String defaultMessage = UtilProperties.getPropertyValue("general", "default.confirmation.message",
-                        "${uiLabelMap.CommonConfirm}");
-                setConfirmationMsg(defaultMessage);
-                return getConfirmationMsg(context);
-            }
-            return "";
-        }
-
-        public ModelFormField getModelFormField() {
-            return this.modelFormField;
-        }
-
-        public boolean shouldUse(Map<String, Object> context) {
-            boolean shouldUse = true;
-            String useWhen = this.getUseWhen(context);
-            if (UtilValidate.isNotEmpty(useWhen)) {
-                try {
-                    Interpreter bsh = (Interpreter) context.get("bshInterpreter");
-                    if (bsh == null) {
-                        bsh = BshUtil.makeInterpreter(context);
-                        context.put("bshInterpreter", bsh);
-                    }
-
-                    Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(useWhen));
-
-                    // retVal should be a Boolean, if not something weird is up...
-                    if (retVal instanceof Boolean) {
-                        Boolean boolVal = (Boolean) retVal;
-                        shouldUse = boolVal.booleanValue();
-                    } else {
-                        throw new IllegalArgumentException("Return value from target condition eval was not a Boolean: "
-                                + retVal.getClass().getName() + " [" + retVal + "]");
-                    }
-                } catch (EvalError e) {
-                    String errmsg = "Error evaluating BeanShell target conditions";
-                    Debug.logError(e, errmsg, module);
-                    throw new IllegalArgumentException(errmsg);
-                }
-            }
-            return shouldUse;
-        }
-
-        /**
-         * @param string
-         */
-        public void setLinkStyle(String string) {
-            this.linkStyle = string;
-        }
-
-        /**
-         * @param string
-         */
-        public void setTargetType(String string) {
-            this.targetType = string;
-        }
-
-        /**
-         * @param string
-         */
-        public void setDescription(String string) {
-            this.description = FlexibleStringExpander.getInstance(string);
-        }
-
-        /**
-         * @param string
-         */
-        public void setTarget(String string) {
-            this.target = FlexibleStringExpander.getInstance(string);
-        }
-
-        /**
-         * @param string
-         */
-        public void setUseWhen(String string) {
-            this.useWhen = FlexibleStringExpander.getInstance(string);
-        }
-
-        public void setRequestConfirmation(boolean val) {
-            this.requestConfirmation = val;
-        }
-
-        public void setConfirmationMsg(String val) {
-            this.confirmationMsgExdr = FlexibleStringExpander.getInstance(val);
-        }
-    }
-
-    public static class AutoComplete {
-        protected String autoSelect;
-        protected String frequency;
-        protected String minChars;
-        protected String choices;
-        protected String partialSearch;
-        protected String partialChars;
-        protected String ignoreCase;
-        protected String fullSearch;
-
-        public AutoComplete(Element element) {
-            this.autoSelect = element.getAttribute("auto-select");
-            this.frequency = element.getAttribute("frequency");
-            this.minChars = element.getAttribute("min-chars");
-            this.choices = element.getAttribute("choices");
-            this.partialSearch = element.getAttribute("partial-search");
-            this.partialChars = element.getAttribute("partial-chars");
-            this.ignoreCase = element.getAttribute("ignore-case");
-            this.fullSearch = element.getAttribute("full-search");
-        }
-
-        public String getAutoSelect() {
-            return this.autoSelect;
-        }
-
-        public String getFrequency() {
-            return this.frequency;
-        }
-
-        public String getMinChars() {
-            return this.minChars;
-        }
-
-        public String getChoices() {
-            return this.choices;
-        }
-
-        public String getPartialSearch() {
-            return this.partialSearch;
-        }
-
-        public String getPartialChars() {
-            return this.partialChars;
-        }
-
-        public String getIgnoreCase() {
-            return this.ignoreCase;
-        }
-
-        public String getFullSearch() {
-            return this.fullSearch;
-        }
-
-        public void setAutoSelect(String string) {
-            this.autoSelect = string;
-        }
-
-        public void setFrequency(String string) {
-            this.frequency = string;
-        }
-
-        public void setMinChars(String string) {
-            this.minChars = string;
-        }
-
-        public void setChoices(String string) {
-            this.choices = string;
-        }
-
-        public void setPartialSearch(String string) {
-            this.partialSearch = string;
-        }
-
-        public void setPartialChars(String string) {
-            this.partialChars = string;
-        }
-
-        public void setIgnoreCase(String string) {
-            this.ignoreCase = string;
-        }
-
-        public void setFullSearch(String string) {
-            this.fullSearch = string;
-        }
-    }
-
-    public static class TextField extends FieldInfo {
-        protected int size = 25;
-        protected Integer maxlength;
-        protected FlexibleStringExpander defaultValue;
-        protected SubHyperlink subHyperlink;
-        protected boolean disabled;
-        protected boolean readonly;
-        protected boolean clientAutocompleteField;
-        protected String mask;
-        protected FlexibleStringExpander placeholder = FlexibleStringExpander.getInstance(null);
-
-        public TextField(ModelFormField modelFormField) {
-            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.TEXT, modelFormField);
-        }
-
-        public TextField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, FieldInfo.TEXT, modelFormField);
-        }
-
-        public TextField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-            this.setDefaultValue(element.getAttribute("default-value"));
-            this.mask = element.getAttribute("mask");
-            this.placeholder = FlexibleStringExpander.getInstance(element.getAttribute("placeholder"));
-            String sizeStr = element.getAttribute("size");
-            try {
-                size = Integer.parseInt(sizeStr);
-            } catch (Exception e) {
-                if (UtilValidate.isNotEmpty(sizeStr)) {
-                    Debug.logError("Could not parse the size value of the text element: [" + sizeStr
-                            + "], setting to the default of " + size, module);
-                }
-            }
-            String maxlengthStr = element.getAttribute("maxlength");
-            try {
-                maxlength = Integer.valueOf(maxlengthStr);
-            } catch (Exception e) {
-                maxlength = null;
-                if (UtilValidate.isNotEmpty(maxlengthStr)) {
-                    Debug.logError("Could not parse the max-length value of the text element: [" + maxlengthStr
-                            + "], setting to null; default of no maxlength will be used", module);
-                }
-            }
-            this.disabled = "true".equals(element.getAttribute("disabled"));
-            this.readonly = "true".equals(element.getAttribute("read-only"));
-            this.clientAutocompleteField = !"false".equals(element.getAttribute("client-autocomplete-field"));
-            Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink");
-            if (subHyperlinkElement != null) {
-                this.subHyperlink = new SubHyperlink(subHyperlinkElement, this.getModelFormField());
-            }
-        }
-
-        protected TextField(TextField original, ModelFormField modelFormField) {
-            super(original.getFieldSource(), original.getFieldType(), modelFormField);
-            this.defaultValue = original.defaultValue;
-            this.mask = original.mask;
-            this.placeholder = original.placeholder;
+        private DropDownField(DropDownField original, ModelFormField modelFormField) {
+            super(original, modelFormField);
+            this.allowEmpty = original.allowEmpty;
+            this.allowMulti = original.allowMulti;
+            this.autoComplete = original.autoComplete;
+            this.current = original.current;
+            this.currentDescription = original.currentDescription;
+            this.otherFieldSize = original.otherFieldSize;
             this.size = original.size;
-            this.maxlength = original.maxlength;
-            this.disabled = original.disabled;
-            this.readonly = original.readonly;
-            this.clientAutocompleteField = original.clientAutocompleteField;
             if (original.subHyperlink != null) {
                 this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField);
-            }
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderTextField(writer, context, this);
-        }
-
-        public Integer getMaxlength() {
-            return maxlength;
-        }
-
-        public int getSize() {
-            return size;
-        }
-
-        public boolean getDisabled() {
-            return this.disabled;
-        }
-
-        public void setDisabled(boolean b) {
-            this.disabled = b;
-        }
-
-        public boolean getReadonly() {
-            return this.readonly;
-        }
-
-        public void setReadonly(boolean b) {
-            this.readonly = b;
-        }
-
-        public boolean getClientAutocompleteField() {
-            return this.clientAutocompleteField;
-        }
-
-        public void setClientAutocompleteField(boolean b) {
-            this.clientAutocompleteField = b;
-        }
-
-        public String getDefaultValue(Map<String, Object> context) {
-            if (this.defaultValue != null) {
-                return this.defaultValue.expandString(context);
             } else {
-                return "";
+                this.subHyperlink = null;
             }
-        }
-
-        /**
-         * @param integer
-         */
-        public void setMaxlength(Integer integer) {
-            maxlength = integer;
-        }
-
-        /**
-         * @param i
-         */
-        public void setSize(int i) {
-            size = i;
-        }
-
-        /**
-         * @param str
-         */
-        public void setDefaultValue(String str) {
-            this.defaultValue = FlexibleStringExpander.getInstance(str);
-        }
-
-        public SubHyperlink getSubHyperlink() {
-            return this.subHyperlink;
-        }
-
-        public void setSubHyperlink(SubHyperlink newSubHyperlink) {
-            this.subHyperlink = newSubHyperlink;
-        }
-
-        public String getMask() {
-            return this.mask;
-        }
-
-        public String getPlaceholder(Map<String, Object> context) {
-            return this.placeholder.expandString(context);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new TextField(this, modelFormField);
-        }
-    }
-
-    public static class TextareaField extends FieldInfo {
-        protected int cols = 60;
-        protected int rows = 2;
-        protected FlexibleStringExpander defaultValue;
-        protected boolean visualEditorEnable = false;
-        protected boolean readOnly = false;
-        protected FlexibleStringExpander visualEditorButtons;
-
-        public TextareaField(ModelFormField modelFormField) {
-            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.TEXTAREA, modelFormField);
-        }
-
-        public TextareaField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, FieldInfo.TEXTAREA, modelFormField);
-        }
-
-        public TextareaField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-            this.setDefaultValue(element.getAttribute("default-value"));
-            visualEditorEnable = "true".equals(element.getAttribute("visual-editor-enable"));
-            visualEditorButtons = FlexibleStringExpander.getInstance(element.getAttribute("visual-editor-buttons"));
-            readOnly = "true".equals(element.getAttribute("read-only"));
-            String colsStr = element.getAttribute("cols");
-            try {
-                cols = Integer.parseInt(colsStr);
-            } catch (Exception e) {
-                if (UtilValidate.isNotEmpty(colsStr)) {
-                    Debug.logError("Could not parse the size value of the text element: [" + colsStr
-                            + "], setting to default of " + cols, module);
-                }
-            }
-            String rowsStr = element.getAttribute("rows");
-            try {
-                rows = Integer.parseInt(rowsStr);
-            } catch (Exception e) {
-                if (UtilValidate.isNotEmpty(rowsStr)) {
-                    Debug.logError("Could not parse the size value of the text element: [" + rowsStr
-                            + "], setting to default of " + rows, module);
-                }
-            }
-        }
-
-        private TextareaField(TextareaField original, ModelFormField modelFormField) {
-            super(original.getFieldSource(), original.getFieldType(), modelFormField);
-            this.defaultValue = original.defaultValue;
-            this.visualEditorEnable = original.visualEditorEnable;
-            this.visualEditorButtons = original.visualEditorButtons;
-            this.readOnly = original.readOnly;
-            this.cols = original.cols;
-            this.rows = original.rows;
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new TextareaField(this, modelFormField);
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderTextareaField(writer, context, this);
-        }
-
-        public int getCols() {
-            return cols;
-        }
-
-        public int getRows() {
-            return rows;
-        }
-
-        public String getDefaultValue(Map<String, Object> context) {
-            if (this.defaultValue != null) {
-                return this.defaultValue.expandString(context);
-            } else {
-                return "";
-            }
-        }
-
-        public boolean getVisualEditorEnable() {
-            return this.visualEditorEnable;
-        }
-
-        public String getVisualEditorButtons(Map<String, Object> context) {
-            return this.visualEditorButtons.expandString(context);
-        }
-
-        public boolean isReadOnly() {
-            return readOnly;
-        }
-
-        /**
-         * @param r
-         */
-        public void setReadOnly(boolean r) {
-            readOnly = r;
-        }
-
-        /**
-         * @param i
-         */
-        public void setCols(int i) {
-            cols = i;
-        }
-
-        /**
-         * @param i
-         */
-        public void setRows(int i) {
-            rows = i;
-        }
-
-        /**
-         * @param str the default value of the field
-         */
-        public void setDefaultValue(String str) {
-            this.defaultValue = FlexibleStringExpander.getInstance(str);
-        }
-
-        /**
-         * @param visualEditorEnable is visualEditor enabled
-         */
-        public void setVisualEditorEnable(boolean visualEditorEnable) {
-            this.visualEditorEnable = visualEditorEnable;
-        }
-
-        /**
-         * @param eb set the visualEditor Buttons
-         */
-        public void setVisualEditorButtons(String eb) {
-            this.visualEditorButtons = FlexibleStringExpander.getInstance(eb);
-        }
-    }
-
-    public static class DateTimeField extends FieldInfo {
-        protected String type;
-        protected FlexibleStringExpander defaultValue;
-        protected String inputMethod;
-        protected String clock;
-        protected String step;
-        protected String mask;
-
-        public DateTimeField(ModelFormField modelFormField) {
-            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DATE_TIME, modelFormField);
-        }
-
-        public DateTimeField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, FieldInfo.DATE_TIME, modelFormField);
-        }
-
-        public DateTimeField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-            this.setDefaultValue(element.getAttribute("default-value"));
-            type = element.getAttribute("type");
-            inputMethod = element.getAttribute("input-method");
-            clock = element.getAttribute("clock");
-            mask = element.getAttribute("mask");
-            if (UtilValidate.isNotEmpty(element.getAttribute("step")))
-                this.setStep(element.getAttribute("step"));
-            else
-                this.setStep("1");
-        }
-
-        protected DateTimeField(DateTimeField original, ModelFormField modelFormField) {
-            super(original.getFieldSource(), original.getFieldType(), modelFormField);
-            this.defaultValue = original.defaultValue;
-            this.type = original.type;
-            this.inputMethod = original.inputMethod;
-            this.clock = original.clock;
-            this.mask = original.mask;
-            this.step = original.step;
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new DateTimeField(this, modelFormField);
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderDateTimeField(writer, context, this);
-        }
-
-        public String getType() {
-            return type;
-        }
-
-        public String getDefaultValue(Map<String, Object> context) {
-            if (this.defaultValue != null) {
-                return this.defaultValue.expandString(context);
-            } else {
-                return "";
-            }
-        }
-
-        public String getInputMethod() {
-            return this.inputMethod;
-        }
-
-        public String getClock() {
-            return this.clock;
-        }
-
-        public String getMask() {
-            return this.mask;
-        }
-
-        public String getStep() {
-            return this.step;
-        }
-
-        public void setStep(String step) {
-            this.step = step;
-        }
-
-        /**
-         * @param string
-         */
-        public void setType(String string) {
-            type = string;
-        }
-
-        /**
-         * @param str
-         */
-        public void setDefaultValue(String str) {
-            this.defaultValue = FlexibleStringExpander.getInstance(str);
-        }
-
-        public void setInputMethod(String str) {
-            this.inputMethod = str;
-        }
-
-        public void setClock(String str) {
-            this.clock = str;
-        }
-
-        /**
-         * Returns the default-value if specified, otherwise the current date, time or timestamp
-         *
-         * @param context Context Map
-         * @return Default value string for date-time
-         */
-        public String getDefaultDateTimeString(Map<String, Object> context) {
-            if (UtilValidate.isNotEmpty(this.defaultValue))
-                return this.getDefaultValue(context);
-
-            if ("date".equals(this.type))
-                return (new java.sql.Date(System.currentTimeMillis())).toString();
-            else if ("time".equals(this.type))
-                return (new java.sql.Time(System.currentTimeMillis())).toString();
-            else
-                return UtilDateTime.nowTimestamp().toString();
-        }
-    }
-
-    public static class DropDownField extends FieldInfoWithOptions {
-        protected boolean allowEmpty = false;
-        protected boolean allowMulti = false;
-        protected String current;
-        protected String size;
-        protected String textSize;
-        protected FlexibleStringExpander currentDescription;
-        protected SubHyperlink subHyperlink;
-        protected int otherFieldSize = 0;
-        protected AutoComplete autoComplete;
-
-        public DropDownField(ModelFormField modelFormField) {
-            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DROP_DOWN, modelFormField);
-        }
-
-        public DropDownField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, FieldInfo.DROP_DOWN, modelFormField);
+            this.textSize = original.textSize;
         }
 
         public DropDownField(Element element, ModelFormField modelFormField) {
             super(element, modelFormField);
-            this.current = element.getAttribute("current");
-            this.size = element.getAttribute("size");
-            this.textSize = element.getAttribute("text-size");
             this.allowEmpty = "true".equals(element.getAttribute("allow-empty"));
             this.allowMulti = "true".equals(element.getAttribute("allow-multiple"));
-            this.currentDescription = FlexibleStringExpander.getInstance(element.getAttribute("current-description"));
-            // set the default size
-            if (size == null) {
-                size = "1";
-            }
-            if (textSize == null) {
-                textSize = "0";
-            }
-            String sizeStr = element.getAttribute("other-field-size");
-            try {
-                this.otherFieldSize = Integer.parseInt(sizeStr);
-            } catch (Exception e) {
-                if (UtilValidate.isNotEmpty(sizeStr)) {
-                    Debug.logError("Could not parse the size value of the text element: [" + sizeStr
-                            + "], setting to the default of " + this.otherFieldSize, module);
-                }
-            }
-            Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink");
-            if (subHyperlinkElement != null) {
-                this.subHyperlink = new SubHyperlink(subHyperlinkElement, this.getModelFormField());
-            }
             Element autoCompleteElement = UtilXml.firstChildElement(element, "auto-complete");
             if (autoCompleteElement != null) {
                 this.autoComplete = new AutoComplete(autoCompleteElement);
+            } else {
+                this.autoComplete = null;
             }
+            this.current = element.getAttribute("current");
+            this.currentDescription = FlexibleStringExpander.getInstance(element.getAttribute("current-description"));
+            int otherFieldSize = 0;
+            String sizeStr = element.getAttribute("other-field-size");
+            if (!sizeStr.isEmpty()) {
+                try {
+                    otherFieldSize = Integer.parseInt(sizeStr);
+                } catch (Exception e) {
+                    Debug.logError("Could not parse the size value of the text element: [" + sizeStr
+                            + "], setting to the default of 0", module);
+                }
+            }
+            this.otherFieldSize = otherFieldSize;
+            String size = element.getAttribute("size");
+            if (size.isEmpty()) {
+                size = "1";
+            }
+            this.size = size;
+            Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink");
+            if (subHyperlinkElement != null) {
+                this.subHyperlink = new SubHyperlink(subHyperlinkElement, this.getModelFormField());
+            } else {
+                this.subHyperlink = null;
+            }
+            String textSize = element.getAttribute("text-size");
+            if (textSize.isEmpty()) {
+                textSize = "0";
+            }
+            this.textSize = textSize;
         }
 
-        private DropDownField(DropDownField original, ModelFormField modelFormField) {
-            super(original, modelFormField);
-            this.current = original.current;
-            this.size = original.size;
-            this.textSize = original.textSize;
-            this.allowEmpty = original.allowEmpty;
-            this.allowMulti = original.allowMulti;
-            this.currentDescription = original.currentDescription;
-            this.otherFieldSize = original.otherFieldSize;
-            if (original.subHyperlink != null) {
-                this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField);
-            }
-            this.autoComplete = original.autoComplete;
+        public DropDownField(int fieldSource, List<OptionSource> optionSources) {
+            super(fieldSource, FieldInfo.DROP_DOWN, optionSources);
+            this.allowEmpty = false;
+            this.allowMulti = false;
+            this.autoComplete = null;
+            this.current = "";
+            this.currentDescription = FlexibleStringExpander.getInstance("");
+            this.otherFieldSize = 0;
+            this.size = "1";
+            this.subHyperlink = null;
+            this.textSize = "0";
+        }
+
+        public DropDownField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, FieldInfo.DROP_DOWN, modelFormField);
+            this.allowEmpty = false;
+            this.allowMulti = false;
+            this.autoComplete = null;
+            this.current = "";
+            this.currentDescription = FlexibleStringExpander.getInstance("");
+            this.otherFieldSize = 0;
+            this.size = "1";
+            this.subHyperlink = null;
+            this.textSize = "0";
+        }
+
+        public DropDownField(ModelFormField modelFormField) {
+            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DROP_DOWN, modelFormField);
+            this.allowEmpty = false;
+            this.allowMulti = false;
+            this.autoComplete = null;
+            this.current = "";
+            this.currentDescription = FlexibleStringExpander.getInstance("");
+            this.otherFieldSize = 0;
+            this.size = "1";
+            this.subHyperlink = null;
+            this.textSize = "0";
         }
 
         @Override
@@ -3332,18 +1650,12 @@
             return new DropDownField(this, modelFormField);
         }
 
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderDropDownField(writer, context, this);
+        public boolean getAllowMulti() {
+            return allowMulti;
         }
 
-        public boolean isAllowEmpty() {
-            return this.allowEmpty;
-        }
-
-        public boolean isAllowMultiple() {
-            return this.allowMulti;
+        public AutoComplete getAutoComplete() {
+            return this.autoComplete;
         }
 
         public String getCurrent() {
@@ -3352,52 +1664,20 @@
             return this.current;
         }
 
+        public FlexibleStringExpander getCurrentDescription() {
+            return currentDescription;
+        }
+
         public String getCurrentDescription(Map<String, Object> context) {
             if (this.currentDescription == null)
                 return null;
             return this.currentDescription.expandString(context);
         }
 
-        public void setAllowEmpty(boolean b) {
-            this.allowEmpty = b;
-        }
-
-        public void setCurrent(String string) {
-            this.current = string;
-        }
-
-        public void setCurrentDescription(String string) {
-            this.currentDescription = FlexibleStringExpander.getInstance(string);
-        }
-
-        public SubHyperlink getSubHyperlink() {
-            return this.subHyperlink;
-        }
-
-        public void setSubHyperlink(SubHyperlink newSubHyperlink) {
-            this.subHyperlink = newSubHyperlink;
-        }
-
-        public AutoComplete getAutoComplete() {
-            return this.autoComplete;
-        }
-
-        public void setAutoComplete(AutoComplete newAutoComplete) {
-            this.autoComplete = newAutoComplete;
-        }
-
         public int getOtherFieldSize() {
             return this.otherFieldSize;
         }
 
-        public String getSize() {
-            return this.size;
-        }
-
-        public String getTextSize() {
-            return this.textSize;
-        }
-
         /**
          * Get the name to use for the parameter for this field in the form interpreter.
          * For HTML forms this is the request parameter name.
@@ -3420,630 +1700,298 @@
             }
         }
 
-    }
-
-    public static class RadioField extends FieldInfoWithOptions {
-
-        public RadioField(ModelFormField modelFormField) {
-            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.RADIO, modelFormField);
-        }
-
-        public RadioField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, FieldInfo.RADIO, modelFormField);
-        }
-
-        public RadioField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-        }
-
-        private RadioField(RadioField original, ModelFormField modelFormField) {
-            super(original, modelFormField);
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new RadioField(this, modelFormField);
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderRadioField(writer, context, this);
-        }
-    }
-
-    public static class CheckField extends FieldInfoWithOptions {
-        public final static String ROW_SUBMIT_FIELD_NAME = "_rowSubmit";
-        protected FlexibleStringExpander allChecked = null;
-
-        public CheckField(ModelFormField modelFormField) {
-            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.CHECK, modelFormField);
-        }
-
-        public CheckField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, FieldInfo.CHECK, modelFormField);
-        }
-
-        public CheckField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-            allChecked = FlexibleStringExpander.getInstance(element.getAttribute("all-checked"));
-        }
-
-        private CheckField(CheckField original, ModelFormField modelFormField) {
-            super(original, modelFormField);
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new CheckField(this, modelFormField);
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderCheckField(writer, context, this);
-        }
-
-        public Boolean isAllChecked(Map<String, Object> context) {
-            String allCheckedStr = this.allChecked.expandString(context);
-            if (UtilValidate.isNotEmpty(allCheckedStr))
-                return Boolean.valueOf("true".equals(allCheckedStr));
-            else
-                return null;
-        }
-    }
-
-    public static class SubmitField extends FieldInfo {
-        protected String buttonType;
-        protected FlexibleStringExpander imageLocation;
-        protected FlexibleStringExpander backgroundSubmitRefreshTargetExdr;
-        protected boolean requestConfirmation = false;
-        protected FlexibleStringExpander confirmationMsgExdr;
-
-        public SubmitField(ModelFormField modelFormField) {
-            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.SUBMIT, modelFormField);
-        }
-
-        public SubmitField(int fieldInfo, ModelFormField modelFormField) {
-            super(fieldInfo, FieldInfo.SUBMIT, modelFormField);
-        }
-
-        public SubmitField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-            this.buttonType = element.getAttribute("button-type");
-            setImageLocation(element.getAttribute("image-location"));
-            this.backgroundSubmitRefreshTargetExdr = FlexibleStringExpander.getInstance(element
-                    .getAttribute("background-submit-refresh-target"));
-            setRequestConfirmation("true".equals(element.getAttribute("request-confirmation")));
-            setConfirmationMsg(element.getAttribute("confirmation-message"));
-        }
-
-        private SubmitField(SubmitField original, ModelFormField modelFormField) {
-            super(original.getFieldSource(), original.getFieldType(), modelFormField);
-            this.buttonType = original.buttonType;
-            this.imageLocation = original.imageLocation;
-            this.backgroundSubmitRefreshTargetExdr = original.backgroundSubmitRefreshTargetExdr;
-            this.requestConfirmation = original.requestConfirmation;
-            this.confirmationMsgExdr = original.confirmationMsgExdr;
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new SubmitField(this, modelFormField);
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderSubmitField(writer, context, this);
-        }
-
-        public String getButtonType() {
-            return buttonType;
-        }
-
-        public String getImageLocation(Map<String, Object> context) {
-            return this.imageLocation.expandString(context);
-        }
-
-        public boolean getRequestConfirmation() {
-            return this.requestConfirmation;
-        }
-
-        public String getConfirmationMsg(Map<String, Object> context) {
-            return this.confirmationMsgExdr.expandString(context);
-        }
-
-        public String getConfirmation(Map<String, Object> context) {
-            String message = getConfirmationMsg(context);
-            if (UtilValidate.isNotEmpty(message))
-                return message;
-            else if (getRequestConfirmation()) {
-                String defaultMessage = UtilProperties.getPropertyValue("general", "default.confirmation.message",
-                        "${uiLabelMap.CommonConfirm}");
-                setConfirmationMsg(defaultMessage);
-                return getConfirmationMsg(context);
-            }
-            return "";
-        }
-
-        /**
-         * @param string
-         */
-        public void setButtonType(String string) {
-            buttonType = string;
-        }
-
-        /**
-         * @param val the value of the image location
-         */
-        public void setImageLocation(String val) {
-            imageLocation = FlexibleStringExpander.getInstance(val);
-        }
-
-        public String getBackgroundSubmitRefreshTarget(Map<String, Object> context) {
-            return this.backgroundSubmitRefreshTargetExdr.expandString(context);
-        }
-
-        public void setRequestConfirmation(boolean val) {
-            this.requestConfirmation = val;
-        }
-
-        public void setConfirmationMsg(String val) {
-            this.confirmationMsgExdr = FlexibleStringExpander.getInstance(val);
-        }
-
-    }
-
-    public static class ResetField extends FieldInfo {
-
-        public ResetField(ModelFormField modelFormField) {
-            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.RESET, modelFormField);
-        }
-
-        public ResetField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, FieldInfo.RESET, modelFormField);
-        }
-
-        public ResetField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-        }
-
-        private ResetField(ResetField original, ModelFormField modelFormField) {
-            super(original.getFieldSource(), original.getFieldType(), modelFormField);
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new ResetField(this, modelFormField);
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderResetField(writer, context, this);
-        }
-    }
-
-    public static class HiddenField extends FieldInfo {
-        protected FlexibleStringExpander value;
-
-        public HiddenField(ModelFormField modelFormField) {
-            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.HIDDEN, modelFormField);
-        }
-
-        public HiddenField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, FieldInfo.HIDDEN, modelFormField);
-        }
-
-        public HiddenField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-            this.setValue(element.getAttribute("value"));
-        }
-
-        private HiddenField(HiddenField original, ModelFormField modelFormField) {
-            super(original.getFieldSource(), original.getFieldType(), modelFormField);
-            this.value = original.value;
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new HiddenField(this, modelFormField);
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderHiddenField(writer, context, this);
-        }
-
-        public String getValue(Map<String, Object> context) {
-            if (UtilValidate.isNotEmpty(this.value)) {
-                String valueEnc = this.value.expandString(context);
-                StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
-                if (simpleEncoder != null) {
-                    valueEnc = simpleEncoder.encode(valueEnc);
-                }
-                return valueEnc;
-            } else {
-                return getModelFormField().getEntry(context);
-            }
-        }
-
-        public void setValue(String string) {
-            this.value = FlexibleStringExpander.getInstance(string);
-        }
-    }
-
-    public static class IgnoredField extends FieldInfo {
-
-        public IgnoredField(ModelFormField modelFormField) {
-            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.IGNORED, modelFormField);
-        }
-
-        public IgnoredField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, FieldInfo.IGNORED, modelFormField);
-        }
-
-        public IgnoredField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-        }
-
-        private IgnoredField(IgnoredField original, ModelFormField modelFormField) {
-            super(original.getFieldSource(), original.getFieldType(), modelFormField);
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new IgnoredField(this, modelFormField);
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderIgnoredField(writer, context, this);
-        }
-    }
-
-    public static class TextFindField extends TextField {
-        protected boolean ignoreCase = true;
-        protected boolean hideIgnoreCase = false;
-        protected String defaultOption = "contains";
-        protected boolean hideOptions = false;
-
-        public TextFindField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-            this.ignoreCase = "true".equals(element.getAttribute("ignore-case"));
-            this.hideIgnoreCase = "true".equals(element.getAttribute("hide-options"))
-                    || "ignore-case".equals(element.getAttribute("hide-options")) ? true : false;
-            if (element.hasAttribute("default-option")) {
-                this.defaultOption = element.getAttribute("default-option");
-            } else {
-                this.defaultOption = UtilProperties.getPropertyValue("widget", "widget.form.defaultTextFindOption", "contains");
-            }
-            this.hideOptions = "true".equals(element.getAttribute("hide-options"))
-                    || "options".equals(element.getAttribute("hide-options")) ? true : false;
-        }
-
-        private TextFindField(TextFindField original, ModelFormField modelFormField) {
-            super(original, modelFormField);
-            this.ignoreCase = original.ignoreCase;
-            this.hideIgnoreCase = original.hideIgnoreCase;
-            this.defaultOption = original.defaultOption;
-            this.hideOptions = original.hideOptions;
-        }
-
-        public TextFindField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, modelFormField);
-        }
-
-        public boolean getIgnoreCase() {
-            return this.ignoreCase;
-        }
-
-        public String getDefaultOption() {
-            return this.defaultOption;
-        }
-
-        public boolean getHideIgnoreCase() {
-            return this.hideIgnoreCase;
-        }
-
-        public boolean getHideOptions() {
-            return this.hideOptions;
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new TextFindField(this, modelFormField);
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderTextFindField(writer, context, this);
-        }
-    }
-
-    public static class DateFindField extends DateTimeField {
-        protected String defaultOptionFrom = "greaterThanEqualTo";
-        protected String defaultOptionThru = "lessThanEqualTo";
-
-        public DateFindField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-            this.defaultOptionFrom = element.getAttribute("default-option-from");
-            this.defaultOptionThru = element.getAttribute("default-option-thru");
-        }
-
-        private DateFindField(DateFindField original, ModelFormField modelFormField) {
-            super(original, modelFormField);
-            this.defaultOptionFrom = original.defaultOptionFrom;
-            this.defaultOptionThru = original.defaultOptionThru;
-        }
-
-        public DateFindField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, modelFormField);
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new DateFindField(this, modelFormField);
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderDateFindField(writer, context, this);
-        }
-
-        public String getDefaultOptionFrom() {
-            return this.defaultOptionFrom;
-        }
-
-        public String getDefaultOptionThru() {
-            return this.defaultOptionThru;
-        }
-    }
-
-    public static class RangeFindField extends TextField {
-        protected String defaultOptionFrom = "greaterThanEqualTo";
-        protected String defaultOptionThru = "lessThanEqualTo";
-
-        public RangeFindField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-            this.defaultOptionFrom = element.getAttribute("default-option-from");
-            this.defaultOptionThru = element.getAttribute("default-option-thru");
-        }
-
-        private RangeFindField(RangeFindField original, ModelFormField modelFormField) {
-            super(original, modelFormField);
-            this.defaultOptionFrom = original.defaultOptionFrom;
-            this.defaultOptionThru = original.defaultOptionThru;
-        }
-
-        public RangeFindField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, modelFormField);
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new RangeFindField(this, modelFormField);
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderRangeFindField(writer, context, this);
-        }
-
-        public String getDefaultOptionFrom() {
-            return this.defaultOptionFrom;
-        }
-
-        public String getDefaultOptionThru() {
-            return this.defaultOptionThru;
-        }
-    }
-
-    public static class LookupField extends TextField {
-        protected FlexibleStringExpander formName;
-        protected String descriptionFieldName;
-        protected String targetParameter;
-        protected String lookupPresentation;
-        protected String lookupWidth;
-        protected String lookupHeight;
-        protected String lookupPosition;
-        protected String fadeBackground;
-        protected String initiallyCollapsed;
-        protected String showDescription;
-
-        public LookupField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-            this.formName = FlexibleStringExpander.getInstance(element.getAttribute("target-form-name"));
-            this.descriptionFieldName = element.getAttribute("description-field-name");
-            this.targetParameter = element.getAttribute("target-parameter");
-            this.lookupPresentation = element.getAttribute("presentation");
-            this.lookupHeight = element.getAttribute("height");
-            this.lookupWidth = element.getAttribute("width");
-            this.lookupPosition = element.getAttribute("position");
-            this.fadeBackground = element.getAttribute("fade-background");
-            this.initiallyCollapsed = element.getAttribute("initially-collapsed");
-            this.showDescription = element.getAttribute("show-description");
-
-            Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink");
-            if (subHyperlinkElement != null) {
-                this.subHyperlink = new SubHyperlink(subHyperlinkElement, this.getModelFormField());
-            }
-        }
-
-        public LookupField(LookupField original, ModelFormField modelFormField) {
-            super(original, modelFormField);
-            this.formName = original.formName;
-            this.descriptionFieldName = original.descriptionFieldName;
-            this.targetParameter = original.targetParameter;
-            this.lookupPresentation = original.lookupPresentation;
-            this.lookupHeight = original.lookupHeight;
-            this.lookupWidth = original.lookupWidth;
-            this.lookupPosition = original.lookupPosition;
-            this.fadeBackground = original.fadeBackground;
-            this.initiallyCollapsed = original.initiallyCollapsed;
-            this.showDescription = original.showDescription;
-            if (original.subHyperlink != null) {
-                this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField);
-            }
-        }
-
-        public LookupField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, modelFormField);
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new LookupField(this, modelFormField);
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderLookupField(writer, context, this);
-        }
-
-        public String getFormName(Map<String, Object> context) {
-            return this.formName.expandString(context);
-        }
-
-        public List<String> getTargetParameterList() {
-            List<String> paramList = new LinkedList<String>();
-            if (UtilValidate.isNotEmpty(this.targetParameter)) {
-                StringTokenizer stk = new StringTokenizer(this.targetParameter, ", ");
-                while (stk.hasMoreTokens()) {
-                    paramList.add(stk.nextToken());
-                }
-            }
-            return paramList;
-        }
-
-        public void setFormName(String str) {
-            this.formName = FlexibleStringExpander.getInstance(str);
-        }
-
-        public String getDescriptionFieldName() {
-            return this.descriptionFieldName;
-        }
-
-        public void setDescriptionFieldName(String str) {
-            this.descriptionFieldName = str;
+        public String getSize() {
+            return this.size;
         }
 
-        @Override
         public SubHyperlink getSubHyperlink() {
             return this.subHyperlink;
         }
 
-        public String getLookupPresentation() {
-            return this.lookupPresentation;
+        public String getTextSize() {
+            return this.textSize;
         }
 
-        public void setLookupPresentation(String str) {
-            this.lookupPresentation = str;
+        public boolean isAllowEmpty() {
+            return this.allowEmpty;
         }
 
-        public String getLookupWidth() {
-            return this.lookupWidth;
+        public boolean isAllowMultiple() {
+            return this.allowMulti;
         }
 
-        public void setLookupWidth(String str) {
-            this.lookupWidth = str;
-        }
-
-        public String getLookupHeight() {
-            return this.lookupHeight;
-        }
-
-        public void setLookupHeight(String str) {
-            this.lookupHeight = str;
-        }
-
-        public String getLookupPosition() {
-            return this.lookupPosition;
-        }
-
-        public void setLookupPosition(String str) {
-            this.lookupPosition = str;
-        }
-
-        public String getFadeBackground() {
-            return this.fadeBackground;
-        }
-
-        public void setFadeBackground(String str) {
-            this.fadeBackground = str;
-        }
-
-        public Boolean getShowDescription() {
-            return UtilValidate.isEmpty(this.showDescription) ? null : "true".equals(this.showDescription);
-        }
-
-        public void setShowDescription(String str) {
-            this.showDescription = str;
-        }
-
-        //initially-collapsed status
-        public boolean getInitiallyCollapsed() {
-            return "true".equals(this.initiallyCollapsed);
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderDropDownField(writer, context, this);
         }
     }
 
+    /**
+     * Models the &lt;entity-options&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class EntityOptions extends OptionSource {
+        private final boolean cache;
+        private final List<EntityFinderUtil.ConditionExpr> constraintList;
+        private final FlexibleStringExpander description;
+        private final String entityName;
+        private final String filterByDate;
+        private final String keyFieldName;
+        private final List<String> orderByList;
+
+        public EntityOptions(Element entityOptionsElement, ModelFormField modelFormField) {
+            super(modelFormField);
+            this.cache = !"false".equals(entityOptionsElement.getAttribute("cache"));
+            List<? extends Element> constraintElements = UtilXml.childElementList(entityOptionsElement, "entity-constraint");
+            if (!constraintElements.isEmpty()) {
+                List<EntityFinderUtil.ConditionExpr> constraintList = new ArrayList<EntityFinderUtil.ConditionExpr>(
+                        constraintElements.size());
+                for (Element constraintElement : constraintElements) {
+                    constraintList.add(new EntityFinderUtil.ConditionExpr(constraintElement));
+                }
+                this.constraintList = Collections.unmodifiableList(constraintList);
+            } else {
+                this.constraintList = Collections.emptyList();
+            }
+            this.description = FlexibleStringExpander.getInstance(entityOptionsElement.getAttribute("description"));
+            this.entityName = entityOptionsElement.getAttribute("entity-name");
+            this.filterByDate = entityOptionsElement.getAttribute("filter-by-date");
+            this.keyFieldName = entityOptionsElement.getAttribute("key-field-name");
+            List<? extends Element> orderByElements = UtilXml.childElementList(entityOptionsElement, "entity-order-by");
+            if (!orderByElements.isEmpty()) {
+                List<String> orderByList = new ArrayList<String>(orderByElements.size());
+                for (Element orderByElement : orderByElements) {
+                    orderByList.add(orderByElement.getAttribute("field-name"));
+                }
+                this.orderByList = Collections.unmodifiableList(orderByList);
+            } else {
+                this.orderByList = Collections.emptyList();
+            }
+        }
+
+        private EntityOptions(EntityOptions original, ModelFormField modelFormField) {
+            super(modelFormField);
+            this.cache = original.cache;
+            this.constraintList = original.constraintList;
+            this.description = original.description;
+            this.entityName = original.entityName;
+            this.filterByDate = original.filterByDate;
+            this.keyFieldName = original.keyFieldName;
+            this.orderByList = original.orderByList;
+        }
+
+        public EntityOptions(ModelFormField modelFormField) {
+            super(modelFormField);
+            this.cache = true;
+            this.constraintList = Collections.emptyList();
+            this.description = FlexibleStringExpander.getInstance("");
+            this.entityName = "";
+            this.filterByDate = "";
+            this.keyFieldName = "";
+            this.orderByList = Collections.emptyList();
+        }
+
+        @Override
+        public void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator) {
+            // first expand any conditions that need expanding based on the current context
+            EntityCondition findCondition = null;
+            if (UtilValidate.isNotEmpty(this.constraintList)) {
+                List<EntityCondition> expandedConditionList = new LinkedList<EntityCondition>();
+                for (EntityFinderUtil.Condition condition : constraintList) {
+                    ModelEntity modelEntity = delegator.getModelEntity(this.entityName);
+                    if (modelEntity == null) {
+                        throw new IllegalArgumentException("Error in entity-options: could not find entity [" + this.entityName
+                                + "]");
+                    }
+                    EntityCondition createdCondition = condition.createCondition(context, modelEntity,
+                            delegator.getModelFieldTypeReader(modelEntity));
+                    if (createdCondition != null) {
+                        expandedConditionList.add(createdCondition);
+                    }
+                }
+                findCondition = EntityCondition.makeCondition(expandedConditionList);
+            }
+
+            try {
+                Locale locale = UtilMisc.ensureLocale(context.get("locale"));
+
+                List<GenericValue> values = null;
+                values = delegator.findList(this.entityName, findCondition, null, this.orderByList, null, this.cache);
+
+                // filter-by-date if requested
+                if ("true".equals(this.filterByDate)) {
+                    values = EntityUtil.filterByDate(values, true);
+                } else if (!"false".equals(this.filterByDate)) {
+                    // not explicitly true or false, check to see if has fromDate and thruDate, if so do the filter
+                    ModelEntity modelEntity = delegator.getModelEntity(this.entityName);
+                    if (modelEntity != null && modelEntity.isField("fromDate") && modelEntity.isField("thruDate")) {
+                        values = EntityUtil.filterByDate(values, true);
+                    }
+                }
+
+                for (GenericValue value : values) {
+                    // add key and description with string expansion, ie expanding ${} stuff, passing locale explicitly to expand value string because it won't be found in the Entity
+                    MapStack<String> localContext = MapStack.create(context);
+                    // Rendering code might try to modify the GenericEntity instance,
+                    // so we make a copy of it.
+                    Map<String, Object> genericEntityClone = UtilGenerics.cast(value.clone());
+                    localContext.push(genericEntityClone);
+
+                    // expand with the new localContext, which is locale aware
+                    String optionDesc = this.description.expandString(localContext, locale);
+
+                    Object keyFieldObject = value.get(this.getKeyFieldName());
+                    if (keyFieldObject == null) {
+                        throw new IllegalArgumentException(
+                                "The entity-options identifier (from key-name attribute, or default to the field name) ["
+                                        + this.getKeyFieldName() + "], may not be a valid key field name for the entity ["
+                                        + this.entityName + "].");
+                    }
+                    String keyFieldValue = keyFieldObject.toString();
+                    optionValues.add(new OptionValue(keyFieldValue, optionDesc));
+                }
+            } catch (GenericEntityException e) {
+                Debug.logError(e, "Error getting entity options in form", module);
+            }
+        }
+
+        @Override
+        public OptionSource copy(ModelFormField modelFormField) {
+            return new EntityOptions(this, modelFormField);
+        }
+
+        public boolean getCache() {
+            return cache;
+        }
+
+        public List<EntityFinderUtil.ConditionExpr> getConstraintList() {
+            return constraintList;
+        }
+
+        public FlexibleStringExpander getDescription() {
+            return description;
+        }
+
+        public String getEntityName() {
+            return entityName;
+        }
+
+        public String getFilterByDate() {
+            return filterByDate;
+        }
+
+        public String getKeyFieldName() {
+            if (UtilValidate.isNotEmpty(this.keyFieldName))
+                return this.keyFieldName;
+            return getModelFormField().getFieldName(); // get the modelFormField fieldName
+        }
+
+        public List<String> getOrderByList() {
+            return orderByList;
+        }
+    }
+
+    public static abstract class FieldInfoWithOptions extends FieldInfo {
+
+        public static String getDescriptionForOptionKey(String key, List<OptionValue> allOptionValues) {
+            if (UtilValidate.isEmpty(key))
+                return "";
+
+            if (UtilValidate.isEmpty(allOptionValues))
+                return key;
+
+            for (OptionValue optionValue : allOptionValues) {
+                if (key.equals(optionValue.getKey())) {
+                    return optionValue.getDescription();
+                }
+            }
+
+            // if we get here we didn't find a match, just return the key
+            return key;
+        }
+
+        private final FlexibleStringExpander noCurrentSelectedKey;
+        private final List<OptionSource> optionSources;
+
+        public FieldInfoWithOptions(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+            this.noCurrentSelectedKey = FlexibleStringExpander.getInstance(element.getAttribute("no-current-selected-key"));
+            // read all option and entity-options sub-elements, maintaining order
+            ArrayList<OptionSource> optionSources = new ArrayList<OptionSource>();
+            List<? extends Element> childElements = UtilXml.childElementList(element);
+            if (childElements.size() > 0) {
+                for (Element childElement : childElements) {
+                    if ("option".equals(childElement.getTagName())) {
+                        optionSources.add(new SingleOption(childElement, modelFormField));
+                    } else if ("list-options".equals(childElement.getTagName())) {
+                        optionSources.add(new ListOptions(childElement, modelFormField));
+                    } else if ("entity-options".equals(childElement.getTagName())) {
+                        optionSources.add(new EntityOptions(childElement, modelFormField));
+                    }
+                }
+            } else {
+                // this must be added or the multi-form select box options would not show up
+                optionSources.add(new SingleOption("Y", " ", modelFormField));
+            }
+            optionSources.trimToSize();
+            this.optionSources = Collections.unmodifiableList(optionSources);
+        }
+
+        // Copy constructor.
+        protected FieldInfoWithOptions(FieldInfoWithOptions original, ModelFormField modelFormField) {
+            super(original.getFieldSource(), original.getFieldType(), modelFormField);
+            this.noCurrentSelectedKey = original.noCurrentSelectedKey;
+            if (original.optionSources.isEmpty()) {
+                this.optionSources = original.optionSources;
+            } else {
+                List<OptionSource> optionSources = new ArrayList<OptionSource>(original.optionSources.size());
+                for (OptionSource source : original.optionSources) {
+                    optionSources.add(source.copy(modelFormField));
+                }
+                this.optionSources = Collections.unmodifiableList(optionSources);
+            }
+        }
+
+        protected FieldInfoWithOptions(int fieldSource, int fieldType, List<OptionSource> optionSources) {
+            super(fieldSource, fieldType, null);
+            this.noCurrentSelectedKey = FlexibleStringExpander.getInstance("");
+            this.optionSources = Collections.unmodifiableList(new ArrayList<OptionSource>(optionSources));
+        }
+
+        public FieldInfoWithOptions(int fieldSource, int fieldType, ModelFormField modelFormField) {
+            super(fieldSource, fieldType, modelFormField);
+            this.noCurrentSelectedKey = FlexibleStringExpander.getInstance("");
+            this.optionSources = Collections.emptyList();
+        }
+
+        public List<OptionValue> getAllOptionValues(Map<String, Object> context, Delegator delegator) {
+            List<OptionValue> optionValues = new LinkedList<OptionValue>();
+            for (OptionSource optionSource : this.optionSources) {
+                optionSource.addOptionValues(optionValues, context, delegator);
+            }
+            return optionValues;
+        }
+
+        public FlexibleStringExpander getNoCurrentSelectedKey() {
+            return noCurrentSelectedKey;
+        }
+
+        public String getNoCurrentSelectedKey(Map<String, Object> context) {
+            return this.noCurrentSelectedKey.expandString(context);
+        }
+
+        public List<OptionSource> getOptionSources() {
+            return optionSources;
+        }
+    }
+
+    /**
+     * Models the &lt;file&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
     public static class FileField extends TextField {
 
         public FileField(Element element, ModelFormField modelFormField) {
@@ -4075,20 +2023,950 @@
         }
     }
 
+    /**
+     * Models the &lt;hidden&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class HiddenField extends FieldInfo {
+        private final FlexibleStringExpander value;
+
+        public HiddenField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+            this.value = FlexibleStringExpander.getInstance(element.getAttribute("value"));
+        }
+
+        private HiddenField(HiddenField original, ModelFormField modelFormField) {
+            super(original.getFieldSource(), original.getFieldType(), modelFormField);
+            this.value = original.value;
+        }
+
+        public HiddenField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, FieldInfo.HIDDEN, modelFormField);
+            this.value = FlexibleStringExpander.getInstance("");
+        }
+
+        public HiddenField(ModelFormField modelFormField) {
+            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.HIDDEN, modelFormField);
+            this.value = FlexibleStringExpander.getInstance("");
+        }
+
+        @Override
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new HiddenField(this, modelFormField);
+        }
+
+        public FlexibleStringExpander getValue() {
+            return value;
+        }
+
+        public String getValue(Map<String, Object> context) {
+            if (UtilValidate.isNotEmpty(this.value)) {
+                String valueEnc = this.value.expandString(context);
+                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+                if (simpleEncoder != null) {
+                    valueEnc = simpleEncoder.encode(valueEnc);
+                }
+                return valueEnc;
+            } else {
+                return getModelFormField().getEntry(context);
+            }
+        }
+
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderHiddenField(writer, context, this);
+        }
+    }
+
+    /**
+     * Models the &lt;hyperlink&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class HyperlinkField extends FieldInfo {
+        public static String DEFAULT_TARGET_TYPE = "intra-app";
+
+        private final boolean alsoHidden;
+        private final FlexibleStringExpander alternate;
+        private final WidgetWorker.AutoEntityParameters autoEntityParameters;
+        private final WidgetWorker.AutoServiceParameters autoServiceParameters;
+        private final FlexibleStringExpander confirmationMsgExdr;
+        private final FlexibleStringExpander description;
+        private final FlexibleStringExpander imageLocation;
+        private final FlexibleStringExpander imageTitle;
+        private final String linkType;
+        private final List<WidgetWorker.Parameter> parameterList;
+        private final FlexibleMapAccessor<Map<String, String>> parametersMapAcsr;
+        private final boolean requestConfirmation;
+        private final String size;
+        private final FlexibleStringExpander target;
+        private final String targetType;
+        private final FlexibleStringExpander targetWindowExdr;
+
+        public HyperlinkField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+            this.alsoHidden = !"false".equals(element.getAttribute("also-hidden"));
+            this.alternate = FlexibleStringExpander.getInstance(element.getAttribute("alternate"));
+            Element autoEntityParamsElement = UtilXml.firstChildElement(element, "auto-parameters-entity");
+            if (autoEntityParamsElement != null) {
+                this.autoEntityParameters = new WidgetWorker.AutoEntityParameters(autoEntityParamsElement);
+            } else {
+                this.autoEntityParameters = null;
+            }
+            Element autoServiceParamsElement = UtilXml.firstChildElement(element, "auto-parameters-service");
+            if (autoServiceParamsElement != null) {
+                this.autoServiceParameters = new WidgetWorker.AutoServiceParameters(autoServiceParamsElement);
+            } else {
+                this.autoServiceParameters = null;
+            }
+            this.confirmationMsgExdr = FlexibleStringExpander.getInstance(element.getAttribute("confirmation-message"));
+            this.description = FlexibleStringExpander.getInstance(element.getAttribute("description"));
+            this.imageLocation = FlexibleStringExpander.getInstance(element.getAttribute("image-location"));
+            this.imageTitle = FlexibleStringExpander.getInstance(element.getAttribute("image-title"));
+            this.linkType = element.getAttribute("link-type");
+            List<? extends Element> parameterElementList = UtilXml.childElementList(element, "parameter");
+            if (!parameterElementList.isEmpty()) {
+                List<WidgetWorker.Parameter> parameterList = new ArrayList<WidgetWorker.Parameter>(parameterElementList.size());
+                for (Element parameterElement : parameterElementList) {
+                    parameterList.add(new WidgetWorker.Parameter(parameterElement));
+                }
+                this.parameterList = Collections.unmodifiableList(parameterList);
+            } else {
+                this.parameterList = Collections.emptyList();
+            }
+            this.parametersMapAcsr = FlexibleMapAccessor.getInstance(element.getAttribute("parameters-map"));
+            this.requestConfirmation = "true".equals(element.getAttribute("request-confirmation"));
+            this.size = element.getAttribute("size");
+            this.target = FlexibleStringExpander.getInstance(element.getAttribute("target"));
+            this.targetType = element.getAttribute("target-type");
+            this.targetWindowExdr = FlexibleStringExpander.getInstance(element.getAttribute("target-window"));
+        }
+
+        private HyperlinkField(HyperlinkField original, ModelFormField modelFormField) {
+            super(original.getFieldSource(), original.getFieldType(), modelFormField);
+            this.description = original.description;
+            this.alternate = original.alternate;
+            this.imageLocation = original.imageLocation;
+            this.imageTitle = original.imageTitle;
+            this.target = original.target;
+            this.alsoHidden = original.alsoHidden;
+            this.linkType = original.linkType;
+            this.targetType = original.targetType;
+            this.targetWindowExdr = original.targetWindowExdr;
+            this.parametersMapAcsr = original.parametersMapAcsr;
+            this.size = original.size;
+            this.requestConfirmation = original.requestConfirmation;
+            this.confirmationMsgExdr = original.confirmationMsgExdr;
+            this.parameterList = original.parameterList;
+            this.autoEntityParameters = original.autoEntityParameters;
+            this.autoServiceParameters = original.autoServiceParameters;
+        }
+
+        public HyperlinkField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, FieldInfo.HYPERLINK, modelFormField);
+            this.alsoHidden = true;
+            this.alternate = FlexibleStringExpander.getInstance("");
+            this.autoEntityParameters = null;
+            this.autoServiceParameters = null;
+            this.confirmationMsgExdr = FlexibleStringExpander.getInstance("");
+            this.description = FlexibleStringExpander.getInstance("");
+            this.imageLocation = FlexibleStringExpander.getInstance("");
+            this.imageTitle = FlexibleStringExpander.getInstance("");
+            this.linkType = "";
+            this.parameterList = Collections.emptyList();
+            this.parametersMapAcsr = FlexibleMapAccessor.getInstance("");
+            this.requestConfirmation = false;
+            this.size = "";
+            this.target = FlexibleStringExpander.getInstance("");
+            this.targetType = "";
+            this.targetWindowExdr = FlexibleStringExpander.getInstance("");
+        }
+
+        public HyperlinkField(ModelFormField modelFormField) {
+            this(FieldInfo.SOURCE_EXPLICIT, modelFormField);
+        }
+
+        @Override
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new HyperlinkField(this, modelFormField);
+        }
+
+        public boolean getAlsoHidden() {
+            return this.alsoHidden;
+        }
+
+        public FlexibleStringExpander getAlternate() {
+            return alternate;
+        }
+
+        public String getAlternate(Map<String, Object> context) {
+            return this.alternate.expandString(context);
+        }
+
+        public WidgetWorker.AutoEntityParameters getAutoEntityParameters() {
+            return autoEntityParameters;
+        }
+
+        public WidgetWorker.AutoServiceParameters getAutoServiceParameters() {
+            return autoServiceParameters;
+        }
+
+        public String getConfirmation(Map<String, Object> context) {
+            String message = getConfirmationMsg(context);
+            if (UtilValidate.isNotEmpty(message))
+                return message;
+            if (getRequestConfirmation()) {
+                String defaultMessage = UtilProperties.getPropertyValue("general", "default.confirmation.message",
+                        "${uiLabelMap.CommonConfirm}");
+                return FlexibleStringExpander.expandString(defaultMessage, context);
+            }
+            return "";
+        }
+
+        public String getConfirmationMsg(Map<String, Object> context) {
+            return this.confirmationMsgExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getConfirmationMsgExdr() {
+            return confirmationMsgExdr;
+        }
+
+        public FlexibleStringExpander getDescription() {
+            return description;
+        }
+
+        public String getDescription(Map<String, Object> context) {
+            return this.description.expandString(context);
+        }
+
+        public FlexibleStringExpander getImageLocation() {
+            return imageLocation;
+        }
+
+        public String getImageLocation(Map<String, Object> context) {
+            return this.imageLocation.expandString(context);
+        }
+
+        public FlexibleStringExpander getImageTitle() {
+            return imageTitle;
+        }
+
+        public String getImageTitle(Map<String, Object> context) {
+            return this.imageTitle.expandString(context);
+        }
+
+        public String getLinkType() {
+            return this.linkType;
+        }
+
+        public List<WidgetWorker.Parameter> getParameterList() {
+            return parameterList;
+        }
+
+        public Map<String, String> getParameterMap(Map<String, Object> context) {
+            Map<String, String> fullParameterMap = new HashMap<String, String>();
+
+            Map<String, String> addlParamMap = this.parametersMapAcsr.get(context);
+            if (addlParamMap != null) {
+                fullParameterMap.putAll(addlParamMap);
+            }
+
+            for (WidgetWorker.Parameter parameter : this.parameterList) {
+                fullParameterMap.put(parameter.getName(), parameter.getValue(context));
+            }
+
+            if (autoServiceParameters != null) {
+                fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, this.getModelFormField().getModelForm()
+                        .getDefaultServiceName()));
+            }
+
+            if (autoEntityParameters != null) {
+                fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, this.getModelFormField().getModelForm()
+                        .getDefaultEntityName()));
+            }
+
+            return fullParameterMap;
+        }
+
+        public FlexibleMapAccessor<Map<String, String>> getParametersMapAcsr() {
+            return parametersMapAcsr;
+        }
+
+        public boolean getRequestConfirmation() {
+            return this.requestConfirmation;
+        }
+
+        public String getSize() {
+            return this.size;
+        }
+
+        public FlexibleStringExpander getTarget() {
+            return target;
+        }
+
+        public String getTarget(Map<String, Object> context) {
+            return this.target.expandString(context);
+        }
+
+        public String getTargetType() {
+            if (UtilValidate.isNotEmpty(this.targetType))
+                return this.targetType;
+            return HyperlinkField.DEFAULT_TARGET_TYPE;
+        }
+
+        public String getTargetWindow(Map<String, Object> context) {
+            String targetWindow = this.targetWindowExdr.expandString(context);
+            return targetWindow;
+        }
+
+        public FlexibleStringExpander getTargetWindowExdr() {
+            return targetWindowExdr;
+        }
+
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderHyperlinkField(writer, context, this);
+        }
+    }
+
+    /**
+     * Models the &lt;ignored&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class IgnoredField extends FieldInfo {
+
+        public IgnoredField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+        }
+
+        private IgnoredField(IgnoredField original, ModelFormField modelFormField) {
+            super(original.getFieldSource(), original.getFieldType(), modelFormField);
+        }
+
+        public IgnoredField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, FieldInfo.IGNORED, modelFormField);
+        }
+
+        public IgnoredField(ModelFormField modelFormField) {
+            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.IGNORED, modelFormField);
+        }
+
+        @Override
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new IgnoredField(this, modelFormField);
+        }
+
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderIgnoredField(writer, context, this);
+        }
+    }
+
+    /**
+     * Models the &lt;image&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class ImageField extends FieldInfo {
+        private final FlexibleStringExpander alternate;
+        private final FlexibleStringExpander defaultValue;
+        private final FlexibleStringExpander description;
+        private final FlexibleStringExpander style;
+        private final SubHyperlink subHyperlink;
+        private final FlexibleStringExpander value;
+
+        public ImageField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+            this.alternate = FlexibleStringExpander.getInstance(element.getAttribute("alternate"));
+            this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value"));
+            this.description = FlexibleStringExpander.getInstance(element.getAttribute("description"));
+            this.style = FlexibleStringExpander.getInstance(element.getAttribute("style"));
+            Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink");
+            if (subHyperlinkElement != null) {
+                this.subHyperlink = new SubHyperlink(subHyperlinkElement, modelFormField);
+            } else {
+                this.subHyperlink = null;
+            }
+            this.value = FlexibleStringExpander.getInstance(element.getAttribute("value"));
+        }
+
+        public ImageField(ImageField original, ModelFormField modelFormField) {
+            super(original.getFieldSource(), original.getFieldType(), modelFormField);
+            this.alternate = original.alternate;
+            this.defaultValue = original.defaultValue;
+            this.description = original.description;
+            this.style = original.style;
+            if (original.subHyperlink != null) {
+                this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField);
+            } else {
+                this.subHyperlink = null;
+            }
+            this.value = original.value;
+        }
+
+        public ImageField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, FieldInfo.IMAGE, modelFormField);
+            this.alternate = FlexibleStringExpander.getInstance("");
+            this.defaultValue = FlexibleStringExpander.getInstance("");
+            this.description = FlexibleStringExpander.getInstance("");
+            this.style = FlexibleStringExpander.getInstance("");
+            this.subHyperlink = null;
+            this.value = FlexibleStringExpander.getInstance("");
+        }
+
+        public ImageField(ModelFormField modelFormField) {
+            this(FieldInfo.SOURCE_EXPLICIT, modelFormField);
+        }
+
+        @Override
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new ImageField(this, modelFormField);
+        }
+
+        public FlexibleStringExpander getAlternate() {
+            return alternate;
+        }
+
+        public String getAlternate(Map<String, Object> context) {
+            if (UtilValidate.isNotEmpty(this.alternate))
+                return this.alternate.expandString(context);
+            return "";
+        }
+
+        public FlexibleStringExpander getDefaultValue() {
+            return defaultValue;
+        }
+
+        public String getDefaultValue(Map<String, Object> context) {
+            if (this.defaultValue != null) {
+                return this.defaultValue.expandString(context);
+            } else {
+                return "";
+            }
+        }
+
+        public FlexibleStringExpander getDescription() {
+            return description;
+        }
+
+        public String getDescription(Map<String, Object> context) {
+            if (UtilValidate.isNotEmpty(this.description))
+                return this.description.expandString(context);
+            return "";
+        }
+
+        public FlexibleStringExpander getStyle() {
+            return style;
+        }
+
+        public String getStyle(Map<String, Object> context) {
+            if (UtilValidate.isNotEmpty(this.style))
+                return this.style.expandString(context);
+            return "";
+        }
+
+        public SubHyperlink getSubHyperlink() {
+            return this.subHyperlink;
+        }
+
+        public FlexibleStringExpander getValue() {
+            return value;
+        }
+
+        public String getValue(Map<String, Object> context) {
+            if (UtilValidate.isNotEmpty(this.value))
+                return this.value.expandString(context);
+            return getModelFormField().getEntry(context);
+        }
+
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderImageField(writer, context, this);
+        }
+    }
+
+    /**
+     * Models the &lt;in-place-editor&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class InPlaceEditor {
+        private final String cancelControl;
+        private final String cancelText;
+        private final String clickToEditText;
+        private final String cols;
+        private final Map<FlexibleMapAccessor<Object>, Object> fieldMap;
+        private final String fieldPostCreation;
+        private final String formClassName;
+        private final String highlightColor;
+        private final String highlightEndColor;
+        private final String hoverClassName;
+        private final String htmlResponse;
+        private final String loadingClassName;
+        private final String loadingText;
+        private final String okControl;
+        private final String okText;
+        private final String paramName;
+        private final String rows;
+        private final String savingClassName;
+        private final String savingText;
+        private final String submitOnBlur;
+        private final String textAfterControls;
+        private final String textBeforeControls;
+        private final String textBetweenControls;
+        private final String updateAfterRequestCall;
+        private final FlexibleStringExpander url;
+
+        public InPlaceEditor(Element element) {
+            this.cancelControl = element.getAttribute("cancel-control");
+            this.cancelText = element.getAttribute("cancel-text");
+            this.clickToEditText = element.getAttribute("click-to-edit-text");
+            this.fieldPostCreation = element.getAttribute("field-post-creation");
+            this.formClassName = element.getAttribute("form-class-name");
+            this.highlightColor = element.getAttribute("highlight-color");
+            this.highlightEndColor = element.getAttribute("highlight-end-color");
+            this.hoverClassName = element.getAttribute("hover-class-name");
+            this.htmlResponse = element.getAttribute("html-response");
+            this.loadingClassName = element.getAttribute("loading-class-name");
+            this.loadingText = element.getAttribute("loading-text");
+            this.okControl = element.getAttribute("ok-control");
+            this.okText = element.getAttribute("ok-text");
+            this.paramName = element.getAttribute("param-name");
+            this.savingClassName = element.getAttribute("saving-class-name");
+            this.savingText = element.getAttribute("saving-text");
+            this.submitOnBlur = element.getAttribute("submit-on-blur");
+            this.textBeforeControls = element.getAttribute("text-before-controls");
+            this.textAfterControls = element.getAttribute("text-after-controls");
+            this.textBetweenControls = element.getAttribute("text-between-controls");
+            this.updateAfterRequestCall = element.getAttribute("update-after-request-call");
+            Element simpleElement = UtilXml.firstChildElement(element, "simple-editor");
+            if (simpleElement != null) {
+                this.rows = simpleElement.getAttribute("rows");
+                this.cols = simpleElement.getAttribute("cols");
+            } else {
+                this.rows = "";
+                this.cols = "";
+            }
+            this.fieldMap = EntityFinderUtil.makeFieldMap(element);
+            this.url = FlexibleStringExpander.getInstance(element.getAttribute("url"));
+        }
+
+        public String getCancelControl() {
+            return this.cancelControl;
+        }
+
+        public String getCancelText() {
+            return this.cancelText;
+        }
+
+        public String getClickToEditText() {
+            return this.clickToEditText;
+        }
+
+        public String getCols() {
+            return this.cols;
+        }
+
+        public Map<FlexibleMapAccessor<Object>, Object> getFieldMap() {
+            return fieldMap;
+        }
+
+        public Map<String, Object> getFieldMap(Map<String, Object> context) {
+            Map<String, Object> inPlaceEditorContext = new HashMap<String, Object>();
+            EntityFinderUtil.expandFieldMapToContext(this.fieldMap, context, inPlaceEditorContext);
+            return inPlaceEditorContext;
+        }
+
+        public String getFieldPostCreation() {
+            return this.fieldPostCreation;
+        }
+
+        public String getFormClassName() {
+            return this.formClassName;
+        }
+
+        public String getHighlightColor() {
+            return this.highlightColor;
+        }
+
+        public String getHighlightEndColor() {
+            return this.highlightEndColor;
+        }
+
+        public String getHoverClassName() {
+            return this.hoverClassName;
+        }
+
+        public String getHtmlResponse() {
+            return this.htmlResponse;
+        }
+
+        public String getLoadingClassName() {
+            return this.loadingClassName;
+        }
+
+        public String getLoadingText() {
+            return this.loadingText;
+        }
+
+        public String getOkControl() {
+            return this.okControl;
+        }
+
+        public String getOkText() {
+            return this.okText;
+        }
+
+        public String getParamName() {
+            return this.paramName;
+        }
+
+        public String getRows() {
+            return this.rows;
+        }
+
+        public String getSavingClassName() {
+            return this.savingClassName;
+        }
+
+        public String getSavingText() {
+            return this.savingText;
+        }
+
+        public String getSubmitOnBlur() {
+            return this.submitOnBlur;
+        }
+
+        public String getTextAfterControls() {
+            return this.textAfterControls;
+        }
+
+        public String getTextBeforeControls() {
+            return this.textBeforeControls;
+        }
+
+        public String getTextBetweenControls() {
+            return this.textBetweenControls;
+        }
+
+        public String getUpdateAfterRequestCall() {
+            return this.updateAfterRequestCall;
+        }
+
+        public FlexibleStringExpander getUrl() {
+            return url;
+        }
+
+        public String getUrl(Map<String, Object> context) {
+            if (this.url != null) {
+                return this.url.expandString(context);
+            } else {
+                return "";
+            }
+        }
+    }
+
+    /**
+     * Models the &lt;list-options&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class ListOptions extends OptionSource {
+        private final FlexibleStringExpander description;
+        private final FlexibleMapAccessor<Object> keyAcsr;
+        private final FlexibleMapAccessor<List<? extends Object>> listAcsr;
+        private final String listEntryName;
+
+        public ListOptions(Element optionElement, ModelFormField modelFormField) {
+            super(modelFormField);
+            this.listEntryName = optionElement.getAttribute("list-entry-name");
+            this.keyAcsr = FlexibleMapAccessor.getInstance(optionElement.getAttribute("key-name"));
+            this.listAcsr = FlexibleMapAccessor.getInstance(optionElement.getAttribute("list-name"));
+            this.description = FlexibleStringExpander.getInstance(optionElement.getAttribute("description"));
+        }
+
+        private ListOptions(ListOptions original, ModelFormField modelFormField) {
+            super(modelFormField);
+            this.listAcsr = original.listAcsr;
+            this.listEntryName = original.listEntryName;
+            this.keyAcsr = original.keyAcsr;
+            this.description = original.description;
+        }
+
+        public ListOptions(String listName, String listEntryName, String keyName, String description,
+                ModelFormField modelFormField) {
+            super(modelFormField);
+            this.listAcsr = FlexibleMapAccessor.getInstance(listName);
+            this.listEntryName = listEntryName;
+            this.keyAcsr = FlexibleMapAccessor.getInstance(keyName);
+            this.description = FlexibleStringExpander.getInstance(description);
+        }
+
+        @Override
+        public void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator) {
+            List<? extends Object> dataList = UtilGenerics.checkList(this.listAcsr.get(context));
+            if (dataList != null && dataList.size() != 0) {
+                for (Object data : dataList) {
+                    Map<String, Object> localContext = new HashMap<String, Object>();
+                    localContext.putAll(context);
+                    if (UtilValidate.isNotEmpty(this.listEntryName)) {
+                        localContext.put(this.listEntryName, data);
+                    } else {
+                        Map<String, Object> dataMap = UtilGenerics.checkMap(data);
+                        localContext.putAll(dataMap);
+                    }
+                    Object keyObj = keyAcsr.get(localContext);
+                    String key = null;
+                    if (keyObj instanceof String) {
+                        key = (String) keyObj;
+                    } else {
+                        try {
+                            key = (String) ObjectType.simpleTypeConvert(keyObj, "String", null, null);
+                        } catch (GeneralException e) {
+                            String errMsg = "Could not convert field value for the field: [" + this.keyAcsr.toString()
+                                    + "] to String for the value [" + keyObj + "]: " + e.toString();
+                            Debug.logError(e, errMsg, module);
+                        }
+                    }
+                    optionValues.add(new OptionValue(key, description.expandString(localContext)));
+                }
+            }
+        }
+
+        @Override
+        public OptionSource copy(ModelFormField modelFormField) {
+            return new ListOptions(this, modelFormField);
+        }
+
+        public FlexibleStringExpander getDescription() {
+            return description;
+        }
+
+        public FlexibleMapAccessor<Object> getKeyAcsr() {
+            return keyAcsr;
+        }
+
+        public FlexibleMapAccessor<List<? extends Object>> getListAcsr() {
+            return listAcsr;
+        }
+
+        public String getListEntryName() {
+            return listEntryName;
+        }
+    }
+
+    /**
+     * Models the &lt;lookup&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class LookupField extends TextField {
+        private final String descriptionFieldName;
+        private final String fadeBackground;
+        private final FlexibleStringExpander formName;
+        private final String initiallyCollapsed;
+        private final String lookupHeight;
+        private final String lookupPosition;
+        private final String lookupPresentation;
+        private final String lookupWidth;
+        private final String showDescription;
+        private final String targetParameter;
+
+        public LookupField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+            this.descriptionFieldName = element.getAttribute("description-field-name");
+            this.fadeBackground = element.getAttribute("fade-background");
+            this.formName = FlexibleStringExpander.getInstance(element.getAttribute("target-form-name"));
+            this.initiallyCollapsed = element.getAttribute("initially-collapsed");
+            this.lookupHeight = element.getAttribute("height");
+            this.lookupPosition = element.getAttribute("position");
+            this.lookupPresentation = element.getAttribute("presentation");
+            this.lookupWidth = element.getAttribute("width");
+            this.showDescription = element.getAttribute("show-description");
+            this.targetParameter = element.getAttribute("target-parameter");
+        }
+
+        public LookupField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, modelFormField);
+            this.descriptionFieldName = "";
+            this.fadeBackground = "";
+            this.formName = FlexibleStringExpander.getInstance("");
+            this.initiallyCollapsed = "";
+            this.lookupHeight = "";
+            this.lookupPosition = "";
+            this.lookupPresentation = "";
+            this.lookupWidth = "";
+            this.showDescription = "";
+            this.targetParameter = "";
+        }
+
+        public LookupField(LookupField original, ModelFormField modelFormField) {
+            super(original, modelFormField);
+            this.descriptionFieldName = original.descriptionFieldName;
+            this.fadeBackground = original.fadeBackground;
+            this.formName = original.formName;
+            this.initiallyCollapsed = original.initiallyCollapsed;
+            this.lookupHeight = original.lookupHeight;
+            this.lookupPosition = original.lookupPosition;
+            this.lookupPresentation = original.lookupPresentation;
+            this.lookupWidth = original.lookupWidth;
+            this.showDescription = original.showDescription;
+            this.targetParameter = original.targetParameter;
+        }
+
+        @Override
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new LookupField(this, modelFormField);
+        }
+
+        public String getDescriptionFieldName() {
+            return this.descriptionFieldName;
+        }
+
+        public String getFadeBackground() {
+            return this.fadeBackground;
+        }
+
+        public FlexibleStringExpander getFormName() {
+            return formName;
+        }
+
+        public String getFormName(Map<String, Object> context) {
+            return this.formName.expandString(context);
+        }
+
+        //initially-collapsed status
+        public boolean getInitiallyCollapsed() {
+            return "true".equals(this.initiallyCollapsed);
+        }
+
+        public String getLookupHeight() {
+            return this.lookupHeight;
+        }
+
+        public String getLookupPosition() {
+            return this.lookupPosition;
+        }
+
+        public String getLookupPresentation() {
+            return this.lookupPresentation;
+        }
+
+        public String getLookupWidth() {
+            return this.lookupWidth;
+        }
+
+        public Boolean getShowDescription() {
+            return UtilValidate.isEmpty(this.showDescription) ? null : "true".equals(this.showDescription);
+        }
+
+        public String getTargetParameter() {
+            return targetParameter;
+        }
+
+        public List<String> getTargetParameterList() {
+            List<String> paramList = new LinkedList<String>();
+            if (UtilValidate.isNotEmpty(this.targetParameter)) {
+                StringTokenizer stk = new StringTokenizer(this.targetParameter, ", ");
+                while (stk.hasMoreTokens()) {
+                    paramList.add(stk.nextToken());
+                }
+            }
+            return paramList;
+        }
+
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderLookupField(writer, context, this);
+        }
+    }
+
+    public static abstract class OptionSource {
+
+        private final ModelFormField modelFormField;
+
+        protected OptionSource(ModelFormField modelFormField) {
+            this.modelFormField = modelFormField;
+        }
+
+        public abstract void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator);
+
+        public abstract OptionSource copy(ModelFormField modelFormField);
+
+        public ModelFormField getModelFormField() {
+            return modelFormField;
+        }
+    }
+
+    public static class OptionValue {
+        private final String description;
+        private final String key;
+
+        public OptionValue(String key, String description) {
+            this.key = key;
+            this.description = description;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public String getKey() {
+            return key;
+        }
+    }
+
+    /**
+     * Models the &lt;password&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
     public static class PasswordField extends TextField {
 
         public PasswordField(Element element, ModelFormField modelFormField) {
             super(element, modelFormField);
         }
 
-        private PasswordField(PasswordField original, ModelFormField modelFormField) {
-            super(original, modelFormField);
-        }
-
         public PasswordField(int fieldSource, ModelFormField modelFormField) {
             super(fieldSource, modelFormField);
         }
 
+        private PasswordField(PasswordField original, ModelFormField modelFormField) {
+            super(original, modelFormField);
+        }
+
         @Override
         public void accept(ModelFieldVisitor visitor) {
             visitor.visit(this);
@@ -4106,43 +2984,27 @@
         }
     }
 
-    public static class ImageField extends FieldInfo {
-        protected FlexibleStringExpander defaultValue;
-        protected FlexibleStringExpander value;
-        protected SubHyperlink subHyperlink;
-        protected FlexibleStringExpander description;
-        protected FlexibleStringExpander alternate;
-        protected FlexibleStringExpander style;
+    /**
+     * Models the &lt;radio&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class RadioField extends FieldInfoWithOptions {
 
-        public ImageField(ModelFormField modelFormField) {
-            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.IMAGE, modelFormField);
-        }
-
-        public ImageField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, FieldInfo.IMAGE, modelFormField);
-        }
-
-        public ImageField(Element element, ModelFormField modelFormField) {
+        public RadioField(Element element, ModelFormField modelFormField) {
             super(element, modelFormField);
-            this.setValue(element.getAttribute("value"));
-            this.setDescription(element.getAttribute("description"));
-            this.setAlternate(element.getAttribute("alternate"));
-            this.setStyle(element.getAttribute("style"));
-            Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink");
-            if (subHyperlinkElement != null) {
-                this.subHyperlink = new SubHyperlink(subHyperlinkElement, this.getModelFormField());
-            }
         }
 
-        public ImageField(ImageField original, ModelFormField modelFormField) {
-            super(original.getFieldSource(), original.getFieldType(), modelFormField);
-            this.value = original.value;
-            this.description = original.description;
-            this.alternate = original.alternate;
-            this.style = original.style;
-            if (original.subHyperlink != null) {
-                this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField);
-            }
+        public RadioField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, FieldInfo.RADIO, modelFormField);
+        }
+
+        public RadioField(ModelFormField modelFormField) {
+            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.RADIO, modelFormField);
+        }
+
+        private RadioField(RadioField original, ModelFormField modelFormField) {
+            super(original, modelFormField);
         }
 
         @Override
@@ -4152,28 +3014,576 @@
 
         @Override
         public FieldInfo copy(ModelFormField modelFormField) {
-            return new ImageField(this, modelFormField);
+            return new RadioField(this, modelFormField);
         }
 
         @Override
         public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                 throws IOException {
-            formStringRenderer.renderImageField(writer, context, this);
+            formStringRenderer.renderRadioField(writer, context, this);
+        }
+    }
+
+    /**
+     * Models the &lt;range-find&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class RangeFindField extends TextField {
+        private final String defaultOptionFrom;
+        private final String defaultOptionThru;
+
+        public RangeFindField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+            this.defaultOptionFrom = element.getAttribute("default-option-from");
+            this.defaultOptionThru = element.getAttribute("default-option-thru");
         }
 
-        /**
-         * @param str
-         */
-        public void setDefaultValue(String str) {
-            this.defaultValue = FlexibleStringExpander.getInstance(str);
+        public RangeFindField(int fieldSource, int size, ModelFormField modelFormField) {
+            super(fieldSource, size, null, modelFormField);
+            this.defaultOptionFrom = "greaterThanEqualTo";
+            this.defaultOptionThru = "lessThanEqualTo";
         }
 
-        public SubHyperlink getSubHyperlink() {
-            return this.subHyperlink;
+        private RangeFindField(RangeFindField original, ModelFormField modelFormField) {
+            super(original, modelFormField);
+            this.defaultOptionFrom = original.defaultOptionFrom;
+            this.defaultOptionThru = original.defaultOptionThru;
         }
 
-        public void setSubHyperlink(SubHyperlink newSubHyperlink) {
-            this.subHyperlink = newSubHyperlink;
+        @Override
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new RangeFindField(this, modelFormField);
+        }
+
+        public String getDefaultOptionFrom() {
+            return this.defaultOptionFrom;
+        }
+
+        public String getDefaultOptionThru() {
+            return this.defaultOptionThru;
+        }
+
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderRangeFindField(writer, context, this);
+        }
+    }
+
+    /**
+     * Models the &lt;reset&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class ResetField extends FieldInfo {
+
+        public ResetField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+        }
+
+        public ResetField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, FieldInfo.RESET, modelFormField);
+        }
+
+        public ResetField(ModelFormField modelFormField) {
+            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.RESET, modelFormField);
+        }
+
+        private ResetField(ResetField original, ModelFormField modelFormField) {
+            super(original.getFieldSource(), original.getFieldType(), modelFormField);
+        }
+
+        @Override
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new ResetField(this, modelFormField);
+        }
+
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderResetField(writer, context, this);
+        }
+    }
+
+    /**
+     * Models the &lt;option&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class SingleOption extends OptionSource {
+        private final FlexibleStringExpander description;
+        private final FlexibleStringExpander key;
+
+        public SingleOption(Element optionElement, ModelFormField modelFormField) {
+            super(modelFormField);
+            this.key = FlexibleStringExpander.getInstance(optionElement.getAttribute("key"));
+            this.description = FlexibleStringExpander.getInstance(UtilXml.checkEmpty(optionElement.getAttribute("description"),
+                    optionElement.getAttribute("key")));
+        }
+
+        private SingleOption(SingleOption original, ModelFormField modelFormField) {
+            super(modelFormField);
+            this.key = original.key;
+            this.description = original.description;
+        }
+
+        public SingleOption(String key, String description, ModelFormField modelFormField) {
+            super(modelFormField);
+            this.key = FlexibleStringExpander.getInstance(key);
+            this.description = FlexibleStringExpander.getInstance(UtilXml.checkEmpty(description, key));
+        }
+
+        @Override
+        public void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator) {
+            optionValues.add(new OptionValue(key.expandString(context), description.expandString(context)));
+        }
+
+        @Override
+        public OptionSource copy(ModelFormField modelFormField) {
+            return new SingleOption(this, modelFormField);
+        }
+
+        public FlexibleStringExpander getDescription() {
+            return description;
+        }
+
+        public FlexibleStringExpander getKey() {
+            return key;
+        }
+    }
+
+    /**
+     * Models the &lt;sub-hyperlink&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class SubHyperlink {
+        private final WidgetWorker.AutoEntityParameters autoEntityParameters;
+        private final WidgetWorker.AutoServiceParameters autoServiceParameters;
+        private final FlexibleStringExpander confirmationMsgExdr;
+        private final FlexibleStringExpander description;
+        private final String linkStyle;
+        private final String linkType;
+        private final ModelFormField modelFormField;
+        private final List<WidgetWorker.Parameter> parameterList;
+        private final boolean requestConfirmation;
+        private final FlexibleStringExpander target;
+        private final String targetType;
+        private final FlexibleStringExpander targetWindowExdr;
+        private final FlexibleStringExpander useWhen;
+
+        public SubHyperlink(Element element, ModelFormField modelFormField) {
+            Element autoEntityParamsElement = UtilXml.firstChildElement(element, "auto-parameters-entity");
+            if (autoEntityParamsElement != null) {
+                this.autoEntityParameters = new WidgetWorker.AutoEntityParameters(autoEntityParamsElement);
+            } else {
+                this.autoEntityParameters = null;
+            }
+            Element autoServiceParamsElement = UtilXml.firstChildElement(element, "auto-parameters-service");
+            if (autoServiceParamsElement != null) {
+                this.autoServiceParameters = new WidgetWorker.AutoServiceParameters(autoServiceParamsElement);
+            } else {
+                this.autoServiceParameters = null;
+            }
+            this.confirmationMsgExdr = FlexibleStringExpander.getInstance(element.getAttribute("confirmation-message"));
+            this.description = FlexibleStringExpander.getInstance(element.getAttribute("description"));
+            this.linkStyle = element.getAttribute("link-style");
+            this.linkType = element.getAttribute("link-type");
+            this.modelFormField = modelFormField;
+            List<? extends Element> parameterElementList = UtilXml.childElementList(element, "parameter");
+            if (!parameterElementList.isEmpty()) {
+                List<WidgetWorker.Parameter> parameterList = new ArrayList<WidgetWorker.Parameter>(parameterElementList.size());
+                for (Element parameterElement : parameterElementList) {
+                    parameterList.add(new WidgetWorker.Parameter(parameterElement));
+                }
+                this.parameterList = Collections.unmodifiableList(parameterList);
+            } else {
+                this.parameterList = Collections.emptyList();
+
+            }
+            this.requestConfirmation = "true".equals(element.getAttribute("request-confirmation"));
+            this.target = FlexibleStringExpander.getInstance(element.getAttribute("target"));
+            this.targetType = element.getAttribute("target-type");
+            this.targetWindowExdr = FlexibleStringExpander.getInstance(element.getAttribute("target-window"));
+            this.useWhen = FlexibleStringExpander.getInstance(element.getAttribute("use-when"));
+        }
+
+        public SubHyperlink(SubHyperlink original, ModelFormField modelFormField) {
+            this.autoEntityParameters = original.autoEntityParameters;
+            this.autoServiceParameters = original.autoServiceParameters;
+            this.confirmationMsgExdr = original.confirmationMsgExdr;
+            this.description = original.description;
+            this.linkStyle = original.linkStyle;
+            this.linkType = original.linkType;
+            this.modelFormField = modelFormField;
+            this.parameterList = original.parameterList;
+            this.requestConfirmation = original.requestConfirmation;
+            this.target = original.target;
+            this.targetType = original.targetType;
+            this.targetWindowExdr = original.targetWindowExdr;
+            this.useWhen = original.useWhen;
+        }
+
+        public WidgetWorker.AutoEntityParameters getAutoEntityParameters() {
+            return autoEntityParameters;
+        }
+
+        public WidgetWorker.AutoServiceParameters getAutoServiceParameters() {
+            return autoServiceParameters;
+        }
+
+        public String getConfirmation(Map<String, Object> context) {
+            String message = getConfirmationMsg(context);
+            if (UtilValidate.isNotEmpty(message))
+                return message;
+
+            if (getRequestConfirmation()) {
+                String defaultMessage = UtilProperties.getPropertyValue("general", "default.confirmation.message",
+                        "${uiLabelMap.CommonConfirm}");
+                return FlexibleStringExpander.expandString(defaultMessage, context);
+            }
+            return "";
+        }
+
+        public String getConfirmationMsg(Map<String, Object> context) {
+            return this.confirmationMsgExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getConfirmationMsgExdr() {
+            return confirmationMsgExdr;
+        }
+
+        public FlexibleStringExpander getDescription() {
+            return description;
+        }
+
+        public String getDescription(Map<String, Object> context) {
+            if (this.description != null) {
+                return this.description.expandString(context);
+            } else {
+                return "";
+            }
+        }
+
+        public String getLinkStyle() {
+            return this.linkStyle;
+        }
+
+        public String getLinkType() {
+            return this.linkType;
+        }
+
+        public ModelFormField getModelFormField() {
+            return this.modelFormField;
+        }
+
+        public List<WidgetWorker.Parameter> getParameterList() {
+            return parameterList;
+        }
+
+        public Map<String, String> getParameterMap(Map<String, Object> context) {
+            Map<String, String> fullParameterMap = new HashMap<String, String>();
+
+            /* leaving this here... may want to add it at some point like the hyperlink element:
+            Map<String, String> addlParamMap = this.parametersMapAcsr.get(context);
+            if (addlParamMap != null) {
+                fullParameterMap.putAll(addlParamMap);
+            }
+            */
+
+            for (WidgetWorker.Parameter parameter : this.parameterList) {
+                fullParameterMap.put(parameter.getName(), parameter.getValue(context));
+            }
+
+            if (autoServiceParameters != null) {
+                fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, getModelFormField().getModelForm()
+                        .getDefaultServiceName()));
+            }
+            if (autoEntityParameters != null) {
+                fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, this.getModelFormField().getModelForm()
+                        .getDefaultEntityName()));
+            }
+
+            return fullParameterMap;
+        }
+
+        public boolean getRequestConfirmation() {
+            return this.requestConfirmation;
+        }
+
+        public FlexibleStringExpander getTarget() {
+            return target;
+        }
+
+        public String getTarget(Map<String, Object> context) {
+            if (this.target != null) {
+                return this.target.expandString(context);
+            } else {
+                return "";
+            }
+        }
+
+        public String getTargetType() {
+            if (UtilValidate.isNotEmpty(this.targetType))
+                return this.targetType;
+            return HyperlinkField.DEFAULT_TARGET_TYPE;
+        }
+
+        public String getTargetWindow(Map<String, Object> context) {
+            String targetWindow = this.targetWindowExdr.expandString(context);
+            return targetWindow;
+        }
+
+        public FlexibleStringExpander getTargetWindowExdr() {
+            return targetWindowExdr;
+        }
+
+        public FlexibleStringExpander getUseWhen() {
+            return useWhen;
+        }
+
+        public String getUseWhen(Map<String, Object> context) {
+            if (this.useWhen != null) {
+                return this.useWhen.expandString(context);
+            } else {
+                return "";
+            }
+        }
+
+        public boolean shouldUse(Map<String, Object> context) {
+            boolean shouldUse = true;
+            String useWhen = this.getUseWhen(context);
+            if (UtilValidate.isNotEmpty(useWhen)) {
+                try {
+                    Interpreter bsh = (Interpreter) context.get("bshInterpreter");
+                    if (bsh == null) {
+                        bsh = BshUtil.makeInterpreter(context);
+                        context.put("bshInterpreter", bsh);
+                    }
+
+                    Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(useWhen));
+
+                    // retVal should be a Boolean, if not something weird is up...
+                    if (retVal instanceof Boolean) {
+                        Boolean boolVal = (Boolean) retVal;
+                        shouldUse = boolVal.booleanValue();
+                    } else {
+                        throw new IllegalArgumentException("Return value from target condition eval was not a Boolean: "
+                                + retVal.getClass().getName() + " [" + retVal + "]");
+                    }
+                } catch (EvalError e) {
+                    String errmsg = "Error evaluating BeanShell target conditions";
+                    Debug.logError(e, errmsg, module);
+                    throw new IllegalArgumentException(errmsg);
+                }
+            }
+            return shouldUse;
+        }
+    }
+
+    /**
+     * Models the &lt;submit&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class SubmitField extends FieldInfo {
+        private final FlexibleStringExpander backgroundSubmitRefreshTargetExdr;
+        private final String buttonType;
+        private final FlexibleStringExpander confirmationMsgExdr;
+        private final FlexibleStringExpander imageLocation;
+        private final boolean requestConfirmation;
+
+        public SubmitField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+            this.backgroundSubmitRefreshTargetExdr = FlexibleStringExpander.getInstance(element
+                    .getAttribute("background-submit-refresh-target"));
+            this.buttonType = element.getAttribute("button-type");
+            this.confirmationMsgExdr = FlexibleStringExpander.getInstance(element.getAttribute("confirmation-message"));
+            this.imageLocation = FlexibleStringExpander.getInstance(element.getAttribute("image-location"));
+            this.requestConfirmation = "true".equals(element.getAttribute("request-confirmation"));
+        }
+
+        public SubmitField(int fieldInfo, ModelFormField modelFormField) {
+            super(fieldInfo, FieldInfo.SUBMIT, modelFormField);
+            this.backgroundSubmitRefreshTargetExdr = FlexibleStringExpander.getInstance("");
+            this.buttonType = "";
+            this.confirmationMsgExdr = FlexibleStringExpander.getInstance("");
+            this.imageLocation = FlexibleStringExpander.getInstance("");
+            this.requestConfirmation = false;
+        }
+
+        public SubmitField(ModelFormField modelFormField) {
+            this(FieldInfo.SOURCE_EXPLICIT, modelFormField);
+        }
+
+        private SubmitField(SubmitField original, ModelFormField modelFormField) {
+            super(original.getFieldSource(), original.getFieldType(), modelFormField);
+            this.buttonType = original.buttonType;
+            this.imageLocation = original.imageLocation;
+            this.backgroundSubmitRefreshTargetExdr = original.backgroundSubmitRefreshTargetExdr;
+            this.requestConfirmation = original.requestConfirmation;
+            this.confirmationMsgExdr = original.confirmationMsgExdr;
+        }
+
+        @Override
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new SubmitField(this, modelFormField);
+        }
+
+        public String getBackgroundSubmitRefreshTarget(Map<String, Object> context) {
+            return this.backgroundSubmitRefreshTargetExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getBackgroundSubmitRefreshTargetExdr() {
+            return backgroundSubmitRefreshTargetExdr;
+        }
+
+        public String getButtonType() {
+            return buttonType;
+        }
+
+        public String getConfirmation(Map<String, Object> context) {
+            String message = getConfirmationMsg(context);
+            if (UtilValidate.isNotEmpty(message))
+                return message;
+            else if (getRequestConfirmation()) {
+                String defaultMessage = UtilProperties.getPropertyValue("general", "default.confirmation.message",
+                        "${uiLabelMap.CommonConfirm}");
+                return FlexibleStringExpander.expandString(defaultMessage, context);
+            }
+            return "";
+        }
+
+        public String getConfirmationMsg(Map<String, Object> context) {
+            return this.confirmationMsgExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getConfirmationMsgExdr() {
+            return confirmationMsgExdr;
+        }
+
+        public FlexibleStringExpander getImageLocation() {
+            return imageLocation;
+        }
+
+        public String getImageLocation(Map<String, Object> context) {
+            return this.imageLocation.expandString(context);
+        }
+
+        public boolean getRequestConfirmation() {
+            return this.requestConfirmation;
+        }
+
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderSubmitField(writer, context, this);
+        }
+    }
+
+    /**
+     * Models the &lt;textarea&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class TextareaField extends FieldInfo {
+        private final int cols;
+        private final FlexibleStringExpander defaultValue;
+        private final boolean readOnly;
+        private final int rows;
+        private final FlexibleStringExpander visualEditorButtons;
+        private final boolean visualEditorEnable;
+
+        public TextareaField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+            int cols = 60;
+            String colsStr = element.getAttribute("cols");
+            if (!colsStr.isEmpty()) {
+                try {
+                    cols = Integer.parseInt(colsStr);
+                } catch (Exception e) {
+                    if (UtilValidate.isNotEmpty(colsStr)) {
+                        Debug.logError("Could not parse the size value of the text element: [" + colsStr
+                                + "], setting to default of " + cols, module);
+                    }
+                }
+            }
+            this.cols = cols;
+            this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value"));
+            this.readOnly = "true".equals(element.getAttribute("read-only"));
+            int rows = 2;
+            String rowsStr = element.getAttribute("rows");
+            if (!rowsStr.isEmpty()) {
+                try {
+                    rows = Integer.parseInt(rowsStr);
+                } catch (Exception e) {
+                    if (UtilValidate.isNotEmpty(rowsStr)) {
+                        Debug.logError("Could not parse the size value of the text element: [" + rowsStr
+                                + "], setting to default of " + rows, module);
+                    }
+                }
+            }
+            this.rows = rows;
+            this.visualEditorButtons = FlexibleStringExpander.getInstance(element.getAttribute("visual-editor-buttons"));
+            this.visualEditorEnable = "true".equals(element.getAttribute("visual-editor-enable"));
+        }
+
+        public TextareaField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, FieldInfo.TEXTAREA, modelFormField);
+            this.cols = 60;
+            this.defaultValue = FlexibleStringExpander.getInstance("");
+            this.readOnly = false;
+            this.rows = 2;
+            this.visualEditorButtons = FlexibleStringExpander.getInstance("");
+            this.visualEditorEnable = false;
+        }
+
+        public TextareaField(ModelFormField modelFormField) {
+            this(FieldInfo.SOURCE_EXPLICIT, modelFormField);
+        }
+
+        private TextareaField(TextareaField original, ModelFormField modelFormField) {
+            super(original.getFieldSource(), original.getFieldType(), modelFormField);
+            this.defaultValue = original.defaultValue;
+            this.visualEditorEnable = original.visualEditorEnable;
+            this.visualEditorButtons = original.visualEditorButtons;
+            this.readOnly = original.readOnly;
+            this.cols = original.cols;
+            this.rows = original.rows;
+        }
+
+        @Override
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new TextareaField(this, modelFormField);
+        }
+
+        public int getCols() {
+            return cols;
+        }
+
+        public FlexibleStringExpander getDefaultValue() {
+            return defaultValue;
         }
 
         public String getDefaultValue(Map<String, Object> context) {
@@ -4184,61 +3594,136 @@
             }
         }
 
-        public String getValue(Map<String, Object> context) {
-            if (UtilValidate.isNotEmpty(this.value))
-                return this.value.expandString(context);
-            return getModelFormField().getEntry(context);
+        public int getRows() {
+            return rows;
         }
 
-        public void setValue(String string) {
-            this.value = FlexibleStringExpander.getInstance(string);
+        public FlexibleStringExpander getVisualEditorButtons() {
+            return visualEditorButtons;
         }
 
-        public String getDescription(Map<String, Object> context) {
-            if (UtilValidate.isNotEmpty(this.description))
-                return this.description.expandString(context);
-            return "";
+        public String getVisualEditorButtons(Map<String, Object> context) {
+            return this.visualEditorButtons.expandString(context);
         }
 
-        public void setDescription(String description) {
-            this.description = FlexibleStringExpander.getInstance(description);
+        public boolean getVisualEditorEnable() {
+            return this.visualEditorEnable;
         }
 
-        public String getAlternate(Map<String, Object> context) {
-            if (UtilValidate.isNotEmpty(this.alternate))
-                return this.alternate.expandString(context);
-            return "";
+        public boolean isReadOnly() {
+            return readOnly;
         }
 
-        public void setAlternate(String alternate) {
-            this.alternate = FlexibleStringExpander.getInstance(alternate);
-        }
-
-        public String getStyle(Map<String, Object> context) {
-            if (UtilValidate.isNotEmpty(this.style))
-                return this.style.expandString(context);
-            return "";
-        }
-
-        public void setStyle(String style) {
-            this.style = FlexibleStringExpander.getInstance(style);
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderTextareaField(writer, context, this);
         }
     }
 
-    public static class ContainerField extends FieldInfo {
-        @Deprecated
-        protected String id;
+    /**
+     * Models the &lt;text&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class TextField extends FieldInfo {
+        private final boolean clientAutocompleteField;
+        private final FlexibleStringExpander defaultValue;
+        private final boolean disabled;
+        private final String mask;
+        private final Integer maxlength;
+        private final FlexibleStringExpander placeholder;
+        private final boolean readonly;
+        private final int size;
+        private final SubHyperlink subHyperlink;
 
-        public ContainerField(Element element, ModelFormField modelFormField) {
+        public TextField(Element element, ModelFormField modelFormField) {
             super(element, modelFormField);
+            this.clientAutocompleteField = !"false".equals(element.getAttribute("client-autocomplete-field"));
+            this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value"));
+            this.disabled = "true".equals(element.getAttribute("disabled"));
+            this.mask = element.getAttribute("mask");
+            Integer maxlength = null;
+            String maxlengthStr = element.getAttribute("maxlength");
+            if (!maxlengthStr.isEmpty()) {
+                try {
+                    maxlength = Integer.valueOf(maxlengthStr);
+                } catch (Exception e) {
+                    Debug.logError("Could not parse the max-length value of the text element: [" + maxlengthStr
+                            + "], setting to null; default of no maxlength will be used", module);
+                }
+            }
+            this.maxlength = maxlength;
+            this.placeholder = FlexibleStringExpander.getInstance(element.getAttribute("placeholder"));
+            this.readonly = "true".equals(element.getAttribute("read-only"));
+            int size = 25;
+            String sizeStr = element.getAttribute("size");
+            if (!sizeStr.isEmpty()) {
+                try {
+                    size = Integer.parseInt(sizeStr);
+                } catch (Exception e) {
+                    Debug.logError("Could not parse the size value of the text element: [" + sizeStr
+                            + "], setting to the default of " + size, module);
+                }
+            }
+            this.size = size;
+            Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink");
+            if (subHyperlinkElement != null) {
+                this.subHyperlink = new SubHyperlink(subHyperlinkElement, this.getModelFormField());
+            } else {
+                this.subHyperlink = null;
+            }
         }
 
-        private ContainerField(ContainerField original, ModelFormField modelFormField) {
-            super(original.getFieldSource(), original.getFieldType(), modelFormField);
+        protected TextField(int fieldSource, int size, Integer maxlength, ModelFormField modelFormField) {
+            super(fieldSource, FieldInfo.TEXT, modelFormField);
+            this.clientAutocompleteField = true;
+            this.defaultValue = FlexibleStringExpander.getInstance("");
+            this.disabled = false;
+            this.mask = "";
+            this.maxlength = maxlength;
+            this.placeholder = FlexibleStringExpander.getInstance("");
+            this.readonly = false;
+            this.size = size;
+            this.subHyperlink = null;
         }
 
-        public ContainerField(int fieldSource, int fieldType, ModelFormField modelFormField) {
+        private TextField(int fieldSource, int fieldType, ModelFormField modelFormField) {
             super(fieldSource, fieldType, modelFormField);
+            this.clientAutocompleteField = true;
+            this.defaultValue = FlexibleStringExpander.getInstance("");
+            this.disabled = false;
+            this.mask = "";
+            this.maxlength = null;
+            this.placeholder = FlexibleStringExpander.getInstance("");
+            this.readonly = false;
+            this.size = 25;
+            this.subHyperlink = null;
+        }
+
+        public TextField(int fieldSource, ModelFormField modelFormField) {
+            this(fieldSource, FieldInfo.TEXT, modelFormField);
+        }
+
+        public TextField(ModelFormField modelFormField) {
+            this(FieldInfo.SOURCE_EXPLICIT, FieldInfo.TEXT, modelFormField);
+        }
+
+        protected TextField(TextField original, ModelFormField modelFormField) {
+            super(original.getFieldSource(), original.getFieldType(), modelFormField);
+            this.clientAutocompleteField = original.clientAutocompleteField;
+            this.defaultValue = original.defaultValue;
+            this.mask = original.mask;
+            this.placeholder = original.placeholder;
+            this.size = original.size;
+            this.maxlength = original.maxlength;
+            this.disabled = original.disabled;
+            this.readonly = original.readonly;
+            if (original.subHyperlink != null) {
+                this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField);
+            } else {
+                this.subHyperlink = null;
+            }
         }
 
         @Override
@@ -4248,23 +3733,143 @@
 
         @Override
         public FieldInfo copy(ModelFormField modelFormField) {
-            return new ContainerField(this, modelFormField);
+            return new TextField(this, modelFormField);
+        }
+
+        public boolean getClientAutocompleteField() {
+            return this.clientAutocompleteField;
+        }
+
+        public FlexibleStringExpander getDefaultValue() {
+            return defaultValue;
+        }
+
+        public String getDefaultValue(Map<String, Object> context) {
+            if (this.defaultValue != null) {
+                return this.defaultValue.expandString(context);
+            } else {
+                return "";
+            }
+        }
+
+        public boolean getDisabled() {
+            return this.disabled;
+        }
+
+        public String getMask() {
+            return this.mask;
+        }
+
+        public Integer getMaxlength() {
+            return maxlength;
+        }
+
+        public FlexibleStringExpander getPlaceholder() {
+            return placeholder;
+        }
+
+        public String getPlaceholder(Map<String, Object> context) {
+            return this.placeholder.expandString(context);
+        }
+
+        public boolean getReadonly() {
+            return this.readonly;
+        }
+
+        public int getSize() {
+            return size;
+        }
+
+        public SubHyperlink getSubHyperlink() {
+            return this.subHyperlink;
         }
 
         @Override
         public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                 throws IOException {
-            formStringRenderer.renderContainerFindField(writer, context, this);
+            formStringRenderer.renderTextField(writer, context, this);
+        }
+    }
+
+    /**
+     * Models the &lt;text-find&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class TextFindField extends TextField {
+        private final String defaultOption;
+        private final boolean hideIgnoreCase;
+        private final boolean hideOptions;
+        private final boolean ignoreCase;
+
+        public TextFindField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+            if (element.hasAttribute("default-option")) {
+                this.defaultOption = element.getAttribute("default-option");
+            } else {
+                this.defaultOption = UtilProperties.getPropertyValue("widget", "widget.form.defaultTextFindOption", "contains");
+            }
+            this.hideIgnoreCase = "true".equals(element.getAttribute("hide-options"))
+                    || "ignore-case".equals(element.getAttribute("hide-options")) ? true : false;
+            this.hideOptions = "true".equals(element.getAttribute("hide-options"))
+                    || "options".equals(element.getAttribute("hide-options")) ? true : false;
+            this.ignoreCase = "true".equals(element.getAttribute("ignore-case"));
         }
 
-        @Deprecated
-        public String getId() {
-            return id;
+        public TextFindField(int fieldSource, int size, Integer maxlength, ModelFormField modelFormField) {
+            super(fieldSource, size, maxlength, modelFormField);
+            this.defaultOption = UtilProperties.getPropertyValue("widget", "widget.form.defaultTextFindOption", "contains");
+            this.hideIgnoreCase = false;
+            this.hideOptions = false;
+            this.ignoreCase = true;
         }
 
-        @Deprecated
-        public void setId(String id) {
-            this.id = id;
+        public TextFindField(int fieldSource, ModelFormField modelFormField) {
+            super(fieldSource, modelFormField);
+            this.defaultOption = UtilProperties.getPropertyValue("widget", "widget.form.defaultTextFindOption", "contains");
+            this.hideIgnoreCase = false;
+            this.hideOptions = false;
+            this.ignoreCase = true;
+        }
+
+        private TextFindField(TextFindField original, ModelFormField modelFormField) {
+            super(original, modelFormField);
+            this.ignoreCase = original.ignoreCase;
+            this.hideIgnoreCase = original.hideIgnoreCase;
+            this.defaultOption = original.defaultOption;
+            this.hideOptions = original.hideOptions;
+        }
+
+        @Override
+        public void accept(ModelFieldVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        @Override
+        public FieldInfo copy(ModelFormField modelFormField) {
+            return new TextFindField(this, modelFormField);
+        }
+
+        public String getDefaultOption() {
+            return this.defaultOption;
+        }
+
+        public boolean getHideIgnoreCase() {
+            return this.hideIgnoreCase;
+        }
+
+        public boolean getHideOptions() {
+            return this.hideOptions;
+        }
+
+        public boolean getIgnoreCase() {
+            return this.ignoreCase;
+        }
+
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderTextFindField(writer, context, this);
         }
     }
 }
diff --git a/framework/widget/src/org/ofbiz/widget/form/ModelFormFieldBuilder.java b/framework/widget/src/org/ofbiz/widget/form/ModelFormFieldBuilder.java
new file mode 100644
index 0000000..e77d8d5
--- /dev/null
+++ b/framework/widget/src/org/ofbiz/widget/form/ModelFormFieldBuilder.java
@@ -0,0 +1,921 @@
+/*******************************************************************************

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ * http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ *******************************************************************************/

+package org.ofbiz.widget.form;

+

+import java.util.ArrayList;

+import java.util.List;

+import java.util.Map;

+

+import org.ofbiz.base.util.Debug;

+import org.ofbiz.base.util.UtilValidate;

+import org.ofbiz.base.util.UtilXml;

+import org.ofbiz.base.util.collections.FlexibleMapAccessor;

+import org.ofbiz.base.util.string.FlexibleStringExpander;

+import org.ofbiz.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.form.ModelForm.UpdateArea;

+import org.ofbiz.widget.form.ModelFormField.CheckField;

+import org.ofbiz.widget.form.ModelFormField.ContainerField;

+import org.ofbiz.widget.form.ModelFormField.DateFindField;

+import org.ofbiz.widget.form.ModelFormField.DateTimeField;

+import org.ofbiz.widget.form.ModelFormField.DisplayEntityField;

+import org.ofbiz.widget.form.ModelFormField.DisplayField;

+import org.ofbiz.widget.form.ModelFormField.DropDownField;

+import org.ofbiz.widget.form.ModelFormField.FileField;

+import org.ofbiz.widget.form.ModelFormField.HiddenField;

+import org.ofbiz.widget.form.ModelFormField.HyperlinkField;

+import org.ofbiz.widget.form.ModelFormField.IgnoredField;

+import org.ofbiz.widget.form.ModelFormField.ImageField;

+import org.ofbiz.widget.form.ModelFormField.LookupField;

+import org.ofbiz.widget.form.ModelFormField.OptionSource;

+import org.ofbiz.widget.form.ModelFormField.PasswordField;

+import org.ofbiz.widget.form.ModelFormField.RadioField;

+import org.ofbiz.widget.form.ModelFormField.RangeFindField;

+import org.ofbiz.widget.form.ModelFormField.ResetField;

+import org.ofbiz.widget.form.ModelFormField.SubmitField;

+import org.ofbiz.widget.form.ModelFormField.TextField;

+import org.ofbiz.widget.form.ModelFormField.TextFindField;

+import org.ofbiz.widget.form.ModelFormField.TextareaField;

+import org.w3c.dom.Element;

+

+/**

+ * A <code>ModelFormField</code> builder.

+ */

+public class ModelFormFieldBuilder {

+

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

+

+    private FlexibleStringExpander action = FlexibleStringExpander.getInstance("");;

+    private String attributeName = "";

+    private boolean encodeOutput = true;

+    private String entityName = "";

+    private FlexibleMapAccessor<Object> entryAcsr = null;

+    private String event = "";

+    private FieldInfo fieldInfo = null;

+    private String fieldName = "";

+    private String fieldType = null;

+    private String headerLink = "";

+    private String headerLinkStyle = "";

+    private String idName = "";

+    private FlexibleMapAccessor<Map<String, ? extends Object>> mapAcsr = null;

+    private ModelForm modelForm = null;

+    private String name = "";

+    private List<UpdateArea> onChangeUpdateAreas = new ArrayList<UpdateArea>();

+    private List<UpdateArea> onClickUpdateAreas = new ArrayList<UpdateArea>();

+    private String parameterName = "";

+    private Integer position = null;

+    private String redWhen = "";

+    private Boolean requiredField = null;

+    private String requiredFieldStyle = "";

+    private boolean separateColumn = false;

+    private String serviceName = "";

+    private Boolean sortField = null;

+    private String sortFieldAscStyle = "";

+    private String sortFieldDescStyle = "";

+    private String sortFieldHelpText = "";

+    private String sortFieldStyle = "";

+    private FlexibleStringExpander title = FlexibleStringExpander.getInstance("");;

+    private String titleAreaStyle = "";

+    private String titleStyle = "";

+    private FlexibleStringExpander tooltip = FlexibleStringExpander.getInstance("");;

+    private String tooltipStyle = "";

+    private FlexibleStringExpander useWhen = FlexibleStringExpander.getInstance("");;

+    private String widgetAreaStyle = "";

+    private String widgetStyle = "";

+

+    public ModelFormFieldBuilder() {

+    }

+

+    /** XML Constructor */

+    public ModelFormFieldBuilder(Element fieldElement, ModelForm modelForm, ModelReader entityModelReader,

+            DispatchContext dispatchContext) {

+        String name = fieldElement.getAttribute("name");

+        this.action = FlexibleStringExpander.getInstance(fieldElement.getAttribute("action"));

+        this.attributeName = UtilXml.checkEmpty(fieldElement.getAttribute("attribute-name"), name);

+        this.encodeOutput = !"false".equals(fieldElement.getAttribute("encode-output"));

+        this.entityName = fieldElement.getAttribute("entity-name");

+        this.entryAcsr = FlexibleMapAccessor.getInstance(UtilXml.checkEmpty(fieldElement.getAttribute("entry-name"), name));

+        this.event = fieldElement.getAttribute("event");

+        this.fieldName = UtilXml.checkEmpty(fieldElement.getAttribute("field-name"), name);

+        this.headerLink = fieldElement.getAttribute("header-link");

+        this.headerLinkStyle = fieldElement.getAttribute("header-link-style");

+        this.idName = fieldElement.getAttribute("id-name");

+        this.mapAcsr = FlexibleMapAccessor.getInstance(fieldElement.getAttribute("map-name"));

+        this.modelForm = modelForm;

+        this.name = name;

+        this.parameterName = UtilXml.checkEmpty(fieldElement.getAttribute("parameter-name"), name);

+        String positionAtttr = fieldElement.getAttribute("position");

+        Integer position = null;

+        if (!positionAtttr.isEmpty()) {

+            position = Integer.parseInt(positionAtttr);

+        }

+        this.position = position;

+        this.redWhen = fieldElement.getAttribute("red-when");

+        String requiredField = fieldElement.getAttribute("required-field");

+        this.requiredField = requiredField.isEmpty() ? null : "true".equals(requiredField);

+        this.requiredFieldStyle = fieldElement.getAttribute("required-field-style");

+        this.separateColumn = "true".equals(fieldElement.getAttribute("separate-column"));

+        this.serviceName = fieldElement.getAttribute("service-name");

+        String sortField = fieldElement.getAttribute("sort-field");

+        this.sortField = sortField.isEmpty() ? null : "true".equals(sortField);

+        this.sortFieldAscStyle = fieldElement.getAttribute("sort-field-asc-style");

+        this.sortFieldDescStyle = fieldElement.getAttribute("sort-field-desc-style");

+        this.sortFieldHelpText = fieldElement.getAttribute("sort-field-help-text");

+        this.sortFieldStyle = fieldElement.getAttribute("sort-field-style");

+        this.title = FlexibleStringExpander.getInstance(fieldElement.getAttribute("title"));

+        this.titleAreaStyle = fieldElement.getAttribute("title-area-style");

+        this.titleStyle = fieldElement.getAttribute("title-style");

+        this.tooltip = FlexibleStringExpander.getInstance(fieldElement.getAttribute("tooltip"));

+        this.tooltipStyle = fieldElement.getAttribute("tooltip-style");

+        this.useWhen = FlexibleStringExpander.getInstance(fieldElement.getAttribute("use-when"));

+        this.widgetAreaStyle = fieldElement.getAttribute("widget-area-style");

+        this.widgetStyle = fieldElement.getAttribute("widget-style");

+        Element childElement = null;

+        List<? extends Element> subElements = UtilXml.childElementList(fieldElement);

+        for (Element subElement : subElements) {

+            String subElementName = subElement.getTagName();

+            if ("on-field-event-update-area".equals(subElementName)) {

+                UpdateArea updateArea = new UpdateArea(subElement);

+                if ("change".equals(updateArea.getEventType()))

+                    onChangeUpdateAreas.add(updateArea);

+                else if ("click".equals(updateArea.getEventType()))

+                    onClickUpdateAreas.add(updateArea);

+            } else {

+                if (this.fieldType != null) {

+                    throw new IllegalArgumentException("Multiple field types found: " + this.fieldType + ", " + subElementName);

+                }

+                this.fieldType = subElementName;

+                childElement = subElement;

+            }

+        }

+        if (UtilValidate.isEmpty(this.fieldType)) {

+            this.induceFieldInfo(modelForm, null, entityModelReader, dispatchContext);

+        } else if ("display".equals(this.fieldType))

+            this.fieldInfo = new DisplayField(childElement, null);

+        else if ("display-entity".equals(this.fieldType))

+            this.fieldInfo = new DisplayEntityField(childElement, null);

+        else if ("hyperlink".equals(this.fieldType))

+            this.fieldInfo = new HyperlinkField(childElement, null);

+        else if ("text".equals(this.fieldType))

+            this.fieldInfo = new TextField(childElement, null);

+        else if ("textarea".equals(this.fieldType))

+            this.fieldInfo = new TextareaField(childElement, null);

+        else if ("date-time".equals(this.fieldType))

+            this.fieldInfo = new DateTimeField(childElement, null);

+        else if ("drop-down".equals(this.fieldType))

+            this.fieldInfo = new DropDownField(childElement, null);

+        else if ("check".equals(this.fieldType))

+            this.fieldInfo = new CheckField(childElement, null);

+        else if ("radio".equals(this.fieldType))

+            this.fieldInfo = new RadioField(childElement, null);

+        else if ("submit".equals(this.fieldType))

+            this.fieldInfo = new SubmitField(childElement, null);

+        else if ("reset".equals(this.fieldType))

+            this.fieldInfo = new ResetField(childElement, null);

+        else if ("hidden".equals(this.fieldType))

+            this.fieldInfo = new HiddenField(childElement, null);

+        else if ("ignored".equals(this.fieldType))

+            this.fieldInfo = new IgnoredField(childElement, null);

+        else if ("text-find".equals(this.fieldType))

+            this.fieldInfo = new TextFindField(childElement, null);

+        else if ("date-find".equals(this.fieldType))

+            this.fieldInfo = new DateFindField(childElement, null);

+        else if ("range-find".equals(this.fieldType))

+            this.fieldInfo = new RangeFindField(childElement, null);

+        else if ("lookup".equals(this.fieldType))

+            this.fieldInfo = new LookupField(childElement, null);

+        else if ("file".equals(this.fieldType))

+            this.fieldInfo = new FileField(childElement, null);

+        else if ("password".equals(this.fieldType))

+            this.fieldInfo = new PasswordField(childElement, null);

+        else if ("image".equals(this.fieldType))

+            this.fieldInfo = new ImageField(childElement, null);

+        else if ("container".equals(this.fieldType))

+            this.fieldInfo = new ContainerField(childElement, null);

+        else

+            throw new IllegalArgumentException("The field sub-element with name " + this.fieldType + " is not supported");

+    }

+

+    public ModelFormFieldBuilder(ModelFormField modelFormField) {

+        this.action = modelFormField.getAction();

+        this.attributeName = modelFormField.getAttributeName();

+        this.encodeOutput = modelFormField.getEncodeOutput();

+        this.entityName = modelFormField.getEntityName();

+        this.entryAcsr = modelFormField.getEntryAcsr();

+        this.event = modelFormField.getEvent();

+        this.fieldInfo = modelFormField.getFieldInfo();

+        this.fieldName = modelFormField.getFieldName();

+        this.headerLink = modelFormField.getHeaderLink();

+        this.headerLinkStyle = modelFormField.getHeaderLinkStyle();

+        this.idName = modelFormField.getIdName();

+        this.mapAcsr = modelFormField.getMapAcsr();

+        this.modelForm = modelFormField.getModelForm();

+        this.name = modelFormField.getName();

+        this.onChangeUpdateAreas.addAll(modelFormField.getOnChangeUpdateAreas());

+        this.onClickUpdateAreas.addAll(modelFormField.getOnClickUpdateAreas());

+        this.parameterName = modelFormField.getParameterName();

+        this.position = modelFormField.getPosition();

+        this.redWhen = modelFormField.getRedWhen();

+        this.requiredField = modelFormField.getRequiredField();

+        this.requiredFieldStyle = modelFormField.getRequiredFieldStyle();

+        this.separateColumn = modelFormField.getSeparateColumn();

+        this.serviceName = modelFormField.getServiceName();

+        this.sortField = modelFormField.getSortField();

+        this.sortFieldAscStyle = modelFormField.getSortFieldAscStyle();

+        this.sortFieldDescStyle = modelFormField.getSortFieldDescStyle();

+        this.sortFieldHelpText = modelFormField.getSortFieldHelpText();

+        this.sortFieldStyle = modelFormField.getSortFieldStyle();

+        this.title = modelFormField.getTitle();

+        this.titleAreaStyle = modelFormField.getTitleAreaStyle();

+        this.titleStyle = modelFormField.getTitleStyle();

+        this.tooltip = modelFormField.getTooltip();

+        this.tooltipStyle = modelFormField.getTooltipStyle();

+        this.useWhen = modelFormField.getUseWhen();

+        this.widgetAreaStyle = modelFormField.getWidgetAreaStyle();

+        this.widgetStyle = modelFormField.getWidgetStyle();

+    }

+

+    public ModelFormFieldBuilder(ModelFormFieldBuilder builder) {

+        this.action = builder.getAction();

+        this.attributeName = builder.getAttributeName();

+        this.encodeOutput = builder.getEncodeOutput();

+        this.entityName = builder.getEntityName();

+        this.entryAcsr = builder.getEntryAcsr();

+        this.event = builder.getEvent();

+        this.fieldInfo = builder.getFieldInfo();

+        this.fieldName = builder.getFieldName();

+        this.headerLink = builder.getHeaderLink();

+        this.headerLinkStyle = builder.getHeaderLinkStyle();

+        this.idName = builder.getIdName();

+        this.mapAcsr = builder.getMapAcsr();

+        this.modelForm = builder.getModelForm();

+        this.name = builder.getName();

+        this.onChangeUpdateAreas.addAll(builder.getOnChangeUpdateAreas());

+        this.onClickUpdateAreas.addAll(builder.getOnClickUpdateAreas());

+        this.parameterName = builder.getParameterName();

+        this.position = builder.getPosition();

+        this.redWhen = builder.getRedWhen();

+        this.requiredField = builder.getRequiredField();

+        this.requiredFieldStyle = builder.getRequiredFieldStyle();

+        this.separateColumn = builder.getSeparateColumn();

+        this.serviceName = builder.getServiceName();

+        this.sortField = builder.getSortField();

+        this.sortFieldAscStyle = builder.getSortFieldAscStyle();

+        this.sortFieldDescStyle = builder.getSortFieldDescStyle();

+        this.sortFieldHelpText = builder.getSortFieldHelpText();

+        this.sortFieldStyle = builder.getSortFieldStyle();

+        this.title = builder.getTitle();

+        this.titleAreaStyle = builder.getTitleAreaStyle();

+        this.titleStyle = builder.getTitleStyle();

+        this.tooltip = builder.getTooltip();

+        this.tooltipStyle = builder.getTooltipStyle();

+        this.useWhen = builder.getUseWhen();

+        this.widgetAreaStyle = builder.getWidgetAreaStyle();

+        this.widgetStyle = builder.getWidgetStyle();

+    }

+

+    public ModelFormFieldBuilder addOnChangeUpdateArea(UpdateArea onChangeUpdateArea) {

+        this.onChangeUpdateAreas.add(onChangeUpdateArea);

+        return this;

+    }

+

+    public ModelFormFieldBuilder addOnClickUpdateArea(UpdateArea onClickUpdateArea) {

+        this.onClickUpdateAreas.add(onClickUpdateArea);

+        return this;

+    }

+

+    public ModelFormField build() {

+        return ModelFormField.from(this);

+    }

+

+    public FlexibleStringExpander getAction() {

+        return action;

+    }

+

+    public String getAttributeName() {

+        return attributeName;

+    }

+

+    public boolean getEncodeOutput() {

+        return encodeOutput;

+    }

+

+    public String getEntityName() {

+        return entityName;

+    }

+

+    public FlexibleMapAccessor<Object> getEntryAcsr() {

+        return entryAcsr;

+    }

+

+    public String getEvent() {

+        return event;

+    }

+

+    public FieldInfo getFieldInfo() {

+        return fieldInfo;

+    }

+

+    public String getFieldName() {

+        return fieldName;

+    }

+

+    public String getFieldType() {

+        return fieldType;

+    }

+

+    public String getHeaderLink() {

+        return headerLink;

+    }

+

+    public String getHeaderLinkStyle() {

+        return headerLinkStyle;

+    }

+

+    public String getIdName() {

+        return idName;

+    }

+

+    public FlexibleMapAccessor<Map<String, ? extends Object>> getMapAcsr() {

+        return mapAcsr;

+    }

+

+    public ModelForm getModelForm() {

+        return modelForm;

+    }

+

+    public String getName() {

+        return name;

+    }

+

+    public List<UpdateArea> getOnChangeUpdateAreas() {

+        return onChangeUpdateAreas;

+    }

+

+    public List<UpdateArea> getOnClickUpdateAreas() {

+        return onClickUpdateAreas;

+    }

+

+    public String getParameterName() {

+        return parameterName;

+    }

+

+    public Integer getPosition() {

+        return position;

+    }

+

+    public String getRedWhen() {

+        return redWhen;

+    }

+

+    public Boolean getRequiredField() {

+        return requiredField;

+    }

+

+    public String getRequiredFieldStyle() {

+        return requiredFieldStyle;

+    }

+

+    public boolean getSeparateColumn() {

+        return separateColumn;

+    }

+

+    public String getServiceName() {

+        return serviceName;

+    }

+

+    public Boolean getSortField() {

+        return sortField;

+    }

+

+    public String getSortFieldAscStyle() {

+        return sortFieldAscStyle;

+    }

+

+    public String getSortFieldDescStyle() {

+        return sortFieldDescStyle;

+    }

+

+    public String getSortFieldHelpText() {

+        return sortFieldHelpText;

+    }

+

+    public String getSortFieldStyle() {

+        return sortFieldStyle;

+    }

+

+    public FlexibleStringExpander getTitle() {

+        return title;

+    }

+

+    public String getTitleAreaStyle() {

+        return titleAreaStyle;

+    }

+

+    public String getTitleStyle() {

+        return titleStyle;

+    }

+

+    public FlexibleStringExpander getTooltip() {

+        return tooltip;

+    }

+

+    public String getTooltipStyle() {

+        return tooltipStyle;

+    }

+

+    public FlexibleStringExpander getUseWhen() {

+        return useWhen;

+    }

+

+    public String getWidgetAreaStyle() {

+        return widgetAreaStyle;

+    }

+

+    public String getWidgetStyle() {

+        return widgetStyle;

+    }

+

+    private boolean induceFieldInfo(ModelForm modelForm, String defaultFieldType, ModelReader entityModelReader, DispatchContext dispatchContext) {

+        if (induceFieldInfoFromEntityField(defaultFieldType, entityModelReader))

+            return true;

+        if (induceFieldInfoFromServiceParam(defaultFieldType, entityModelReader, dispatchContext))

+            return true;

+        return false;

+    }

+

+    public boolean induceFieldInfoFromEntityField(ModelEntity modelEntity, ModelField modelField, String defaultFieldType) {

+        if (modelEntity == null || modelField == null)

+            return false;

+        this.entityName = modelEntity.getEntityName();

+        this.fieldName = modelField.getName();

+        if ("find".equals(defaultFieldType)) {

+            if ("id".equals(modelField.getType()) || "id-ne".equals(modelField.getType())) {

+                ModelFormField.TextFindField textField = new ModelFormField.TextFindField(FieldInfo.SOURCE_AUTO_ENTITY, 20,

+                        Integer.valueOf(20), null);

+                this.setFieldInfo(textField);

+            } else if ("id-long".equals(modelField.getType()) || "id-long-ne".equals(modelField.getType())) {

+                ModelFormField.TextFindField textField = new ModelFormField.TextFindField(FieldInfo.SOURCE_AUTO_ENTITY, 40,

+                        Integer.valueOf(60), null);

+                this.setFieldInfo(textField);

+            } else if ("id-vlong".equals(modelField.getType()) || "id-vlong-ne".equals(modelField.getType())) {

+                ModelFormField.TextFindField textField = new ModelFormField.TextFindField(FieldInfo.SOURCE_AUTO_ENTITY, 60,

+                        Integer.valueOf(250), null);

+                this.setFieldInfo(textField);

+            } else if ("very-short".equals(modelField.getType())) {

+                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, 6,

+                        Integer.valueOf(10), null);

+                this.setFieldInfo(textField);

+            } else if ("name".equals(modelField.getType()) || "short-varchar".equals(modelField.getType())) {

+                ModelFormField.TextFindField textField = new ModelFormField.TextFindField(FieldInfo.SOURCE_AUTO_ENTITY, 40,

+                        Integer.valueOf(60), null);

+                this.setFieldInfo(textField);

+            } else if ("value".equals(modelField.getType()) || "comment".equals(modelField.getType())

+                    || "description".equals(modelField.getType()) || "long-varchar".equals(modelField.getType())

+                    || "url".equals(modelField.getType()) || "email".equals(modelField.getType())) {

+                ModelFormField.TextFindField textField = new ModelFormField.TextFindField(FieldInfo.SOURCE_AUTO_ENTITY, 60,

+                        Integer.valueOf(250), null);

+                this.setFieldInfo(textField);

+            } else if ("floating-point".equals(modelField.getType()) || "currency-amount".equals(modelField.getType())

+                    || "numeric".equals(modelField.getType())) {

+                ModelFormField.RangeFindField textField = new ModelFormField.RangeFindField(FieldInfo.SOURCE_AUTO_ENTITY, 6, null);

+                this.setFieldInfo(textField);

+            } else if ("date-time".equals(modelField.getType()) || "date".equals(modelField.getType())

+                    || "time".equals(modelField.getType())) {

+                String type = modelField.getType();

+                if ("date-time".equals(modelField.getType())) {

+                    type = "timestamp";

+                }

+                ModelFormField.DateFindField dateTimeField = new ModelFormField.DateFindField(FieldInfo.SOURCE_AUTO_ENTITY, type);

+                this.setFieldInfo(dateTimeField);

+            } else {

+                ModelFormField.TextFindField textField = new ModelFormField.TextFindField(FieldInfo.SOURCE_AUTO_ENTITY, null);

+                this.setFieldInfo(textField);

+            }

+        } else if ("display".equals(defaultFieldType)) {

+            ModelFormField.DisplayField displayField = new ModelFormField.DisplayField(FieldInfo.SOURCE_AUTO_SERVICE, null);

+            this.setFieldInfo(displayField);

+        } else if ("hidden".equals(defaultFieldType)) {

+            ModelFormField.HiddenField hiddenField = new ModelFormField.HiddenField(FieldInfo.SOURCE_AUTO_SERVICE, null);

+            this.setFieldInfo(hiddenField);

+        } else {

+            if ("id".equals(modelField.getType()) || "id-ne".equals(modelField.getType())) {

+                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, 20,

+                        Integer.valueOf(20), null);

+                this.setFieldInfo(textField);

+            } else if ("id-long".equals(modelField.getType()) || "id-long-ne".equals(modelField.getType())) {

+                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, 40,

+                        Integer.valueOf(60), null);

+                this.setFieldInfo(textField);

+            } else if ("id-vlong".equals(modelField.getType()) || "id-vlong-ne".equals(modelField.getType())) {

+                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, 60,

+                        Integer.valueOf(250), null);

+                this.setFieldInfo(textField);

+            } else if ("indicator".equals(modelField.getType())) {

+                ArrayList<OptionSource> optionSources = new ArrayList<OptionSource>();

+                optionSources.add(new ModelFormField.SingleOption("Y", null, null));

+                optionSources.add(new ModelFormField.SingleOption("N", null, null));

+                ModelFormField.DropDownField dropDownField = new ModelFormField.DropDownField(FieldInfo.SOURCE_AUTO_ENTITY,

+                        optionSources);

+                this.setFieldInfo(dropDownField);

+            } else if ("very-short".equals(modelField.getType())) {

+                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, 6,

+                        Integer.valueOf(10), null);

+                this.setFieldInfo(textField);

+            } else if ("very-long".equals(modelField.getType())) {

+                ModelFormField.TextareaField textareaField = new ModelFormField.TextareaField(FieldInfo.SOURCE_AUTO_ENTITY, null);

+                this.setFieldInfo(textareaField);

+            } else if ("name".equals(modelField.getType()) || "short-varchar".equals(modelField.getType())) {

+                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, 40,

+                        Integer.valueOf(60), null);

+                this.setFieldInfo(textField);

+            } else if ("value".equals(modelField.getType()) || "comment".equals(modelField.getType())

+                    || "description".equals(modelField.getType()) || "long-varchar".equals(modelField.getType())

+                    || "url".equals(modelField.getType()) || "email".equals(modelField.getType())) {

+                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, 60,

+                        Integer.valueOf(250), null);

+                this.setFieldInfo(textField);

+            } else if ("floating-point".equals(modelField.getType()) || "currency-amount".equals(modelField.getType())

+                    || "numeric".equals(modelField.getType())) {

+                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, 6, null, null);

+                this.setFieldInfo(textField);

+            } else if ("date-time".equals(modelField.getType()) || "date".equals(modelField.getType())

+                    || "time".equals(modelField.getType())) {

+                String type = modelField.getType();

+                if ("date-time".equals(modelField.getType())) {

+                    type = "timestamp";

+                }

+                ModelFormField.DateTimeField dateTimeField = new ModelFormField.DateTimeField(FieldInfo.SOURCE_AUTO_ENTITY, type);

+                this.setFieldInfo(dateTimeField);

+            } else {

+                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_ENTITY, null);

+                this.setFieldInfo(textField);

+            }

+        }

+        return true;

+    }

+

+    private boolean induceFieldInfoFromEntityField(String defaultFieldType, ModelReader entityModelReader) {

+        if (UtilValidate.isEmpty(this.getEntityName()) || UtilValidate.isEmpty(this.getFieldName()))

+            return false;

+        try {

+            ModelEntity modelEntity = entityModelReader.getModelEntity(this.getEntityName());

+            if (modelEntity != null) {

+                ModelField modelField = modelEntity.getField(this.getFieldName());

+                if (modelField != null) {

+                    // okay, populate using the entity field info...

+                    this.induceFieldInfoFromEntityField(modelEntity, modelField, defaultFieldType);

+                    return true;

+                }

+            }

+        } catch (GenericEntityException e) {

+            Debug.logError(e, module);

+        }

+        return false;

+    }

+

+    public boolean induceFieldInfoFromServiceParam(ModelService modelService, ModelParam modelParam, String defaultFieldType) {

+        if (modelService == null || modelParam == null)

+            return false;

+        this.serviceName = modelService.name;

+        this.attributeName = modelParam.name;

+        if ("find".equals(defaultFieldType)) {

+            if (modelParam.type.indexOf("Double") != -1 || modelParam.type.indexOf("Float") != -1

+                    || modelParam.type.indexOf("Long") != -1 || modelParam.type.indexOf("Integer") != -1) {

+                ModelFormField.RangeFindField textField = new ModelFormField.RangeFindField(FieldInfo.SOURCE_AUTO_SERVICE, 6,

+                        null);

+                this.setFieldInfo(textField);

+            } else if (modelParam.type.indexOf("Timestamp") != -1) {

+                ModelFormField.DateFindField dateTimeField = new ModelFormField.DateFindField(FieldInfo.SOURCE_AUTO_SERVICE,

+                        "timestamp");

+                this.setFieldInfo(dateTimeField);

+            } else if (modelParam.type.indexOf("Date") != -1) {

+                ModelFormField.DateFindField dateTimeField = new ModelFormField.DateFindField(FieldInfo.SOURCE_AUTO_SERVICE,

+                        "date");

+                this.setFieldInfo(dateTimeField);

+            } else if (modelParam.type.indexOf("Time") != -1) {

+                ModelFormField.DateFindField dateTimeField = new ModelFormField.DateFindField(FieldInfo.SOURCE_AUTO_SERVICE,

+                        "time");

+                this.setFieldInfo(dateTimeField);

+            } else {

+                ModelFormField.TextFindField textField = new ModelFormField.TextFindField(FieldInfo.SOURCE_AUTO_SERVICE, null);

+                this.setFieldInfo(textField);

+            }

+        } else if ("display".equals(defaultFieldType)) {

+            ModelFormField.DisplayField displayField = new ModelFormField.DisplayField(FieldInfo.SOURCE_AUTO_SERVICE, null);

+            this.setFieldInfo(displayField);

+        } else {

+            // default to "edit"

+            if (modelParam.type.indexOf("Double") != -1 || modelParam.type.indexOf("Float") != -1

+                    || modelParam.type.indexOf("Long") != -1 || modelParam.type.indexOf("Integer") != -1) {

+                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_SERVICE, 6, null, null);

+                this.setFieldInfo(textField);

+            } else if (modelParam.type.indexOf("Timestamp") != -1) {

+                ModelFormField.DateTimeField dateTimeField = new ModelFormField.DateTimeField(FieldInfo.SOURCE_AUTO_SERVICE,

+                        "timestamp");

+                this.setFieldInfo(dateTimeField);

+            } else if (modelParam.type.indexOf("Date") != -1) {

+                ModelFormField.DateTimeField dateTimeField = new ModelFormField.DateTimeField(FieldInfo.SOURCE_AUTO_SERVICE,

+                        "date");

+                this.setFieldInfo(dateTimeField);

+            } else if (modelParam.type.indexOf("Time") != -1) {

+                ModelFormField.DateTimeField dateTimeField = new ModelFormField.DateTimeField(FieldInfo.SOURCE_AUTO_SERVICE,

+                        "time");

+                this.setFieldInfo(dateTimeField);

+            } else {

+                ModelFormField.TextField textField = new ModelFormField.TextField(FieldInfo.SOURCE_AUTO_SERVICE, null);

+                this.setFieldInfo(textField);

+            }

+        }

+        return true;

+    }

+

+    private boolean induceFieldInfoFromServiceParam(String defaultFieldType, ModelReader entityModelReader,

+            DispatchContext dispatchContext) {

+        if (UtilValidate.isEmpty(this.getServiceName()) || UtilValidate.isEmpty(this.getAttributeName()))

+            return false;

+        try {

+            ModelService modelService = dispatchContext.getModelService(this.getServiceName());

+            if (modelService != null) {

+                ModelParam modelParam = modelService.getParam(this.getAttributeName());

+                if (modelParam != null) {

+                    if (UtilValidate.isNotEmpty(modelParam.entityName) && UtilValidate.isNotEmpty(modelParam.fieldName)) {

+                        this.entityName = modelParam.entityName;

+                        this.fieldName = modelParam.fieldName;

+                        if (this.induceFieldInfoFromEntityField(defaultFieldType, entityModelReader)) {

+                            return true;

+                        }

+                    }

+

+                    this.induceFieldInfoFromServiceParam(modelService, modelParam, defaultFieldType);

+                    return true;

+                }

+            }

+        } catch (GenericServiceException e) {

+            Debug.logError(e,

+                    "error getting service parameter definition for auto-field with serviceName: " + this.getServiceName()

+                            + ", and attributeName: " + this.getAttributeName(), module);

+        }

+        return false;

+    }

+

+    public void mergeOverrideModelFormField(ModelFormFieldBuilder builder) {

+        if (builder == null)

+            return;

+        if (UtilValidate.isNotEmpty(builder.getName()))

+            this.name = builder.getName();

+        if (UtilValidate.isNotEmpty(builder.getMapAcsr()))

+            this.mapAcsr = builder.getMapAcsr();

+        if (UtilValidate.isNotEmpty(builder.getEntityName()))

+            this.entityName = builder.getEntityName();

+        if (UtilValidate.isNotEmpty(builder.getServiceName()))

+            this.serviceName = builder.getServiceName();

+        if (UtilValidate.isNotEmpty(builder.getEntryAcsr()))

+            this.entryAcsr = builder.getEntryAcsr();

+        if (UtilValidate.isNotEmpty(builder.getParameterName()))

+            this.parameterName = builder.getParameterName();

+        if (UtilValidate.isNotEmpty(builder.getFieldName()))

+            this.fieldName = builder.getFieldName();

+        if (!builder.getAttributeName().isEmpty())

+            this.attributeName = builder.getAttributeName();

+        if (UtilValidate.isNotEmpty(builder.getTitle()))

+            this.title = builder.getTitle();

+        if (UtilValidate.isNotEmpty(builder.getTooltip()))

+            this.tooltip = builder.getTooltip();

+        if (builder.getSortField() != null)

+            this.sortField = builder.getSortField();

+        if (UtilValidate.isNotEmpty(builder.getSortFieldHelpText()))

+            this.sortFieldHelpText = builder.getSortFieldHelpText();

+        if (UtilValidate.isNotEmpty(builder.getTitleAreaStyle()))

+            this.titleAreaStyle = builder.getTitleAreaStyle();

+        if (UtilValidate.isNotEmpty(builder.getWidgetAreaStyle()))

+            this.widgetAreaStyle = builder.getWidgetAreaStyle();

+        if (UtilValidate.isNotEmpty(builder.getTitleStyle()))

+            this.titleStyle = builder.getTitleStyle();

+        if (UtilValidate.isNotEmpty(builder.getWidgetStyle()))

+            this.widgetStyle = builder.getWidgetStyle();

+        if (UtilValidate.isNotEmpty(builder.getRedWhen()))

+            this.redWhen = builder.getRedWhen();

+        if (UtilValidate.isNotEmpty(builder.getEvent()))

+            this.event = builder.getEvent();

+        if (!builder.getAction().isEmpty())

+            this.action = builder.getAction();

+        if (UtilValidate.isNotEmpty(builder.getUseWhen()))

+            this.useWhen = builder.getUseWhen();

+        if (builder.getFieldInfo() != null)

+            this.setFieldInfo(builder.getFieldInfo());

+        if (UtilValidate.isNotEmpty(builder.getHeaderLink()))

+            this.headerLink = builder.getHeaderLink();

+        if (UtilValidate.isNotEmpty(builder.getHeaderLinkStyle()))

+            this.headerLinkStyle = builder.getHeaderLinkStyle();

+        if (UtilValidate.isNotEmpty(builder.getIdName()))

+            this.idName = builder.getIdName();

+        if (UtilValidate.isNotEmpty(builder.getOnChangeUpdateAreas()))

+            this.onChangeUpdateAreas.addAll(builder.getOnChangeUpdateAreas());

+        if (UtilValidate.isNotEmpty(builder.getOnClickUpdateAreas()))

+            this.onClickUpdateAreas.addAll(builder.getOnClickUpdateAreas());

+        this.encodeOutput = builder.getEncodeOutput();

+        this.position = builder.getPosition();

+        this.requiredField = builder.getRequiredField();

+        this.separateColumn = builder.getSeparateColumn();

+    }

+

+    public ModelFormFieldBuilder setAction(String action) {

+        this.action = FlexibleStringExpander.getInstance(action);

+        return this;

+    }

+

+    public ModelFormFieldBuilder setAttributeName(String attributeName) {

+        this.attributeName = attributeName;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setEncodeOutput(boolean encodeOutput) {

+        this.encodeOutput = encodeOutput;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setEntityName(String entityName) {

+        this.entityName = entityName;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setEntryName(String entryName) {

+        this.entryAcsr = FlexibleMapAccessor.getInstance(entryName);

+        return this;

+    }

+

+    public ModelFormFieldBuilder setEvent(String event) {

+        this.event = event;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setFieldInfo(FieldInfo fieldInfo) {

+        if (fieldInfo != null && (this.fieldInfo == null || (fieldInfo.getFieldSource() <= this.fieldInfo.getFieldSource()))) {

+            this.fieldInfo = fieldInfo;

+        }

+        return this;

+    }

+

+    public ModelFormFieldBuilder setFieldName(String fieldName) {

+        this.fieldName = fieldName;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setFieldType(String fieldType) {

+        this.fieldType = fieldType;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setHeaderLink(String headerLink) {

+        this.headerLink = headerLink;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setHeaderLinkStyle(String headerLinkStyle) {

+        this.headerLinkStyle = headerLinkStyle;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setIdName(String idName) {

+        this.idName = idName;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setMapName(String mapName) {

+        this.mapAcsr = FlexibleMapAccessor.getInstance(mapName);

+        return this;

+    }

+

+    public ModelFormFieldBuilder setModelForm(ModelForm modelForm) {

+        this.modelForm = modelForm;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setName(String name) {

+        this.name = name;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setParameterName(String parameterName) {

+        this.parameterName = parameterName;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setPosition(Integer position) {

+        this.position = position;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setRedWhen(String redWhen) {

+        this.redWhen = redWhen;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setRequiredField(Boolean requiredField) {

+        this.requiredField = requiredField;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setRequiredFieldStyle(String requiredFieldStyle) {

+        this.requiredFieldStyle = requiredFieldStyle;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setSeparateColumn(boolean separateColumn) {

+        this.separateColumn = separateColumn;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setServiceName(String serviceName) {

+        this.serviceName = serviceName;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setSortField(Boolean sortField) {

+        this.sortField = sortField;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setSortFieldAscStyle(String sortFieldAscStyle) {

+        this.sortFieldAscStyle = sortFieldAscStyle;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setSortFieldDescStyle(String sortFieldDescStyle) {

+        this.sortFieldDescStyle = sortFieldDescStyle;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setSortFieldHelpText(String sortFieldHelpText) {

+        this.sortFieldHelpText = sortFieldHelpText;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setSortFieldStyle(String sortFieldStyle) {

+        this.sortFieldStyle = sortFieldStyle;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setTitle(String title) {

+        this.title = FlexibleStringExpander.getInstance(title);

+        return this;

+    }

+

+    public ModelFormFieldBuilder setTitleAreaStyle(String titleAreaStyle) {

+        this.titleAreaStyle = titleAreaStyle;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setTitleStyle(String titleStyle) {

+        this.titleStyle = titleStyle;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setTooltip(String tooltip) {

+        this.tooltip = FlexibleStringExpander.getInstance(tooltip);

+        return this;

+    }

+

+    public ModelFormFieldBuilder setTooltipStyle(String tooltipStyle) {

+        this.tooltipStyle = tooltipStyle;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setUseWhen(String useWhen) {

+        this.useWhen = FlexibleStringExpander.getInstance(useWhen);

+        return this;

+    }

+

+    public ModelFormFieldBuilder setWidgetAreaStyle(String widgetAreaStyle) {

+        this.widgetAreaStyle = widgetAreaStyle;

+        return this;

+    }

+

+    public ModelFormFieldBuilder setWidgetStyle(String widgetStyle) {

+        this.widgetStyle = widgetStyle;

+        return this;

+    }

+}

diff --git a/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java b/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java
index 00b2b9e..fd6435e 100644
--- a/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java
@@ -31,8 +31,7 @@
 import javax.servlet.http.HttpServletResponse;
 
 import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.StringUtil;
-import org.ofbiz.base.util.StringUtil.SimpleEncoder;
+import org.ofbiz.base.util.UtilCodec;
 import org.ofbiz.base.util.UtilGenerics;
 import org.ofbiz.base.util.UtilHttp;
 import org.ofbiz.base.util.UtilMisc;
@@ -90,7 +89,7 @@
     protected String lastFieldGroupId = "";
     protected boolean renderPagination = true;
     protected boolean javaScriptEnabled = false;
-    private SimpleEncoder internalEncoder;
+    private UtilCodec.SimpleEncoder internalEncoder;
 
     protected HtmlFormRenderer() {}
 
@@ -100,7 +99,7 @@
         ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
         this.rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
         this.javaScriptEnabled = UtilHttp.isJavaScriptEnabled(request);
-        internalEncoder = StringUtil.getEncoder("string");
+        internalEncoder = UtilCodec.getEncoder("string");
     }
 
     public boolean getRenderPagination() {
@@ -362,7 +361,7 @@
         if (UtilValidate.isEmpty(value)) {
             return value;
         }
-        StringUtil.SimpleEncoder encoder = (StringUtil.SimpleEncoder)context.get("simpleEncoder");
+        UtilCodec.SimpleEncoder encoder = (UtilCodec.SimpleEncoder)context.get("simpleEncoder");
         if (modelFormField.getEncodeOutput() && encoder != null) {
             value = encoder.encode(value);
         } else {
diff --git a/framework/widget/src/org/ofbiz/widget/html/HtmlMenuRenderer.java b/framework/widget/src/org/ofbiz/widget/html/HtmlMenuRenderer.java
index c4509e6..59a0527 100644
--- a/framework/widget/src/org/ofbiz/widget/html/HtmlMenuRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/html/HtmlMenuRenderer.java
@@ -29,6 +29,7 @@
 import javax.servlet.http.HttpSession;
 
 import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
 import org.ofbiz.base.util.UtilMisc;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.entity.Delegator;
@@ -157,7 +158,7 @@
             }
         }
 
-        if (menuItem.getDisabled() || this.isDisableIfEmpty(menuItem, context)) {
+        if (this.isDisableIfEmpty(menuItem, context)) {
             style = menuItem.getDisabledTitleStyle();
         }
 
@@ -185,7 +186,7 @@
             renderLink(writer, context, link);
         } else {
             String txt = menuItem.getTitle(context);
-            StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
+            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
             if (simpleEncoder != null) {
                 txt = simpleEncoder.encode(txt);
             }
@@ -377,7 +378,7 @@
     public void renderLink(Appendable writer, Map<String, Object> context, ModelMenuItem.Link link) throws IOException {
         String target = link.getTarget(context);
         ModelMenuItem menuItem = link.getLinkMenuItem();
-        if (menuItem.getDisabled() || isDisableIfEmpty(menuItem, context)) {
+        if (isDisableIfEmpty(menuItem, context)) {
             target = null;
         }
 
@@ -407,7 +408,7 @@
                 writer.append(uniqueItemName);
                 writer.append("\">");
 
-                StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
+                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
                 for (Map.Entry<String, String> parameter: link.getParameterMap(context).entrySet()) {
                     writer.append("<input name=\"");
                     writer.append(parameter.getKey());
diff --git a/framework/widget/src/org/ofbiz/widget/html/HtmlTreeRenderer.java b/framework/widget/src/org/ofbiz/widget/html/HtmlTreeRenderer.java
index 103cbd5..d3a3d4a 100644
--- a/framework/widget/src/org/ofbiz/widget/html/HtmlTreeRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/html/HtmlTreeRenderer.java
@@ -61,7 +61,7 @@
         appendWhitespace(writer);
         writer.append("<li>");
 
-        String pkName = node.getPkName();
+        String pkName = node.getPkName(context);
         String entityId = null;
         String entryName = node.getEntryName();
         if (UtilValidate.isNotEmpty(entryName)) {
@@ -71,7 +71,6 @@
         }
         boolean hasChildren = node.hasChildren(context);
 
-        ModelTree.ModelNode.Link expandCollapseLink = new ModelTree.ModelNode.Link();
         // check to see if this node needs to be expanded.
         if (hasChildren && node.isExpandCollapse()) {
             String targetEntityId = null;
@@ -79,7 +78,8 @@
             if (depth < targetNodeTrail.size()) {
                 targetEntityId = targetNodeTrail.get(depth);
             }
-
+            // FIXME: Using a widget model in this way is an ugly hack.
+            ModelTree.ModelNode.Link expandCollapseLink = null;
             int openDepth = node.getModelTree().getOpenDepth();
             if (depth >= openDepth && (targetEntityId == null || !targetEntityId.equals(entityId))) {
                 // Not on the trail
@@ -87,8 +87,6 @@
                     context.put("processChildren", Boolean.FALSE);
                     //expandCollapseLink.setText("&nbsp;+&nbsp;");
                     currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|");
-                    expandCollapseLink.setStyle("collapsed");
-                    expandCollapseLink.setText(" ");
                     StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));
                     String trailName = node.getModelTree().getTrailName(context);
                     if (target.indexOf("?") < 0) {
@@ -97,7 +95,7 @@
                         target.append("&");
                     }
                     target.append(trailName).append("=").append(currentNodeTrailPiped);
-                    expandCollapseLink.setTarget(target.toString());
+                    expandCollapseLink = new ModelTree.ModelNode.Link("collapsed", target.toString(), " ");
                 }
             } else {
                 context.put("processChildren", Boolean.TRUE);
@@ -107,8 +105,6 @@
                 if (currentNodeTrailPiped == null) {
                     currentNodeTrailPiped = "";
                 }
-                expandCollapseLink.setStyle("expanded");
-                expandCollapseLink.setText(" ");
                 StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));
                 String trailName = node.getModelTree().getTrailName(context);
                 if (target.indexOf("?") < 0) {
@@ -117,15 +113,16 @@
                     target.append("&");
                 }
                 target.append(trailName).append("=").append(currentNodeTrailPiped);
-                expandCollapseLink.setTarget(target.toString());
+                expandCollapseLink = new ModelTree.ModelNode.Link("expanded", target.toString(), " ");
                 // add it so it can be remove in renderNodeEnd
                 currentNodeTrail.add(lastContentId);
             }
-            renderLink(writer, context, expandCollapseLink);
+            if (expandCollapseLink != null) {
+                renderLink(writer, context, expandCollapseLink);
+            }
         } else if (!hasChildren) {
             context.put("processChildren", Boolean.FALSE);
-            expandCollapseLink.setStyle("leafnode");
-            expandCollapseLink.setText(" ");
+            ModelTree.ModelNode.Link expandCollapseLink = new ModelTree.ModelNode.Link("leafnode", "", " ");
             renderLink(writer, context, expandCollapseLink);
         }
     }
diff --git a/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java b/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java
index 9bfe5eb..3c051ee 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java
@@ -33,6 +33,7 @@
 

 import org.ofbiz.base.util.Debug;

 import org.ofbiz.base.util.StringUtil;

+import org.ofbiz.base.util.UtilCodec;

 import org.ofbiz.base.util.UtilMisc;

 import org.ofbiz.base.util.UtilValidate;

 import org.ofbiz.base.util.template.FreeMarkerWorker;

@@ -193,7 +194,7 @@
         Map<String, Object> parameters = new HashMap<String, Object>();

         String target = link.getTarget(context);

         ModelMenuItem menuItem = link.getLinkMenuItem();

-        if (menuItem.getDisabled() || isDisableIfEmpty(menuItem, context)) {

+        if (isDisableIfEmpty(menuItem, context)) {

             target = null;

         }

         parameters.put("id", link.getId(context));

@@ -289,7 +290,7 @@
                 style = "selected";

             }

         }

-        if (menuItem.getDisabled() || this.isDisableIfEmpty(menuItem, context)) {

+        if (this.isDisableIfEmpty(menuItem, context)) {

             style = menuItem.getDisabledTitleStyle();

         }

         if (style == null) {

@@ -309,7 +310,7 @@
             linkStr = sw.toString();

         } else {

             linkStr = menuItem.getTitle(context);

-            StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");

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

             if (simpleEncoder != null) {

                 linkStr = simpleEncoder.encode(linkStr);

             }

diff --git a/framework/widget/src/org/ofbiz/widget/menu/MenuFactory.java b/framework/widget/src/org/ofbiz/widget/menu/MenuFactory.java
index ac89855..472d688 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/MenuFactory.java
+++ b/framework/widget/src/org/ofbiz/widget/menu/MenuFactory.java
@@ -84,8 +84,7 @@
             // 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);
-                modelMenu.setMenuLocation(menuLocation);
+                ModelMenu modelMenu = new ModelMenu(menuElement, menuLocation);
                 modelMenuMap.put(modelMenu.getName(), modelMenu);
             }
          }
diff --git a/framework/widget/src/org/ofbiz/widget/menu/ModelMenu.java b/framework/widget/src/org/ofbiz/widget/menu/ModelMenu.java
index 3e17668..fa28058 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/ModelMenu.java
+++ b/framework/widget/src/org/ofbiz/widget/menu/ModelMenu.java
@@ -20,6 +20,7 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -35,34 +36,50 @@
 import org.w3c.dom.Element;
 
 /**
- * Widget Library - Menu model class
+ * Models the &lt;menu&gt; element.
+ * 
+ * @see <code>widget-menu.xsd</code>
  */
 @SuppressWarnings("serial")
 public class ModelMenu extends ModelWidget {
 
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     DEVELOPERS PLEASE READ
+     * ----------------------------------------------------------------------- *
+     * 
+     * This model is intended to be a read-only data structure that represents
+     * an XML element. Outside of object construction, the class should not
+     * have any behaviors.
+     * 
+     * Instances of this class will be shared by multiple threads - therefore
+     * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME!
+     * 
+     */
+
     public static final String module = ModelMenu.class.getName();
 
-    protected List<ModelWidgetAction> actions;
-    protected String defaultAlign;
-    protected String defaultAlignStyle;
-    protected FlexibleStringExpander defaultAssociatedContentId;
-    protected String defaultCellWidth;
-    protected String defaultDisabledTitleStyle;
-    protected String defaultEntityName;
-    protected Boolean defaultHideIfSelected;
-    protected String defaultMenuItemName;
-    protected String defaultPermissionEntityAction;
-    protected String defaultPermissionOperation;
-    protected String defaultPermissionStatusId;
-    protected String defaultPrivilegeEnumId;
-    protected String defaultSelectedStyle;
-    protected String defaultTitleStyle;
-    protected String defaultTooltipStyle;
-    protected String defaultWidgetStyle;
-    protected FlexibleStringExpander extraIndex;
-    protected String fillStyle;
-    protected String id;
-    protected FlexibleStringExpander menuContainerStyleExdr;
+    private final List<ModelWidgetAction> actions;
+    private final String defaultAlign;
+    private final String defaultAlignStyle;
+    private final FlexibleStringExpander defaultAssociatedContentId;
+    private final String defaultCellWidth;
+    private final String defaultDisabledTitleStyle;
+    private final String defaultEntityName;
+    private final Boolean defaultHideIfSelected;
+    private final String defaultMenuItemName;
+    private final String defaultPermissionEntityAction;
+    private final String defaultPermissionOperation;
+    private final String defaultPermissionStatusId;
+    private final String defaultPrivilegeEnumId;
+    private final String defaultSelectedStyle;
+    private final String defaultTitleStyle;
+    private final String defaultTooltipStyle;
+    private final String defaultWidgetStyle;
+    private final FlexibleStringExpander extraIndex;
+    private final String fillStyle;
+    private final String id;
+    private final FlexibleStringExpander menuContainerStyleExdr;
     /** This List will contain one copy of each item for each item name in the order
      * they were encountered in the service, entity, or menu definition; item definitions
      * with constraints will also be in this list but may appear multiple times for the same
@@ -72,41 +89,68 @@
      * necessary to use the Map. The Map is used when loading the menu definition to keep the
      * list clean and implement the override features for item definitions.
      */
-    protected List<ModelMenuItem> menuItemList = new ArrayList<ModelMenuItem>();
+    private final List<ModelMenuItem> menuItemList;
     /** This Map is keyed with the item name and has a ModelMenuItem for the value; items
      * with conditions will not be put in this Map so item definition overrides for items
      * with conditions is not possible.
      */
-    protected Map<String, ModelMenuItem> menuItemMap = new HashMap<String, ModelMenuItem>();
-    protected String menuLocation;
-    protected String menuWidth;
-    protected String orientation = "horizontal";
-    protected FlexibleMapAccessor<String> selectedMenuItemContextFieldName;
-    protected String target;
-    protected FlexibleStringExpander title;
-    protected String tooltip;
-    protected String type;
-
-
-   // ===== CONSTRUCTORS =====
+    private final Map<String, ModelMenuItem> menuItemMap;
+    private final String menuLocation;
+    private final String menuWidth;
+    private final String orientation;
+    private final FlexibleMapAccessor<String> selectedMenuItemContextFieldName;
+    private final String target;
+    private final FlexibleStringExpander title;
+    private final String tooltip;
+    private final String type;
 
     /** XML Constructor */
-    public ModelMenu(Element menuElement) {
+    public ModelMenu(Element menuElement, String menuLocation) {
         super(menuElement);
-
+        ArrayList<ModelWidgetAction> actions = new ArrayList<ModelWidgetAction>();
+        String defaultAlign = "";
+        String defaultAlignStyle = "";
+        FlexibleStringExpander defaultAssociatedContentId = FlexibleStringExpander.getInstance("");
+        String defaultCellWidth = "";
+        String defaultDisabledTitleStyle = "";
+        String defaultEntityName = "";
+        Boolean defaultHideIfSelected = Boolean.FALSE;
+        String defaultMenuItemName = "";
+        String defaultPermissionEntityAction = "";
+        String defaultPermissionOperation = "";
+        String defaultPermissionStatusId = "";
+        String defaultPrivilegeEnumId = "";
+        String defaultSelectedStyle = "";
+        String defaultTitleStyle = "";
+        String defaultTooltipStyle = "";
+        String defaultWidgetStyle = "";
+        FlexibleStringExpander extraIndex = FlexibleStringExpander.getInstance("");
+        String fillStyle = "";
+        String id = "";
+        FlexibleStringExpander menuContainerStyleExdr = FlexibleStringExpander.getInstance("");
+        ArrayList<ModelMenuItem> menuItemList = new ArrayList<ModelMenuItem>();
+        Map<String, ModelMenuItem> menuItemMap = new HashMap<String, ModelMenuItem>();
+        String menuWidth = "";
+        String orientation = "horizontal";
+        FlexibleMapAccessor<String> selectedMenuItemContextFieldName = FlexibleMapAccessor.getInstance("");
+        String target = "";
+        FlexibleStringExpander title = FlexibleStringExpander.getInstance("");
+        String tooltip = "";
+        String type = "";
         // check if there is a parent menu to inherit from
         String parentResource = menuElement.getAttribute("extends-resource");
         String parentMenu = menuElement.getAttribute("extends");
-        if (parentMenu.length() > 0 && !(parentMenu.equals(menuElement.getAttribute("name")) && UtilValidate.isEmpty(parentResource))) {
+        if (!parentMenu.isEmpty()) {
             ModelMenu parent = null;
-            // check if we have a resource name (part of the string before the ?)
-            if (UtilValidate.isNotEmpty(parentResource)) {
+            if (!parentResource.isEmpty()) {
                 try {
                     parent = MenuFactory.getMenuFromLocation(parentResource, parentMenu);
                 } catch (Exception e) {
-                    Debug.logError(e, "Failed to load parent menu definition '" + parentMenu + "' at resource '" + parentResource + "'", module);
+                    Debug.logError(e, "Failed to load parent menu definition '" + parentMenu + "' at resource '" + parentResource
+                            + "'", module);
                 }
             } else {
+                parentResource = menuLocation;
                 // try to find a menu definition in the same file
                 Element rootElement = menuElement.getOwnerDocument().getDocumentElement();
                 List<? extends Element> menuElements = UtilXml.childElementList(rootElement, "menu");
@@ -114,7 +158,7 @@
                 //menuElements.addAll(UtilXml.childElementList(rootElement, "abstract-menu"));
                 for (Element menuElementEntry : menuElements) {
                     if (menuElementEntry.getAttribute("name").equals(parentMenu)) {
-                        parent = new ModelMenu(menuElementEntry);
+                        parent = new ModelMenu(menuElementEntry, parentResource);
                         break;
                     }
                 }
@@ -122,148 +166,341 @@
                     Debug.logError("Failed to find parent menu definition '" + parentMenu + "' in same document.", module);
                 }
             }
-
             if (parent != null) {
-                this.type = parent.type;
-                this.target = parent.target;
-                this.id = parent.id;
-                this.title = parent.title;
-                this.tooltip = parent.tooltip;
-                this.defaultEntityName = parent.defaultEntityName;
-                this.defaultTitleStyle = parent.defaultTitleStyle;
-                this.defaultSelectedStyle = parent.defaultSelectedStyle;
-                this.defaultWidgetStyle = parent.defaultWidgetStyle;
-                this.defaultTooltipStyle = parent.defaultTooltipStyle;
-                this.defaultMenuItemName = parent.defaultMenuItemName;
-                this.menuItemList.addAll(parent.menuItemList);
-                this.menuItemMap.putAll(parent.menuItemMap);
-                this.defaultPermissionOperation = parent.defaultPermissionOperation;
-                this.defaultPermissionEntityAction = parent.defaultPermissionEntityAction;
-                this.defaultAssociatedContentId = parent.defaultAssociatedContentId;
-                this.defaultPermissionStatusId = parent.defaultPermissionStatusId;
-                this.defaultPrivilegeEnumId = parent.defaultPrivilegeEnumId;
-                this.defaultHideIfSelected = parent.defaultHideIfSelected;
-                this.orientation = parent.orientation;
-                this.menuWidth = parent.menuWidth;
-                this.defaultCellWidth = parent.defaultCellWidth;
-                this.defaultDisabledTitleStyle = parent.defaultDisabledTitleStyle;
-                this.defaultAlign = parent.defaultAlign;
-                this.defaultAlignStyle = parent.defaultAlignStyle;
-                this.fillStyle = parent.fillStyle;
-                this.extraIndex = parent.extraIndex;
-                this.selectedMenuItemContextFieldName = parent.selectedMenuItemContextFieldName;
-                this.menuContainerStyleExdr = parent.menuContainerStyleExdr;
+                type = parent.type;
+                target = parent.target;
+                id = parent.id;
+                title = parent.title;
+                tooltip = parent.tooltip;
+                defaultEntityName = parent.defaultEntityName;
+                defaultTitleStyle = parent.defaultTitleStyle;
+                defaultSelectedStyle = parent.defaultSelectedStyle;
+                defaultWidgetStyle = parent.defaultWidgetStyle;
+                defaultTooltipStyle = parent.defaultTooltipStyle;
+                defaultMenuItemName = parent.defaultMenuItemName;
+                menuItemList.addAll(parent.menuItemList);
+                menuItemMap.putAll(parent.menuItemMap);
+                defaultPermissionOperation = parent.defaultPermissionOperation;
+                defaultPermissionEntityAction = parent.defaultPermissionEntityAction;
+                defaultAssociatedContentId = parent.defaultAssociatedContentId;
+                defaultPermissionStatusId = parent.defaultPermissionStatusId;
+                defaultPrivilegeEnumId = parent.defaultPrivilegeEnumId;
+                defaultHideIfSelected = parent.defaultHideIfSelected;
+                orientation = parent.orientation;
+                menuWidth = parent.menuWidth;
+                defaultCellWidth = parent.defaultCellWidth;
+                defaultDisabledTitleStyle = parent.defaultDisabledTitleStyle;
+                defaultAlign = parent.defaultAlign;
+                defaultAlignStyle = parent.defaultAlignStyle;
+                fillStyle = parent.fillStyle;
+                extraIndex = parent.extraIndex;
+                selectedMenuItemContextFieldName = parent.selectedMenuItemContextFieldName;
+                menuContainerStyleExdr = parent.menuContainerStyleExdr;
                 if (parent.actions != null) {
-                    this.actions = new ArrayList<ModelWidgetAction>();
-                    this.actions.addAll(parent.actions);
+                    actions.addAll(parent.actions);
                 }
             }
         }
-
-        if (this.type == null || menuElement.hasAttribute("type"))
-            this.type = menuElement.getAttribute("type");
-        if (this.target == null || menuElement.hasAttribute("target"))
-            this.target = menuElement.getAttribute("target");
-        if (this.id == null || menuElement.hasAttribute("id"))
-            this.id = menuElement.getAttribute("id");
-        if (this.title == null || menuElement.hasAttribute("title"))
-            this.setTitle(menuElement.getAttribute("title"));
-        if (this.tooltip == null || menuElement.hasAttribute("tooltip"))
-            this.tooltip = menuElement.getAttribute("tooltip");
-        if (this.defaultEntityName == null || menuElement.hasAttribute("default-entity-name"))
-            this.defaultEntityName = menuElement.getAttribute("default-entity-name");
-        if (this.defaultTitleStyle == null || menuElement.hasAttribute("default-title-style"))
-            this.defaultTitleStyle = menuElement.getAttribute("default-title-style");
-        if (this.defaultSelectedStyle == null || menuElement.hasAttribute("default-selected-style"))
-            this.defaultSelectedStyle = menuElement.getAttribute("default-selected-style");
-        if (this.defaultWidgetStyle == null || menuElement.hasAttribute("default-widget-style"))
-            this.defaultWidgetStyle = menuElement.getAttribute("default-widget-style");
-        if (this.defaultTooltipStyle == null || menuElement.hasAttribute("default-tooltip-style"))
-            this.defaultTooltipStyle = menuElement.getAttribute("default-tooltip-style");
-        if (this.defaultMenuItemName == null || menuElement.hasAttribute("default-menu-item-name"))
-            this.defaultMenuItemName = menuElement.getAttribute("default-menu-item-name");
-        if (this.defaultPermissionOperation == null || menuElement.hasAttribute("default-permission-operation"))
-            this.defaultPermissionOperation = menuElement.getAttribute("default-permission-operation");
-        if (this.defaultPermissionEntityAction == null || menuElement.hasAttribute("default-permission-entity-action"))
-            this.defaultPermissionEntityAction = menuElement.getAttribute("default-permission-entity-action");
-        if (this.defaultPermissionStatusId == null || menuElement.hasAttribute("defaultPermissionStatusId"))
-            this.defaultPermissionStatusId = menuElement.getAttribute("default-permission-status-id");
-        if (this.defaultPrivilegeEnumId == null || menuElement.hasAttribute("defaultPrivilegeEnumId"))
-            this.defaultPrivilegeEnumId = menuElement.getAttribute("default-privilege-enum-id");
-        if (this.defaultAssociatedContentId == null || menuElement.hasAttribute("defaultAssociatedContentId"))
-            this.setDefaultAssociatedContentId(menuElement.getAttribute("default-associated-content-id"));
-        if (this.orientation == null || menuElement.hasAttribute("orientation"))
-            this.orientation = menuElement.getAttribute("orientation");
-        if (this.menuWidth == null || menuElement.hasAttribute("menu-width"))
-            this.menuWidth = menuElement.getAttribute("menu-width");
-        if (this.defaultCellWidth == null || menuElement.hasAttribute("default-cell-width"))
-            this.defaultCellWidth = menuElement.getAttribute("default-cell-width");
-        if (menuElement.hasAttribute("default-hide-if-selected")) {
-            String val = menuElement.getAttribute("default-hide-if-selected");
-            if (val != null && val.equalsIgnoreCase("true"))
-                defaultHideIfSelected = Boolean.TRUE;
-            else
-                defaultHideIfSelected = Boolean.FALSE;
-        }
-        if (this.defaultDisabledTitleStyle == null || menuElement.hasAttribute("default-disabled-title-style"))
-            this.defaultDisabledTitleStyle = menuElement.getAttribute("default-disabled-title-style");
-        if (this.selectedMenuItemContextFieldName == null || menuElement.hasAttribute("selected-menuitem-context-field-name"))
-            this.selectedMenuItemContextFieldName = FlexibleMapAccessor.getInstance(menuElement.getAttribute("selected-menuitem-context-field-name"));
-        if (this.menuContainerStyleExdr == null || menuElement.hasAttribute("menu-container-style"))
-            this.setMenuContainerStyle(menuElement.getAttribute("menu-container-style"));
-        if (this.defaultAlign == null || menuElement.hasAttribute("default-align"))
-            this.defaultAlign = menuElement.getAttribute("default-align");
-        if (this.defaultAlignStyle == null || menuElement.hasAttribute("default-align-style"))
-            this.defaultAlignStyle = menuElement.getAttribute("default-align-style");
-        if (this.fillStyle == null || menuElement.hasAttribute("fill-style"))
-            this.fillStyle = menuElement.getAttribute("fill-style");
-		if (this.extraIndex == null || menuElement.hasAttribute("extra-index"))
-            this.setExtraIndex(menuElement.getAttribute("extra-index"));
-
+        if (menuElement.hasAttribute("type"))
+            type = menuElement.getAttribute("type");
+        if (menuElement.hasAttribute("target"))
+            target = menuElement.getAttribute("target");
+        if (menuElement.hasAttribute("id"))
+            id = menuElement.getAttribute("id");
+        if (menuElement.hasAttribute("title"))
+            title = FlexibleStringExpander.getInstance(menuElement.getAttribute("title"));
+        if (menuElement.hasAttribute("tooltip"))
+            tooltip = menuElement.getAttribute("tooltip");
+        if (menuElement.hasAttribute("default-entity-name"))
+            defaultEntityName = menuElement.getAttribute("default-entity-name");
+        if (menuElement.hasAttribute("default-title-style"))
+            defaultTitleStyle = menuElement.getAttribute("default-title-style");
+        if (menuElement.hasAttribute("default-selected-style"))
+            defaultSelectedStyle = menuElement.getAttribute("default-selected-style");
+        if (menuElement.hasAttribute("default-widget-style"))
+            defaultWidgetStyle = menuElement.getAttribute("default-widget-style");
+        if (menuElement.hasAttribute("default-tooltip-style"))
+            defaultTooltipStyle = menuElement.getAttribute("default-tooltip-style");
+        if (menuElement.hasAttribute("default-menu-item-name"))
+            defaultMenuItemName = menuElement.getAttribute("default-menu-item-name");
+        if (menuElement.hasAttribute("default-permission-operation"))
+            defaultPermissionOperation = menuElement.getAttribute("default-permission-operation");
+        if (menuElement.hasAttribute("default-permission-entity-action"))
+            defaultPermissionEntityAction = menuElement.getAttribute("default-permission-entity-action");
+        if (menuElement.hasAttribute("defaultPermissionStatusId"))
+            defaultPermissionStatusId = menuElement.getAttribute("default-permission-status-id");
+        if (menuElement.hasAttribute("defaultPrivilegeEnumId"))
+            defaultPrivilegeEnumId = menuElement.getAttribute("default-privilege-enum-id");
+        if (menuElement.hasAttribute("defaultAssociatedContentId"))
+            defaultAssociatedContentId = FlexibleStringExpander.getInstance(menuElement
+                    .getAttribute("default-associated-content-id"));
+        if (menuElement.hasAttribute("orientation"))
+            orientation = menuElement.getAttribute("orientation");
+        if (menuElement.hasAttribute("menu-width"))
+            menuWidth = menuElement.getAttribute("menu-width");
+        if (menuElement.hasAttribute("default-cell-width"))
+            defaultCellWidth = menuElement.getAttribute("default-cell-width");
+        if (menuElement.hasAttribute("default-hide-if-selected"))
+            defaultHideIfSelected = "true".equals(menuElement.getAttribute("default-hide-if-selected"));
+        if (menuElement.hasAttribute("default-disabled-title-style"))
+            defaultDisabledTitleStyle = menuElement.getAttribute("default-disabled-title-style");
+        if (menuElement.hasAttribute("selected-menuitem-context-field-name"))
+            selectedMenuItemContextFieldName = FlexibleMapAccessor.getInstance(menuElement
+                    .getAttribute("selected-menuitem-context-field-name"));
+        if (menuElement.hasAttribute("menu-container-style"))
+            menuContainerStyleExdr = FlexibleStringExpander.getInstance(menuElement.getAttribute("menu-container-style"));
+        if (menuElement.hasAttribute("default-align"))
+            defaultAlign = menuElement.getAttribute("default-align");
+        if (menuElement.hasAttribute("default-align-style"))
+            defaultAlignStyle = menuElement.getAttribute("default-align-style");
+        if (menuElement.hasAttribute("fill-style"))
+            fillStyle = menuElement.getAttribute("fill-style");
+        if (menuElement.hasAttribute("extra-index"))
+            extraIndex = FlexibleStringExpander.getInstance(menuElement.getAttribute("extra-index"));
         // read all actions under the "actions" element
         Element actionsElement = UtilXml.firstChildElement(menuElement, "actions");
         if (actionsElement != null) {
-            if (this.actions == null) {
-                this.actions = ModelMenuAction.readSubActions(this, actionsElement);
-            } else {
-                this.actions.addAll(ModelMenuAction.readSubActions(this, actionsElement));
-                ArrayList<ModelWidgetAction> actionsList = (ArrayList<ModelWidgetAction>)this.actions;
-                actionsList.trimToSize();
-            }
+            actions.addAll(ModelMenuAction.readSubActions(this, actionsElement));
         }
-
-        // read in add item defs, add/override one by one using the menuItemList
+        actions.trimToSize();
+        this.actions = Collections.unmodifiableList(actions);
+        this.defaultAlign = defaultAlign;
+        this.defaultAlignStyle = defaultAlignStyle;
+        this.defaultAssociatedContentId = defaultAssociatedContentId;
+        this.defaultCellWidth = defaultCellWidth;
+        this.defaultDisabledTitleStyle = defaultDisabledTitleStyle;
+        this.defaultEntityName = defaultEntityName;
+        this.defaultHideIfSelected = defaultHideIfSelected;
+        this.defaultMenuItemName = defaultMenuItemName;
+        this.defaultPermissionEntityAction = defaultPermissionEntityAction;
+        this.defaultPermissionOperation = defaultPermissionOperation;
+        this.defaultPermissionStatusId = defaultPermissionStatusId;
+        this.defaultPrivilegeEnumId = defaultPrivilegeEnumId;
+        this.defaultSelectedStyle = defaultSelectedStyle;
+        this.defaultTitleStyle = defaultTitleStyle;
+        this.defaultTooltipStyle = defaultTooltipStyle;
+        this.defaultWidgetStyle = defaultWidgetStyle;
+        this.extraIndex = extraIndex;
+        this.fillStyle = fillStyle;
+        this.id = id;
+        this.menuContainerStyleExdr = menuContainerStyleExdr;
         List<? extends Element> itemElements = UtilXml.childElementList(menuElement, "menu-item");
         for (Element itemElement : itemElements) {
             ModelMenuItem modelMenuItem = new ModelMenuItem(itemElement, this);
-            modelMenuItem = this.addUpdateMenuItem(modelMenuItem);
+            addUpdateMenuItem(modelMenuItem, menuItemList, menuItemMap);
         }
+        menuItemList.trimToSize();
+        this.menuItemList = Collections.unmodifiableList(menuItemList);
+        this.menuItemMap = Collections.unmodifiableMap(menuItemMap);
+        this.menuLocation = menuLocation;
+        this.menuWidth = menuWidth;
+        this.orientation = orientation;
+        this.selectedMenuItemContextFieldName = selectedMenuItemContextFieldName;
+        this.target = target;
+        this.title = title;
+        this.tooltip = tooltip;
+        this.type = type;
+    }
+
+    @Override
+    public void accept(ModelWidgetVisitor visitor) throws Exception {
+        visitor.visit(this);
     }
 
     /**
      * add/override modelMenuItem using the menuItemList and menuItemMap
      *
-     * @return The same ModelMenuItem, or if merged with an existing item, the existing item.
      */
-    public ModelMenuItem addUpdateMenuItem(ModelMenuItem modelMenuItem) {
-        // not a conditional item, see if a named item exists in Map
-        ModelMenuItem existingMenuItem = this.menuItemMap.get(modelMenuItem.getName());
+    private void addUpdateMenuItem(ModelMenuItem modelMenuItem, List<ModelMenuItem> menuItemList,
+            Map<String, ModelMenuItem> menuItemMap) {
+        ModelMenuItem existingMenuItem = menuItemMap.get(modelMenuItem.getName());
         if (existingMenuItem != null) {
             // does exist, update the item by doing a merge/override
-            existingMenuItem.mergeOverrideModelMenuItem(modelMenuItem);
-            return existingMenuItem;
+            ModelMenuItem mergedMenuItem = existingMenuItem.mergeOverrideModelMenuItem(modelMenuItem);
+            int existingItemIndex = menuItemList.indexOf(existingMenuItem);
+            menuItemList.set(existingItemIndex, mergedMenuItem);
+            menuItemMap.put(modelMenuItem.getName(), mergedMenuItem);
         } else {
-            // does not exist, add to List and Map
-            this.menuItemList.add(modelMenuItem);
-            this.menuItemMap.put(modelMenuItem.getName(), modelMenuItem);
-            return modelMenuItem;
+            // does not exist, add to Map
+            menuItemList.add(modelMenuItem);
+            menuItemMap.put(modelMenuItem.getName(), modelMenuItem);
         }
     }
 
+    public List<ModelWidgetAction> getActions() {
+        return actions;
+    }
+
+    @Override
+    public String getBoundaryCommentName() {
+        return menuLocation + "#" + getName();
+    }
+
+    public String getCurrentMenuName(Map<String, Object> context) {
+        return getName();
+    }
+
+    public String getDefaultAlign() {
+        return this.defaultAlign;
+    }
+
+    public String getDefaultAlignStyle() {
+        return this.defaultAlignStyle;
+    }
+
+    public FlexibleStringExpander getDefaultAssociatedContentId() {
+        return defaultAssociatedContentId;
+    }
+
+    public String getDefaultAssociatedContentId(Map<String, Object> context) {
+        return defaultAssociatedContentId.expandString(context);
+    }
+
+    public String getDefaultCellWidth() {
+        return this.defaultCellWidth;
+    }
+
+    public String getDefaultDisabledTitleStyle() {
+        return this.defaultDisabledTitleStyle;
+    }
+
+    public String getDefaultEntityName() {
+        return this.defaultEntityName;
+    }
+
+    public Boolean getDefaultHideIfSelected() {
+        return this.defaultHideIfSelected;
+    }
+
+    public String getDefaultMenuItemName() {
+        return this.defaultMenuItemName;
+    }
+
+    public String getDefaultPermissionEntityAction() {
+        return this.defaultPermissionEntityAction;
+    }
+
+    public String getDefaultPermissionOperation() {
+        return this.defaultPermissionOperation;
+    }
+
+    public String getDefaultPermissionStatusId() {
+        return this.defaultPermissionStatusId;
+    }
+
+    public String getDefaultPrivilegeEnumId() {
+        return this.defaultPrivilegeEnumId;
+    }
+
+    public String getDefaultSelectedStyle() {
+        return this.defaultSelectedStyle;
+    }
+
+    public String getDefaultTitleStyle() {
+        return this.defaultTitleStyle;
+    }
+
+    public String getDefaultTooltipStyle() {
+        return this.defaultTooltipStyle;
+    }
+
+    public String getDefaultWidgetStyle() {
+        return this.defaultWidgetStyle;
+    }
+
+    public FlexibleStringExpander getExtraIndex() {
+        return extraIndex;
+    }
+
+    public String getExtraIndex(Map<String, Object> context) {
+        try {
+            return extraIndex.expandString(context);
+        } catch (Exception ex) {
+            return "";
+        }
+    }
+
+    public String getFillStyle() {
+        return this.fillStyle;
+    }
+
+    public String getId() {
+        return this.id;
+    }
+
+    public String getMenuContainerStyle(Map<String, Object> context) {
+        return menuContainerStyleExdr.expandString(context);
+    }
+
+    public FlexibleStringExpander getMenuContainerStyleExdr() {
+        return menuContainerStyleExdr;
+    }
+
+    public List<ModelMenuItem> getMenuItemList() {
+        return menuItemList;
+    }
+
+    public Map<String, ModelMenuItem> getMenuItemMap() {
+        return menuItemMap;
+    }
+
+    public String getMenuLocation() {
+        return menuLocation;
+    }
+
+    public String getMenuWidth() {
+        return this.menuWidth;
+    }
+
     public ModelMenuItem getModelMenuItemByName(String name) {
         return this.menuItemMap.get(name);
     }
 
+    public String getOrientation() {
+        return this.orientation;
+    }
+
+    public FlexibleMapAccessor<String> getSelectedMenuItemContextFieldName() {
+        return selectedMenuItemContextFieldName;
+    }
+
+    public String getSelectedMenuItemContextFieldName(Map<String, Object> context) {
+        String menuItemName = this.selectedMenuItemContextFieldName.get(context);
+        if (UtilValidate.isEmpty(menuItemName)) {
+            return this.defaultMenuItemName;
+        }
+        return menuItemName;
+    }
+
+    public String getTarget() {
+        return target;
+    }
+
+    public FlexibleStringExpander getTitle() {
+        return title;
+    }
+
+    public String getTitle(Map<String, Object> context) {
+        return title.expandString(context);
+    }
+
+    public String getTooltip() {
+        return this.tooltip;
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
+    public int renderedMenuItemCount(Map<String, Object> context) {
+        int count = 0;
+        for (ModelMenuItem item : this.menuItemList) {
+            if (item.shouldBeRendered(context))
+                count++;
+        }
+        return count;
+    }
+
     /**
      * Renders this menu to a String, i.e. in a text format, as defined with the
      * MenuStringRenderer implementation.
@@ -279,30 +516,19 @@
      *   different menu elements; implementing you own makes it possible to
      *   use the same menu definitions for many types of menu UIs
      */
-    public void renderMenuString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer) throws IOException {
+    public void renderMenuString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer)
+            throws IOException {
         ModelWidgetAction.runSubActions(this.actions, context);
         if ("simple".equals(this.type)) {
             this.renderSimpleMenuString(writer, context, menuStringRenderer);
         } else {
-            throw new IllegalArgumentException("The type " + this.getType() + " is not supported for menu with name " + this.getName());
+            throw new IllegalArgumentException("The type " + this.getType() + " is not supported for menu with name "
+                    + this.getName());
         }
     }
 
-    public void runActions(Map<String, Object> context) {
-        ModelWidgetAction.runSubActions(this.actions, context);
-    }
-
-    public int renderedMenuItemCount(Map<String, Object> context)
-    {
-        int count = 0;
-        for (ModelMenuItem item : this.menuItemList) {
-            if (item.shouldBeRendered(context))
-                count++;
-        }
-        return count;
-    }
-    
-    public void renderSimpleMenuString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer) throws IOException {
+    public void renderSimpleMenuString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer)
+            throws IOException {
         // render menu open
         menuStringRenderer.renderMenuOpen(writer, context, this);
 
@@ -320,290 +546,7 @@
         menuStringRenderer.renderMenuClose(writer, context, this);
     }
 
-    public String getDefaultEntityName() {
-        return this.defaultEntityName;
-    }
-
-    public String getDefaultAlign() {
-        return this.defaultAlign;
-    }
-
-    public String getDefaultAlignStyle() {
-        return this.defaultAlignStyle;
-    }
-
-    public String getDefaultTitleStyle() {
-        return this.defaultTitleStyle;
-    }
-
-    public String getDefaultDisabledTitleStyle() {
-        return this.defaultDisabledTitleStyle;
-    }
-
-    public String getDefaultSelectedStyle() {
-        return this.defaultSelectedStyle;
-    }
-
-    public String getDefaultWidgetStyle() {
-        return this.defaultWidgetStyle;
-    }
-
-    public String getDefaultTooltipStyle() {
-        return this.defaultTooltipStyle;
-    }
-
-    public String getDefaultMenuItemName() {
-        return this.defaultMenuItemName;
-    }
-
-    public String getFillStyle() {
-        return this.fillStyle;
-    }
-
-    public String getSelectedMenuItemContextFieldName(Map<String, Object> context) {
-        String menuItemName = this.selectedMenuItemContextFieldName.get(context);
-        if (UtilValidate.isEmpty(menuItemName)) {
-            return this.defaultMenuItemName;
-        }
-        return menuItemName;
-    }
-
-    public String getCurrentMenuName(Map<String, Object> context) {
-        return getName();
-    }
-
-    public String getId() {
-        return this.id;
-    }
-
-    public String getTitle(Map<String, Object> context) {
-        return title.expandString(context);
-    }
-
-    public String getTooltip() {
-        return this.tooltip;
-    }
-
-    public String getType() {
-        return this.type;
-    }
-
-    @Override
-    public String getBoundaryCommentName() {
-        return menuLocation + "#" + getName();
-    }
-
-    /**
-     * @param string
-     */
-    public void setDefaultEntityName(String string) {
-        this.defaultEntityName = string;
-    }
-
-
-    /**
-     * @param string
-     */
-    public void setDefaultTitleStyle(String string) {
-        this.defaultTitleStyle = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setDefaultSelectedStyle(String string) {
-        this.defaultSelectedStyle = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setDefaultWidgetStyle(String string) {
-        this.defaultWidgetStyle = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setDefaultTooltipStyle(String string) {
-        this.defaultTooltipStyle = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setDefaultMenuItemName(String string) {
-        this.defaultMenuItemName = string;
-    }
-
-    /**
-     * @param menuLocation the menu location to set
-     */
-    public void setMenuLocation(String menuLocation) {
-        this.menuLocation = menuLocation;
-    }
-
-    /**
-     * @param string
-     */
-    public void setTarget(String string) {
-        this.target = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setId(String string) {
-        this.id = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setTitle(String string) {
-        this.title = FlexibleStringExpander.getInstance(string);
-    }
-
-    /**
-     * @param string
-     */
-    public void setTooltip(String string) {
-        this.tooltip = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setType(String string) {
-        this.type = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setDefaultAssociatedContentId(String string) {
-        this.defaultAssociatedContentId = FlexibleStringExpander.getInstance(string);
-    }
-
-    /**
-     * @param string
-     */
-    public void setMenuContainerStyle(String string) {
-        this.menuContainerStyleExdr = FlexibleStringExpander.getInstance(string);
-    }
-
-    public String getDefaultAssociatedContentId(Map<String, Object> context) {
-        return defaultAssociatedContentId.expandString(context);
-    }
-    public String getMenuContainerStyle(Map<String, Object> context) {
-        return menuContainerStyleExdr.expandString(context);
-    }
-
-    /**
-     * @param string
-     */
-    public void setDefaultPermissionOperation(String string) {
-        this.defaultPermissionOperation = string;
-    }
-
-    public String getDefaultPermissionStatusId() {
-        return this.defaultPermissionStatusId;
-    }
-
-    /**
-     * @param string
-     */
-    public void setDefaultPermissionStatusId(String string) {
-        this.defaultPermissionStatusId = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setDefaultPrivilegeEnumId(String string) {
-        this.defaultPrivilegeEnumId = string;
-    }
-
-    public String getDefaultPrivilegeEnumId() {
-        return this.defaultPrivilegeEnumId;
-    }
-
-    /**
-     * @param string
-     */
-    public void setOrientation(String string) {
-        this.orientation = string;
-    }
-
-    public String getOrientation() {
-        return this.orientation;
-    }
-
-    /**
-     * @param string
-     */
-    public void setMenuWidth(String string) {
-        this.menuWidth = string;
-    }
-
-    public String getMenuWidth() {
-        return this.menuWidth;
-    }
-
-    /**
-     * @param string
-     */
-    public void setDefaultCellWidth(String string) {
-        this.defaultCellWidth = string;
-    }
-
-    public String getDefaultCellWidth() {
-        return this.defaultCellWidth;
-    }
-
-    public String getDefaultPermissionOperation() {
-        return this.defaultPermissionOperation;
-    }
-
-    /**
-     * @param string
-     */
-    public void setDefaultPermissionEntityAction(String string) {
-        this.defaultPermissionEntityAction = string;
-    }
-
-    public String getDefaultPermissionEntityAction() {
-        return this.defaultPermissionEntityAction;
-    }
-
-    /**
-     * @param val
-     */
-    public void setDefaultHideIfSelected(Boolean val) {
-        this.defaultHideIfSelected = val;
-    }
-
-    public Boolean getDefaultHideIfSelected() {
-        return this.defaultHideIfSelected;
-    }
-
-    public List<ModelMenuItem> getMenuItemList() {
-        return menuItemList;
-    }
-	public String getExtraIndex(Map<String, Object> context) {
-        try {
-            return extraIndex.expandString(context);
-        } catch (Exception ex) {
-            return "";
-        }
-    }
-
-    public void setExtraIndex(String extraIndex) {
-        this.extraIndex = FlexibleStringExpander.getInstance(extraIndex);
-    }
-
-    @Override
-    public void accept(ModelWidgetVisitor visitor) throws Exception {
-        visitor.visit(this);
+    public void runActions(Map<String, Object> context) {
+        ModelWidgetAction.runSubActions(this.actions, context);
     }
 }
diff --git a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuAction.java b/framework/widget/src/org/ofbiz/widget/menu/ModelMenuAction.java
index 8c63b62..6fae76d 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuAction.java
+++ b/framework/widget/src/org/ofbiz/widget/menu/ModelMenuAction.java
@@ -43,7 +43,7 @@
 import org.w3c.dom.Element;
 
 /**
- * Widget Library - Screen model class
+ * Abstract menu action.
  */
 public abstract class ModelMenuAction {
 
@@ -56,22 +56,27 @@
             if ("set".equals(actionElement.getNodeName())) {
                 actions.add(new SetField(modelMenu, actionElement));
             } else {
-                actions.add(ModelWidgetAction.toModelWidgetAction(modelMenu, actionElement));
+                actions.add(ModelWidgetAction.newInstance(modelMenu, actionElement));
             }
         }
         return Collections.unmodifiableList(actions);
     }
 
+    /**
+     * Models the &lt;set&gt; element.
+     * 
+     * @see <code>widget-common.xsd</code>
+     */
     @SuppressWarnings("serial")
     public static class SetField extends ModelWidgetAction {
-        protected FlexibleMapAccessor<Object> field;
-        protected FlexibleMapAccessor<Object> fromField;
-        protected FlexibleStringExpander valueExdr;
-        protected FlexibleStringExpander defaultExdr;
-        protected FlexibleStringExpander globalExdr;
-        protected String type;
-        protected String toScope;
-        protected String fromScope;
+        private final FlexibleMapAccessor<Object> field;
+        private final FlexibleMapAccessor<Object> fromField;
+        private final FlexibleStringExpander valueExdr;
+        private final FlexibleStringExpander defaultExdr;
+        private final FlexibleStringExpander globalExdr;
+        private final String type;
+        private final String toScope;
+        private final String fromScope;
 
         public SetField(ModelMenu modelMenu, Element setElement) {
             super (modelMenu, setElement);
diff --git a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuCondition.java b/framework/widget/src/org/ofbiz/widget/menu/ModelMenuCondition.java
index 2306bac..721ce77 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuCondition.java
+++ b/framework/widget/src/org/ofbiz/widget/menu/ModelMenuCondition.java
@@ -18,545 +18,48 @@
  *******************************************************************************/
 package org.ofbiz.widget.menu;
 
-import java.lang.reflect.Method;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TimeZone;
-
-import org.apache.oro.text.regex.MalformedPatternException;
-import org.apache.oro.text.regex.Pattern;
-import org.apache.oro.text.regex.PatternMatcher;
-import org.apache.oro.text.regex.Perl5Matcher;
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.ObjectType;
-import org.ofbiz.base.util.PatternFactory;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.collections.FlexibleMapAccessor;
 import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.entityext.permission.EntityPermissionChecker;
-import org.ofbiz.minilang.operation.BaseCompare;
-import org.ofbiz.security.Security;
-import org.ofbiz.service.DispatchContext;
-import org.ofbiz.service.GenericServiceException;
-import org.ofbiz.service.LocalDispatcher;
-import org.ofbiz.service.ModelService;
-import org.ofbiz.service.ServiceUtil;
+import org.ofbiz.widget.ModelWidgetCondition;
 import org.w3c.dom.Element;
 
 /**
- * Widget Library - Screen model condition class
+ * Models the &lt;condition&gt; element.
+ * 
+ * @see <code>widget-menu.xsd</code>
  */
-public class ModelMenuCondition {
+@SuppressWarnings("serial")
+public class ModelMenuCondition extends ModelWidgetCondition {
+
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     DEVELOPERS PLEASE READ
+     * ----------------------------------------------------------------------- *
+     * 
+     * This model is intended to be a read-only data structure that represents
+     * an XML element. Outside of object construction, the class should not
+     * have any behaviors.
+     * 
+     * Instances of this class will be shared by multiple threads - therefore
+     * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME!
+     * 
+     */
+
     public static final String module = ModelMenuCondition.class.getName();
 
-    protected ModelMenuItem modelMenuItem;
-    protected MenuCondition rootCondition;
-    protected FlexibleStringExpander passStyleExdr;
-    protected FlexibleStringExpander failStyleExdr;
+    private final FlexibleStringExpander passStyleExdr;
+    private final FlexibleStringExpander failStyleExdr;
 
     public ModelMenuCondition(ModelMenuItem modelMenuItem, Element conditionElement) {
-        this.modelMenuItem = modelMenuItem;
+        super(ModelWidgetCondition.DEFAULT_CONDITION_FACTORY, modelMenuItem, conditionElement);
         this.passStyleExdr = FlexibleStringExpander.getInstance(conditionElement.getAttribute("pass-style"));
         this.failStyleExdr = FlexibleStringExpander.getInstance(conditionElement.getAttribute("disabled-style"));
-        Element firstChildElement = UtilXml.firstChildElement(conditionElement);
-        this.rootCondition = readCondition(modelMenuItem, firstChildElement);
     }
 
-    public boolean eval(Map<String, Object> context) {
-        if (rootCondition == null) {
-            return true;
-        }
-        boolean cond = rootCondition.eval(context);
-        if (cond) {
-            String passStyle = passStyleExdr.expandString(context);
-            if (UtilValidate.isNotEmpty(passStyle)) {
-                modelMenuItem.setWidgetStyle(passStyle);
-            }
-            modelMenuItem.setDisabled(false);
-        } else {
-            String failStyle = failStyleExdr.expandString(context);
-            if (UtilValidate.isNotEmpty(failStyle)) {
-                modelMenuItem.setDisabledTitleStyle(failStyle);
-                modelMenuItem.setDisabled(true);
-                cond = true;
-            }
-        }
-        return cond;
+    public FlexibleStringExpander getFailStyleExdr() {
+        return failStyleExdr;
     }
 
-    public static abstract class MenuCondition {
-        protected ModelMenuItem modelMenuItem;
-
-        public MenuCondition(ModelMenuItem modelMenuItem, Element conditionElement) {
-            this.modelMenuItem = modelMenuItem;
-        }
-
-        public abstract boolean eval(Map<String, Object> context);
-    }
-
-    public static List<MenuCondition> readSubConditions(ModelMenuItem modelMenuItem, Element conditionElement) {
-        List<MenuCondition> condList = new LinkedList<MenuCondition>();
-        List<? extends Element> subElementList = UtilXml.childElementList(conditionElement);
-        for (Element subElement: subElementList) {
-            condList.add(readCondition(modelMenuItem, subElement));
-        }
-        return condList;
-    }
-
-    public static MenuCondition readCondition(ModelMenuItem modelMenuItem, Element conditionElement) {
-        if (conditionElement == null) {
-            return null;
-        }
-        if ("and".equals(conditionElement.getNodeName())) {
-            return new And(modelMenuItem, conditionElement);
-        } else if ("xor".equals(conditionElement.getNodeName())) {
-            return new Xor(modelMenuItem, conditionElement);
-        } else if ("or".equals(conditionElement.getNodeName())) {
-            return new Or(modelMenuItem, conditionElement);
-        } else if ("not".equals(conditionElement.getNodeName())) {
-            return new Not(modelMenuItem, conditionElement);
-        } else if ("if-service-permission".equals(conditionElement.getNodeName())) {
-            return new IfServicePermission(modelMenuItem, conditionElement);
-        } else if ("if-has-permission".equals(conditionElement.getNodeName())) {
-            return new IfHasPermission(modelMenuItem, conditionElement);
-        } else if ("if-validate-method".equals(conditionElement.getNodeName())) {
-            return new IfValidateMethod(modelMenuItem, conditionElement);
-        } else if ("if-compare".equals(conditionElement.getNodeName())) {
-            return new IfCompare(modelMenuItem, conditionElement);
-        } else if ("if-compare-field".equals(conditionElement.getNodeName())) {
-            return new IfCompareField(modelMenuItem, conditionElement);
-        } else if ("if-regexp".equals(conditionElement.getNodeName())) {
-            return new IfRegexp(modelMenuItem, conditionElement);
-        } else if ("if-empty".equals(conditionElement.getNodeName())) {
-            return new IfEmpty(modelMenuItem, conditionElement);
-        } else if ("if-entity-permission".equals(conditionElement.getNodeName())) {
-            return new IfEntityPermission(modelMenuItem, conditionElement);
-        } else {
-            throw new IllegalArgumentException("Condition element not supported with name: " + conditionElement.getNodeName());
-        }
-    }
-
-    public static class And extends MenuCondition {
-        protected List<MenuCondition> subConditions;
-
-        public And(ModelMenuItem modelMenuItem, Element condElement) {
-            super (modelMenuItem, condElement);
-            this.subConditions = readSubConditions(modelMenuItem, condElement);
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            // return false for the first one in the list that is false, basic and algo
-            for (MenuCondition subCondition: this.subConditions) {
-                if (!subCondition.eval(context)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-
-    public static class Xor extends MenuCondition {
-        protected List<MenuCondition> subConditions;
-
-        public Xor(ModelMenuItem modelMenuItem, Element condElement) {
-            super (modelMenuItem, condElement);
-            this.subConditions = readSubConditions(modelMenuItem, condElement);
-        }
-
-        @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 (MenuCondition subCondition: this.subConditions) {
-                if (subCondition.eval(context)) {
-                    if (foundOneTrue) {
-                        // now found two true, so return false
-                        return false;
-                    } else {
-                        foundOneTrue = true;
-                    }
-                }
-            }
-            return foundOneTrue;
-        }
-    }
-
-    public static class Or extends MenuCondition {
-        protected List<MenuCondition> subConditions;
-
-        public Or(ModelMenuItem modelMenuItem, Element condElement) {
-            super (modelMenuItem, condElement);
-            this.subConditions = readSubConditions(modelMenuItem, condElement);
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            // return true for the first one in the list that is true, basic or algo
-            for (MenuCondition subCondition: this.subConditions) {
-                if (subCondition.eval(context)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
-    public static class Not extends MenuCondition {
-        protected MenuCondition subCondition;
-
-        public Not(ModelMenuItem modelMenuItem, Element condElement) {
-            super (modelMenuItem, condElement);
-            Element firstChildElement = UtilXml.firstChildElement(condElement);
-            this.subCondition = readCondition(modelMenuItem, firstChildElement);
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            return !this.subCondition.eval(context);
-        }
-    }
-
-    public static class IfServicePermission extends MenuCondition {
-        protected FlexibleStringExpander serviceExdr;
-        protected FlexibleStringExpander actionExdr;
-        protected FlexibleStringExpander resExdr;
-
-        public IfServicePermission(ModelMenuItem modelMenuItem, Element condElement) {
-            super(modelMenuItem, condElement);
-            this.serviceExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("service-name"));
-            this.actionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("main-action"));
-            this.resExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("resource-description"));
-        }
-
-        @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");
-            if (userLogin != null) {
-                String serviceName = serviceExdr.expandString(context);
-                String mainAction = actionExdr.expandString(context);
-                String resource = resExdr.expandString(context);
-                if (resource == null) {
-                    resource = serviceName;
-                }
-
-                if (serviceName == null) {
-                    Debug.logWarning("No permission service-name specified!", module);
-                    return false;
-                }
-
-                // get the service objects
-                LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
-                DispatchContext dctx = dispatcher.getDispatchContext();
-
-                // get the service
-                ModelService permService;
-                try {
-                    permService = dctx.getModelService(serviceName);
-                } catch (GenericServiceException e) {
-                    Debug.logError(e, module);
-                    return false;
-                }
-
-                if (permService != null) {
-                    // build the context
-                    Map<String, Object> svcCtx = permService.makeValid(context, ModelService.IN_PARAM);
-                    svcCtx.put("resourceDescription", resource);
-                    if (UtilValidate.isNotEmpty(mainAction)) {
-                        svcCtx.put("mainAction", mainAction);
-                    }
-
-                    // invoke the service
-                    Map<String, Object> resp;
-                    try {
-                        resp = dispatcher.runSync(permService.name,  svcCtx, 300, true);
-                    } catch (GenericServiceException e) {
-                        Debug.logError(e, module);
-                        return false;
-                    }
-                    if (ServiceUtil.isError(resp) || ServiceUtil.isFailure(resp)) {
-                        Debug.logError(ServiceUtil.getErrorMessage(resp), module);
-                        return false;
-                    }
-                    Boolean hasPermission = (Boolean) resp.get("hasPermission");
-                    if (hasPermission != null) {
-                        return hasPermission.booleanValue();
-                    }
-                }
-            }
-            return false;
-        }
-    }
-
-    public static class IfHasPermission extends MenuCondition {
-        protected FlexibleStringExpander permissionExdr;
-        protected FlexibleStringExpander actionExdr;
-
-        public IfHasPermission(ModelMenuItem modelMenuItem, Element condElement) {
-            super (modelMenuItem, condElement);
-            this.permissionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("permission"));
-            this.actionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("action"));
-        }
-
-        @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");
-            if (userLogin != null) {
-                String permission = permissionExdr.expandString(context);
-                String action = actionExdr.expandString(context);
-                Security security = (Security) context.get("security");
-                if (UtilValidate.isNotEmpty(action)) {
-                    // run hasEntityPermission
-                    if (security.hasEntityPermission(permission, action, userLogin)) {
-                        return true;
-                    }
-                } else {
-                    // run hasPermission
-                    if (security.hasPermission(permission, userLogin)) {
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-    }
-
-    public static class IfValidateMethod extends MenuCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-        protected FlexibleStringExpander methodExdr;
-        protected FlexibleStringExpander classExdr;
-
-        public IfValidateMethod(ModelMenuItem modelMenuItem, Element condElement) {
-            super (modelMenuItem, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-            this.methodExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("method"));
-            this.classExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("class"));
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            String methodName = this.methodExdr.expandString(context);
-            String className = this.classExdr.expandString(context);
-
-            Object fieldVal = this.fieldAcsr.get(context);
-            String fieldString = null;
-            if (fieldVal != null) {
-                try {
-                    fieldString = (String) ObjectType.simpleTypeConvert(fieldVal, "String", null, (TimeZone) context.get("timeZone"), (Locale) context.get("locale"), true);
-                } catch (GeneralException e) {
-                    Debug.logError(e, "Could not convert object to String, using empty String", module);
-                }
-            }
-
-            // always use an empty string by default
-            if (fieldString == null) fieldString = "";
-
-            Class<?>[] paramTypes = new Class[] {String.class};
-            Object[] params = new Object[] {fieldString};
-
-            Class<?> valClass;
-            try {
-                valClass = ObjectType.loadClass(className);
-            } catch (ClassNotFoundException cnfe) {
-                Debug.logError("Could not find validation class: " + className, module);
-                return false;
-            }
-
-            Method valMethod;
-            try {
-                valMethod = valClass.getMethod(methodName, paramTypes);
-            } catch (NoSuchMethodException cnfe) {
-                Debug.logError("Could not find validation method: " + methodName + " of class " + className, module);
-                return false;
-            }
-
-            Boolean resultBool = Boolean.FALSE;
-            try {
-                resultBool = (Boolean) valMethod.invoke(null, params);
-            } catch (Exception e) {
-                Debug.logError(e, "Error in IfValidationMethod " + methodName + " of class " + className + ", defaulting to false ", module);
-            }
-
-            return resultBool.booleanValue();
-        }
-    }
-
-    public static class IfCompare extends MenuCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-        protected FlexibleStringExpander valueExdr;
-
-        protected String operator;
-        protected String type;
-        protected FlexibleStringExpander formatExdr;
-
-        public IfCompare(ModelMenuItem modelMenuItem, Element condElement) {
-            super (modelMenuItem, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-            this.valueExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("value"));
-
-            this.operator = condElement.getAttribute("operator");
-            this.type = condElement.getAttribute("type");
-
-            this.formatExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("format"));
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            String value = this.valueExdr.expandString(context);
-            String format = this.formatExdr.expandString(context);
-
-            Object fieldVal = this.fieldAcsr.get(context);
-
-            // always use an empty string by default
-            if (fieldVal == null) {
-                fieldVal = "";
-            }
-
-            List<Object> messages = new LinkedList<Object>();
-            Boolean resultBool = BaseCompare.doRealCompare(fieldVal, value, operator, type, format, messages, null, null, true);
-            if (messages.size() > 0) {
-                messages.add(0, "Error with comparison in if-compare between field [" + fieldAcsr.toString() + "] with value [" + fieldVal + "] and value [" + value + "] with operator [" + operator + "] and type [" + type + "]: ");
-
-                StringBuilder fullString = new StringBuilder();
-                for (Object message: messages) {
-                    fullString.append((String) message);
-                }
-                Debug.logWarning(fullString.toString(), module);
-
-                throw new IllegalArgumentException(fullString.toString());
-            }
-
-            return resultBool.booleanValue();
-        }
-    }
-
-    public static class IfCompareField extends MenuCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-        protected FlexibleMapAccessor<Object> toFieldAcsr;
-
-        protected String operator;
-        protected String type;
-        protected FlexibleStringExpander formatExdr;
-
-        public IfCompareField(ModelMenuItem modelMenuItem, Element condElement) {
-            super (modelMenuItem, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-            this.toFieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("to-field"));
-            if (this.toFieldAcsr.isEmpty()) this.toFieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("to-field-name"));
-
-            this.operator = condElement.getAttribute("operator");
-            this.type = condElement.getAttribute("type");
-
-            this.formatExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("format"));
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            String format = this.formatExdr.expandString(context);
-
-            Object fieldVal = this.fieldAcsr.get(context);
-            Object toFieldVal = this.toFieldAcsr.get(context);
-
-            // always use an empty string by default
-            if (fieldVal == null) {
-                fieldVal = "";
-            }
-
-            List<Object> messages = new LinkedList<Object>();
-            Boolean resultBool = BaseCompare.doRealCompare(fieldVal, toFieldVal, operator, type, format, messages, null, null, false);
-            if (messages.size() > 0) {
-                messages.add(0, "Error with comparison in if-compare-field between field [" + fieldAcsr.toString() + "] with value [" + fieldVal + "] and to-field [" + toFieldVal.toString() + "] with value [" + toFieldVal + "] with operator [" + operator + "] and type [" + type + "]: ");
-
-                StringBuilder fullString = new StringBuilder();
-                for (Object message: messages) {
-                    fullString.append((String) message);
-                }
-                Debug.logWarning(fullString.toString(), module);
-
-                throw new IllegalArgumentException(fullString.toString());
-            }
-
-            return resultBool.booleanValue();
-        }
-    }
-
-    public static class IfRegexp extends MenuCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-        protected FlexibleStringExpander exprExdr;
-
-        public IfRegexp(ModelMenuItem modelMenuItem, Element condElement) {
-            super (modelMenuItem, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-            this.exprExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("expr"));
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            Object fieldVal = this.fieldAcsr.get(context);
-            String expr = this.exprExdr.expandString(context);
-            Pattern pattern = null;
-
-            try {
-                pattern = PatternFactory.createOrGetPerl5CompiledPattern(expr, true);
-            } catch (MalformedPatternException e) {
-                String errMsg = "Error in evaluation in if-regexp in screen: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-
-            String fieldString = null;
-            try {
-                fieldString = (String) ObjectType.simpleTypeConvert(fieldVal, "String", null, (TimeZone) context.get("timeZone"), (Locale) context.get("locale"), true);
-            } catch (GeneralException e) {
-                Debug.logError(e, "Could not convert object to String, using empty String", module);
-            }
-            // always use an empty string by default
-            if (fieldString == null) fieldString = "";
-
-            PatternMatcher matcher = new Perl5Matcher();
-            return matcher.matches(fieldString, pattern);
-        }
-    }
-
-    public static class IfEmpty extends MenuCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-
-        public IfEmpty(ModelMenuItem modelMenuItem, Element condElement) {
-            super (modelMenuItem, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            Object fieldVal = this.fieldAcsr.get(context);
-            return ObjectType.isEmpty(fieldVal);
-        }
-    }
-    public static class IfEntityPermission extends MenuCondition {
-        protected EntityPermissionChecker permissionChecker;
-
-        public IfEntityPermission(ModelMenuItem modelMenuItem, Element condElement) {
-            super (modelMenuItem, condElement);
-            this.permissionChecker = new EntityPermissionChecker(condElement);
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-
-            boolean passed = permissionChecker.runPermissionCheck(context);
-            return passed;
-        }
+    public FlexibleStringExpander getPassStyleExdr() {
+        return passStyleExdr;
     }
 }
diff --git a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuItem.java b/framework/widget/src/org/ofbiz/widget/menu/ModelMenuItem.java
index 8807ae9..fcc05a6 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuItem.java
+++ b/framework/widget/src/org/ofbiz/widget/menu/ModelMenuItem.java
@@ -20,8 +20,8 @@
 
 import java.io.IOException;
 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;
@@ -29,8 +29,7 @@
 import javax.xml.parsers.ParserConfigurationException;
 
 import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.StringUtil;
-import org.ofbiz.base.util.UtilFormatOut;
+import org.ofbiz.base.util.UtilCodec;
 import org.ofbiz.base.util.UtilProperties;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.base.util.UtilXml;
@@ -41,115 +40,105 @@
 import org.ofbiz.widget.ModelWidgetAction;
 import org.ofbiz.widget.ModelWidgetVisitor;
 import org.ofbiz.widget.PortalPageWorker;
-import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.WidgetWorker.AutoEntityParameters;
+import org.ofbiz.widget.WidgetWorker.AutoServiceParameters;
+import org.ofbiz.widget.WidgetWorker.Parameter;
 import org.w3c.dom.Element;
 import org.xml.sax.SAXException;
 
 /**
- * Widget Library - Form model class
+ * Models the &lt;menu-item&gt; element.
+ * 
+ * @see <code>widget-menu.xsd</code>
  */
 @SuppressWarnings("serial")
 public class ModelMenuItem extends ModelWidget {
 
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     DEVELOPERS PLEASE READ
+     * ----------------------------------------------------------------------- *
+     * 
+     * This model is intended to be a read-only data structure that represents
+     * an XML element. Outside of object construction, the class should not
+     * have any behaviors.
+     * 
+     * Instances of this class will be shared by multiple threads - therefore
+     * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME!
+     * 
+     */
+
     public static final String module = ModelMenuItem.class.getName();
 
-    protected List<ModelWidgetAction> actions;
-    protected String align;
-    protected String alignStyle;
-    protected FlexibleStringExpander associatedContentId;
-    protected String cellWidth;
-    protected ModelMenuCondition condition;
-    protected Map<String, Object> dataMap = new HashMap<String, Object>();
-    protected boolean disabled = false;
-    protected String disabledTitleStyle;
-    protected String disableIfEmpty;
-    protected String entityName;
-    protected Boolean hasPermission;
-    protected Boolean hideIfSelected;
-    protected Link link;
-    /** This List will contain one copy of each item for each item name in the order
-     * they were encountered in the service, entity, or menu definition; item definitions
-     * with constraints will also be in this list but may appear multiple times for the same
-     * item name.
-     *
-     * When rendering the menu the order in this list should be following and it should not be
-     * necessary to use the Map. The Map is used when loading the menu definition to keep the
-     * list clean and implement the override features for item definitions.
-     */
-    protected List<ModelMenuItem> menuItemList = new LinkedList<ModelMenuItem>();
-    /** This Map is keyed with the item name and has a ModelMenuItem for the value; items
-     * with conditions will not be put in this Map so item definition overrides for items
-     * with conditions is not possible.
-     */
-    protected Map<String, ModelMenuItem> menuItemMap = new HashMap<String, ModelMenuItem>();
-    protected ModelMenu modelMenu;
-    protected String overrideName = null;
-    protected ModelMenuItem parentMenuItem;
-    protected FlexibleStringExpander parentPortalPageId;
-    protected Integer position = null;
-    protected String selectedStyle;
-    protected ModelMenu subMenu;
-    protected FlexibleStringExpander title;
-    protected String titleStyle;
-    protected FlexibleStringExpander tooltip;
-    protected String tooltipStyle;
-    protected String widgetStyle;
+    private final List<ModelWidgetAction> actions;
+    private final String align;
+    private final String alignStyle;
+    private final FlexibleStringExpander associatedContentId;
+    private final String cellWidth;
+    private final ModelMenuCondition condition;
+    private final String disabledTitleStyle;
+    private final String disableIfEmpty;
+    private final String entityName;
+    private final Boolean hideIfSelected;
+    private final Link link;
+    private final List<ModelMenuItem> menuItemList;
+    private final ModelMenu modelMenu;
+    private final String overrideName;
+    private final ModelMenuItem parentMenuItem;
+    private final FlexibleStringExpander parentPortalPageId;
+    private final Integer position;
+    private final String selectedStyle;
+    private final ModelMenu subMenu;
+    private final FlexibleStringExpander title;
+    private final String titleStyle;
+    private final FlexibleStringExpander tooltip;
+    private final String tooltipStyle;
+    private final String widgetStyle;
 
     // ===== CONSTRUCTORS =====
-    public ModelMenuItem(String name) {
-        super(name);
-    }
-
-    public ModelMenuItem(Element menuItemElement) {
-        super(menuItemElement);
-        loadMenuItem(menuItemElement);
-    }
 
     public ModelMenuItem(Element menuItemElement, ModelMenu modelMenu) {
-        super(menuItemElement);
-        loadMenuItem(menuItemElement, modelMenu);
+        this(menuItemElement, modelMenu, null);
     }
 
-    public ModelMenuItem(Element menuItemElement, ModelMenuItem modelMenuItem) {
+    private ModelMenuItem(Element menuItemElement, ModelMenu modelMenu, ModelMenuItem parentMenuItem) {
         super(menuItemElement);
-        parentMenuItem = modelMenuItem;
-        loadMenuItem(menuItemElement, modelMenuItem.getModelMenu());
-    }
-
-    private void loadMenuItem(Element menuItemElement, ModelMenu modelMenu) {
         this.modelMenu = modelMenu;
-        loadMenuItem(menuItemElement);
-    }
-
-    private void loadMenuItem(Element menuItemElement) {
+        this.parentMenuItem = parentMenuItem;
         this.entityName = menuItemElement.getAttribute("entity-name");
-        this.setTitle(menuItemElement.getAttribute("title"));
-        this.setTooltip(menuItemElement.getAttribute("tooltip"));
-        this.setParentPortalPageId(menuItemElement.getAttribute("parent-portal-page-value"));
+        this.title = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("title"));
+        this.tooltip = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("tooltip"));
+        this.parentPortalPageId = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("parent-portal-page-value"));
         this.titleStyle = menuItemElement.getAttribute("title-style");
         this.disabledTitleStyle = menuItemElement.getAttribute("disabled-title-style");
         this.widgetStyle = menuItemElement.getAttribute("widget-style");
         this.tooltipStyle = menuItemElement.getAttribute("tooltip-style");
         this.selectedStyle = menuItemElement.getAttribute("selected-style");
-        this.setHideIfSelected(menuItemElement.getAttribute("hide-if-selected"));
+        String hideIfSelected = menuItemElement.getAttribute("hide-if-selected");
+        if (!hideIfSelected.isEmpty())
+            if (hideIfSelected.equalsIgnoreCase("true"))
+                this.hideIfSelected = Boolean.TRUE;
+            else
+                this.hideIfSelected = Boolean.FALSE;
+        else
+            this.hideIfSelected = null;
         this.disableIfEmpty = menuItemElement.getAttribute("disable-if-empty");
         this.align = menuItemElement.getAttribute("align");
         this.alignStyle = menuItemElement.getAttribute("align-style");
+        Integer position = null;
         String positionStr = menuItemElement.getAttribute("position");
-        try {
-            if (UtilValidate.isNotEmpty(positionStr)) {
+        if (!positionStr.isEmpty()) {
+            try {
                 position = Integer.valueOf(positionStr);
+            } catch (Exception e) {
+                Debug.logError(e, "Could not convert position attribute of the field element to an integer: [" + positionStr
+                        + "], using the default of the menu renderer", module);
+                position = null;
             }
-        } catch (Exception e) {
-            Debug.logError(e, "Could not convert position attribute of the field element to an integer: [" +
-                    positionStr + "], using the default of the menu renderer", module);
         }
-
-        this.setAssociatedContentId(menuItemElement.getAttribute("associated-content-id"));
+        this.position = position;
+        this.associatedContentId = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("associated-content-id"));
         this.cellWidth = menuItemElement.getAttribute("cell-width");
-
-        dataMap.put("name", getName());
-
         Element subMenuElement = UtilXml.firstChildElement(menuItemElement, "sub-menu");
         if (subMenuElement != null) {
             String subMenuLocation = subMenuElement.getAttribute("location");
@@ -169,179 +158,167 @@
                 Debug.logError(e3, errMsg, module);
                 throw new RuntimeException(errMsg);
             }
+        } else {
+            this.subMenu = null;
         }
-
         Element linkElement = UtilXml.firstChildElement(menuItemElement, "link");
         if (linkElement != null) {
-            link = new Link(linkElement, this);
+            this.link = new Link(linkElement, this);
+        } else {
+            this.link = null;
         }
-
         // read in add item defs, add/override one by one using the menuItemList and menuItemMap
         List<? extends Element> itemElements = UtilXml.childElementList(menuItemElement, "menu-item");
-        for (Element itemElement: itemElements) {
-            ModelMenuItem modelMenuItem = new ModelMenuItem(itemElement, this);
-            modelMenuItem = this.addUpdateMenuItem(modelMenuItem);
+        if (!itemElements.isEmpty()) {
+            ArrayList<ModelMenuItem> menuItemList = new ArrayList<ModelMenuItem>();
+            Map<String, ModelMenuItem> menuItemMap = new HashMap<String, ModelMenuItem>();
+            for (Element itemElement : itemElements) {
+                ModelMenuItem modelMenuItem = new ModelMenuItem(itemElement, modelMenu, this);
+                addUpdateMenuItem(modelMenuItem, menuItemList, menuItemMap);
+            }
+            menuItemList.trimToSize();
+            this.menuItemList = Collections.unmodifiableList(menuItemList);
+        } else {
+            this.menuItemList = Collections.emptyList();
         }
         // read condition under the "condition" element
         Element conditionElement = UtilXml.firstChildElement(menuItemElement, "condition");
         if (conditionElement != null) {
             this.condition = new ModelMenuCondition(this, conditionElement);
+        } else {
+            this.condition = null;
         }
         // read all actions under the "actions" element
         Element actionsElement = UtilXml.firstChildElement(conditionElement, "actions");
         if (actionsElement != null) {
             this.actions = ModelWidgetAction.readSubActions(this, actionsElement);
-        }
-
-    }
-
-    public ModelMenuItem addUpdateMenuItem(ModelMenuItem modelMenuItem) {
-
-        // not a conditional item, see if a named item exists in Map
-        ModelMenuItem existingMenuItem = this.menuItemMap.get(modelMenuItem.getName());
-        if (existingMenuItem != null) {
-            // does exist, update the item by doing a merge/override
-            existingMenuItem.mergeOverrideModelMenuItem(modelMenuItem);
-            return existingMenuItem;
         } else {
-            // does not exist, add to List and Map
-            this.menuItemList.add(modelMenuItem);
-            this.menuItemMap.put(modelMenuItem.getName(), modelMenuItem);
-            return modelMenuItem;
+            this.actions = Collections.emptyList();
         }
+        this.overrideName = "";
     }
 
-    public List<ModelMenuItem> getMenuItemList() {
-        return menuItemList;
+    // Portal constructor
+    private ModelMenuItem(GenericValue portalPage, ModelMenuItem parentMenuItem, Locale locale) {
+        super(portalPage.getString("portalPageId"));
+        this.actions = Collections.emptyList();
+        this.align = "";
+        this.alignStyle = "";
+        this.associatedContentId = FlexibleStringExpander.getInstance("");
+        this.cellWidth = "";
+        this.condition = null;
+        this.disabledTitleStyle = "";
+        this.disableIfEmpty = "";
+        this.entityName = "";
+        this.hideIfSelected = null;
+        this.menuItemList = Collections.emptyList();
+        this.overrideName = "";
+        this.parentMenuItem = null;
+        this.parentPortalPageId = FlexibleStringExpander.getInstance(portalPage.getString("parentPortalPageId"));
+        this.position = null;
+        this.selectedStyle = "";
+        this.subMenu = null;
+        this.title = FlexibleStringExpander.getInstance((String) portalPage.get("portalPageName", locale));
+        this.titleStyle = "";
+        this.tooltip = FlexibleStringExpander.getInstance("");
+        this.tooltipStyle = "";
+        this.widgetStyle = "";
+        this.link = new Link(portalPage, parentMenuItem, locale);
+        this.modelMenu = parentMenuItem.modelMenu;
     }
 
-    public void setHideIfSelected(String val) {
-        if (UtilValidate.isNotEmpty(val))
-            if (val.equalsIgnoreCase("true"))
-                hideIfSelected = Boolean.TRUE;
-            else
-                hideIfSelected = Boolean.FALSE;
-        else
-            hideIfSelected = null;
-
-    }
-
-    public void setDisabled(boolean val) {
-         this.disabled = val;
-    }
-
-    public boolean getDisabled() {
-         return this.disabled;
+    // Merge constructor
+    private ModelMenuItem(ModelMenuItem existingMenuItem, ModelMenuItem overrideMenuItem) {
+        super(existingMenuItem.getName());
+        this.modelMenu = existingMenuItem.modelMenu;
+        if (UtilValidate.isNotEmpty(overrideMenuItem.getName())) {
+            this.overrideName = overrideMenuItem.getName();
+        } else {
+            this.overrideName = existingMenuItem.getName();
+        }
+        if (UtilValidate.isNotEmpty(overrideMenuItem.entityName)) {
+            this.entityName = overrideMenuItem.entityName;
+        } else {
+            this.entityName = existingMenuItem.entityName;
+        }
+        if (UtilValidate.isNotEmpty(overrideMenuItem.parentPortalPageId)) {
+            this.parentPortalPageId = overrideMenuItem.parentPortalPageId;
+        } else {
+            this.parentPortalPageId = existingMenuItem.parentPortalPageId;
+        }
+        if (UtilValidate.isNotEmpty(overrideMenuItem.title)) {
+            this.title = overrideMenuItem.title;
+        } else {
+            this.title = existingMenuItem.title;
+        }
+        if (UtilValidate.isNotEmpty(overrideMenuItem.tooltip)) {
+            this.tooltip = overrideMenuItem.tooltip;
+        } else {
+            this.tooltip = existingMenuItem.tooltip;
+        }
+        if (UtilValidate.isNotEmpty(overrideMenuItem.titleStyle)) {
+            this.titleStyle = overrideMenuItem.titleStyle;
+        } else {
+            this.titleStyle = existingMenuItem.titleStyle;
+        }
+        if (UtilValidate.isNotEmpty(overrideMenuItem.selectedStyle)) {
+            this.selectedStyle = overrideMenuItem.selectedStyle;
+        } else {
+            this.selectedStyle = existingMenuItem.selectedStyle;
+        }
+        if (UtilValidate.isNotEmpty(overrideMenuItem.widgetStyle)) {
+            this.widgetStyle = overrideMenuItem.widgetStyle;
+        } else {
+            this.widgetStyle = existingMenuItem.widgetStyle;
+        }
+        if (overrideMenuItem.position != null) {
+            this.position = overrideMenuItem.position;
+        } else {
+            this.position = existingMenuItem.position;
+        }
+        this.actions = existingMenuItem.actions;
+        this.align = existingMenuItem.align;
+        this.alignStyle = existingMenuItem.alignStyle;
+        this.associatedContentId = existingMenuItem.associatedContentId;
+        this.cellWidth = existingMenuItem.cellWidth;
+        this.condition = existingMenuItem.condition;
+        this.disabledTitleStyle = existingMenuItem.disabledTitleStyle;
+        this.disableIfEmpty = existingMenuItem.disableIfEmpty;
+        this.hideIfSelected = existingMenuItem.hideIfSelected;
+        this.menuItemList = existingMenuItem.menuItemList;
+        this.parentMenuItem = existingMenuItem.parentMenuItem;
+        this.subMenu = existingMenuItem.subMenu;
+        this.tooltipStyle = existingMenuItem.tooltipStyle;
+        this.link = existingMenuItem.link;
     }
 
     @Override
-    public String getName() {
-        if (this.overrideName != null) {
-            return this.overrideName;
-        }
-        return super.getName();
+    public void accept(ModelWidgetVisitor visitor) throws Exception {
+        visitor.visit(this);
     }
 
-    public void mergeOverrideModelMenuItem(ModelMenuItem overrideMenuItem) {
-        if (overrideMenuItem == null)
-            return;
-
-        // incorporate updates for values that are not empty in the overrideMenuItem
-        if (UtilValidate.isNotEmpty(overrideMenuItem.getName()))
-            this.overrideName = overrideMenuItem.getName();
-        if (UtilValidate.isNotEmpty(overrideMenuItem.entityName))
-            this.entityName = overrideMenuItem.entityName;
-        if (UtilValidate.isNotEmpty(overrideMenuItem.parentPortalPageId))
-            this.parentPortalPageId = overrideMenuItem.parentPortalPageId;
-        if (UtilValidate.isNotEmpty(overrideMenuItem.title))
-            this.title = overrideMenuItem.title;
-        if (UtilValidate.isNotEmpty(overrideMenuItem.tooltip))
-            this.tooltip = overrideMenuItem.tooltip;
-        if (UtilValidate.isNotEmpty(overrideMenuItem.titleStyle))
-            this.titleStyle = overrideMenuItem.titleStyle;
-        if (UtilValidate.isNotEmpty(overrideMenuItem.selectedStyle))
-            this.selectedStyle = overrideMenuItem.selectedStyle;
-        if (UtilValidate.isNotEmpty(overrideMenuItem.widgetStyle))
-            this.widgetStyle = overrideMenuItem.widgetStyle;
-        if (overrideMenuItem.position != null)
-            this.position = overrideMenuItem.position;
-
-    }
-
-    public boolean shouldBeRendered(Map<String, Object> context) {
-        boolean passed = true;
-        if (this.condition != null) {
-            if (!this.condition.eval(context)) {
-                passed = false;
-            }
+    private void addUpdateMenuItem(ModelMenuItem modelMenuItem, List<ModelMenuItem> menuItemList,
+            Map<String, ModelMenuItem> menuItemMap) {
+        ModelMenuItem existingMenuItem = menuItemMap.get(modelMenuItem.getName());
+        if (existingMenuItem != null) {
+            // does exist, update the item by doing a merge/override
+            ModelMenuItem mergedMenuItem = existingMenuItem.mergeOverrideModelMenuItem(modelMenuItem);
+            int existingItemIndex = menuItemList.indexOf(existingMenuItem);
+            menuItemList.set(existingItemIndex, mergedMenuItem);
+            menuItemMap.put(modelMenuItem.getName(), mergedMenuItem);
+        } else {
+            // does not exist, add to List and Map
+            menuItemList.add(modelMenuItem);
+            menuItemMap.put(modelMenuItem.getName(), modelMenuItem);
         }
-        return passed;
-    }
-    
-    public void renderMenuItemString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer) throws IOException {
-
-        boolean passed = true;
-        if (this.condition != null) {
-            if (!this.condition.eval(context)) {
-                passed = false;
-            }
-        }
-        Locale locale = (Locale) context.get("locale");
-           //Debug.logInfo("in ModelMenu, name:" + this.getName(), module);
-        if (passed) {
-            ModelWidgetAction.runSubActions(this.actions, context);
-            String parentPortalPageId = this.getParentPortalPageId(context);
-            if (UtilValidate.isNotEmpty(parentPortalPageId)) {
-                List<GenericValue> portalPages = PortalPageWorker.getPortalPages(parentPortalPageId, context);
-                if (UtilValidate.isNotEmpty(portalPages)) {
-                    for (GenericValue portalPage : portalPages) {
-                        if (UtilValidate.isNotEmpty(portalPage.getString("portalPageName"))) {
-                            String itemName =  portalPage.getString("portalPageId");
-                            ModelMenuItem localItem = new ModelMenuItem(itemName);
-                            localItem.setTitle((String) portalPage.get("portalPageName", locale));
-                            localItem.link = new Link(this);
-                            List<WidgetWorker.Parameter> linkParams = localItem.link.getParameterList();
-                            linkParams.add(new WidgetWorker.Parameter("portalPageId", portalPage.getString("portalPageId"), false));
-                            linkParams.add(new WidgetWorker.Parameter("parentPortalPageId", parentPortalPageId, false));
-                            if (link != null) {
-                                localItem.link.setTarget(link.targetExdr.getOriginal());
-                                linkParams.addAll(link.parameterList);
-                            } else {
-                                localItem.link.setTarget("showPortalPage");
-                            }
-                            localItem.link.setText((String)portalPage.get("portalPageName", locale));
-                            localItem.modelMenu = this.getModelMenu();
-                            menuStringRenderer.renderMenuItem(writer, context, localItem);
-                        }
-                    }
-                }
-            } else {
-                menuStringRenderer.renderMenuItem(writer, context, this);
-            }
-        }
-    }
-
-
-    public ModelMenu getModelMenu() {
-        return modelMenu;
     }
 
     public List<ModelWidgetAction> getActions() {
         return actions;
     }
 
-    public String getEntityName() {
-        if (UtilValidate.isNotEmpty(this.entityName)) {
-            return this.entityName;
-        } else if (parentMenuItem != null) {
-            return parentMenuItem.getEntityName();
-        } else {
-            return this.modelMenu.getDefaultEntityName();
-        }
-    }
-
     public String getAlign() {
-        if (UtilValidate.isNotEmpty(this.align)) {
+        if (!this.align.isEmpty()) {
             return this.align;
         } else if (parentMenuItem != null) {
             return parentMenuItem.getAlign();
@@ -350,80 +327,8 @@
         }
     }
 
-    public int getPosition() {
-        if (this.position == null) {
-            return 1;
-        } else {
-            return position.intValue();
-        }
-    }
-
-    public String getTitle(Map<String, Object> context) {
-            return title.expandString(context);
-    }
-
-    public String getTitleStyle() {
-        if (UtilValidate.isNotEmpty(this.titleStyle)) {
-            return this.titleStyle;
-        } else if (parentMenuItem != null) {
-            return parentMenuItem.getTitleStyle();
-         } else {
-            return this.modelMenu.getDefaultTitleStyle();
-        }
-    }
-
-    public String getDisabledTitleStyle() {
-        if (UtilValidate.isNotEmpty(this.disabledTitleStyle)) {
-            return this.disabledTitleStyle;
-        } else if (parentMenuItem != null) {
-            return parentMenuItem.getDisabledTitleStyle();
-        } else {
-            return this.modelMenu.getDefaultDisabledTitleStyle();
-        }
-    }
-
-    public void setDisabledTitleStyle(String style) {
-            this.disabledTitleStyle = style;
-    }
-
-    public String getSelectedStyle() {
-        if (UtilValidate.isNotEmpty(this.selectedStyle)) {
-            return this.selectedStyle;
-        } else if (parentMenuItem != null) {
-            return parentMenuItem.getSelectedStyle();
-        } else {
-            return this.modelMenu.getDefaultSelectedStyle();
-        }
-    }
-
-    public String getTooltip(Map<String, Object> context) {
-        if (UtilValidate.isNotEmpty(tooltip)) {
-            return tooltip.expandString(context);
-        } else {
-            return "";
-        }
-    }
-
-    public void setParentPortalPageId(String string) {
-        this.parentPortalPageId = FlexibleStringExpander.getInstance(string);
-    }
-
-    public String getParentPortalPageId(Map<String, Object> context) {
-        return this.parentPortalPageId.expandString(context);
-    }
-
-    public String getWidgetStyle() {
-        if (UtilValidate.isNotEmpty(this.widgetStyle)) {
-            return this.widgetStyle;
-        } else if (parentMenuItem != null) {
-            return parentMenuItem.getWidgetStyle();
-        } else {
-            return this.modelMenu.getDefaultWidgetStyle();
-        }
-    }
-
     public String getAlignStyle() {
-        if (UtilValidate.isNotEmpty(this.alignStyle)) {
+        if (!this.alignStyle.isEmpty()) {
             return this.alignStyle;
         } else if (parentMenuItem != null) {
             return parentMenuItem.getAlignStyle();
@@ -432,72 +337,8 @@
         }
     }
 
-    public String getTooltipStyle() {
-        if (UtilValidate.isNotEmpty(this.tooltipStyle)) {
-            return this.tooltipStyle;
-        } else if (parentMenuItem != null) {
-            return parentMenuItem.getTooltipStyle();
-        } else {
-            return this.modelMenu.getDefaultTooltipStyle();
-        }
-    }
-
-    /**
-     * @param string
-     */
-    public void setEntityName(String string) {
-        entityName = string;
-    }
-
-    /**
-     * @param i
-     */
-    public void setPosition(int i) {
-        position = Integer.valueOf(i);
-    }
-
-
-    /**
-     * @param string
-     */
-    public void setTitle(String string) {
-        this.title = FlexibleStringExpander.getInstance(string);
-    }
-
-    /**
-     * @param string
-     */
-    public void setTitleStyle(String string) {
-        this.titleStyle = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setTooltip(String string) {
-        this.tooltip = FlexibleStringExpander.getInstance(string);
-    }
-
-    /**
-     * @param string
-     */
-    public void setWidgetStyle(String string) {
-        this.widgetStyle = string;
-    }
-
-    /**
-     * @param string
-     */
-    public void setTooltipStyle(String string) {
-        this.tooltipStyle = string;
-    }
-
-
-    /**
-     * @param string
-     */
-    public void setAssociatedContentId(String string) {
-        this.associatedContentId = FlexibleStringExpander.getInstance(string);
+    public FlexibleStringExpander getAssociatedContentId() {
+        return associatedContentId;
     }
 
     public String getAssociatedContentId(Map<String, Object> context) {
@@ -505,33 +346,46 @@
         if (this.associatedContentId != null) {
             retStr = associatedContentId.expandString(context);
         }
-        if (UtilValidate.isEmpty(retStr)) {
+        if (retStr.isEmpty()) {
             retStr = this.modelMenu.getDefaultAssociatedContentId(context);
         }
         return retStr;
     }
 
-
-    /**
-     * @param string
-     */
-    public void setCellWidth(String string) {
-        this.cellWidth = string;
-    }
-
     public String getCellWidth() {
-        if (UtilValidate.isNotEmpty(this.cellWidth)) {
-            return this.cellWidth ;
+        if (!this.cellWidth.isEmpty()) {
+            return this.cellWidth;
         } else {
-            return this.modelMenu.getDefaultCellWidth ();
+            return this.modelMenu.getDefaultCellWidth();
         }
     }
 
-    /**
-     * @param val
-     */
-    public void setHideIfSelected(Boolean val) {
-        this.hideIfSelected = val;
+    public ModelMenuCondition getCondition() {
+        return condition;
+    }
+
+    public String getDisabledTitleStyle() {
+        if (!this.disabledTitleStyle.isEmpty()) {
+            return this.disabledTitleStyle;
+        } else if (parentMenuItem != null) {
+            return parentMenuItem.getDisabledTitleStyle();
+        } else {
+            return this.modelMenu.getDefaultDisabledTitleStyle();
+        }
+    }
+
+    public String getDisableIfEmpty() {
+        return this.disableIfEmpty;
+    }
+
+    public String getEntityName() {
+        if (!this.entityName.isEmpty()) {
+            return this.entityName;
+        } else if (parentMenuItem != null) {
+            return parentMenuItem.getEntityName();
+        } else {
+            return this.modelMenu.getDefaultEntityName();
+        }
     }
 
     public Boolean getHideIfSelected() {
@@ -542,123 +396,389 @@
         }
     }
 
-    public String getDisableIfEmpty() {
-            return this.disableIfEmpty;
-    }
-
-    /**
-     * @param val
-     */
-    public void setHasPermission(Boolean val) {
-        this.hasPermission = val;
-    }
-
-    public Boolean getHasPermission() {
-        return this.hasPermission;
-    }
-
     public Link getLink() {
-       return this.link;
+        return this.link;
+    }
+
+    public List<ModelMenuItem> getMenuItemList() {
+        return menuItemList;
+    }
+
+    public ModelMenu getModelMenu() {
+        return modelMenu;
+    }
+
+    @Override
+    public String getName() {
+        if (!this.overrideName.isEmpty()) {
+            return this.overrideName;
+        }
+        return super.getName();
+    }
+
+    public String getOverrideName() {
+        return overrideName;
+    }
+
+    public ModelMenuItem getParentMenuItem() {
+        return parentMenuItem;
+    }
+
+    public FlexibleStringExpander getParentPortalPageId() {
+        return parentPortalPageId;
+    }
+
+    public String getParentPortalPageId(Map<String, Object> context) {
+        return this.parentPortalPageId.expandString(context);
+    }
+
+    public int getPosition() {
+        if (this.position == null) {
+            return 1;
+        } else {
+            return position.intValue();
+        }
+    }
+
+    public String getSelectedStyle() {
+        if (!this.selectedStyle.isEmpty()) {
+            return this.selectedStyle;
+        } else if (parentMenuItem != null) {
+            return parentMenuItem.getSelectedStyle();
+        } else {
+            return this.modelMenu.getDefaultSelectedStyle();
+        }
+    }
+
+    public ModelMenu getSubMenu() {
+        return subMenu;
+    }
+
+    public FlexibleStringExpander getTitle() {
+        return title;
+    }
+
+    public String getTitle(Map<String, Object> context) {
+        return title.expandString(context);
+    }
+
+    public String getTitleStyle() {
+        if (!this.titleStyle.isEmpty()) {
+            return this.titleStyle;
+        } else if (parentMenuItem != null) {
+            return parentMenuItem.getTitleStyle();
+        } else {
+            return this.modelMenu.getDefaultTitleStyle();
+        }
+    }
+
+    public FlexibleStringExpander getTooltip() {
+        return tooltip;
+    }
+
+    public String getTooltip(Map<String, Object> context) {
+        if (UtilValidate.isNotEmpty(tooltip)) {
+            return tooltip.expandString(context);
+        } else {
+            return "";
+        }
+    }
+
+    public String getTooltipStyle() {
+        if (!this.tooltipStyle.isEmpty()) {
+            return this.tooltipStyle;
+        } else if (parentMenuItem != null) {
+            return parentMenuItem.getTooltipStyle();
+        } else {
+            return this.modelMenu.getDefaultTooltipStyle();
+        }
+    }
+
+    public String getWidgetStyle() {
+        if (!this.widgetStyle.isEmpty()) {
+            return this.widgetStyle;
+        } else if (parentMenuItem != null) {
+            return parentMenuItem.getWidgetStyle();
+        } else {
+            return this.modelMenu.getDefaultWidgetStyle();
+        }
     }
 
     public boolean isSelected(Map<String, Object> context) {
         return getName().equals(modelMenu.getSelectedMenuItemContextFieldName(context));
     }
 
-    public static class Link {
-        protected ModelMenuItem linkMenuItem;
-        protected FlexibleStringExpander textExdr;
-        protected FlexibleStringExpander idExdr;
-        protected FlexibleStringExpander styleExdr;
-        protected FlexibleStringExpander targetExdr;
-        protected FlexibleStringExpander targetWindowExdr;
-        protected FlexibleStringExpander prefixExdr;
-        protected FlexibleStringExpander nameExdr;
-        protected Image image;
-        protected String urlMode = "intra-app";
-        protected boolean fullPath = false;
-        protected boolean secure = false;
-        protected boolean encode = false;
-        protected String linkType;
-        protected WidgetWorker.AutoServiceParameters autoServiceParameters;
-        protected WidgetWorker.AutoEntityParameters autoEntityParameters;
-        protected FlexibleMapAccessor<Map<String, String>> parametersMapAcsr;
-        protected List<WidgetWorker.Parameter> parameterList = new ArrayList<WidgetWorker.Parameter>();
-        protected boolean requestConfirmation = false;
-        protected FlexibleStringExpander confirmationMsgExdr;
+    public ModelMenuItem mergeOverrideModelMenuItem(ModelMenuItem overrideMenuItem) {
+        return new ModelMenuItem(this, overrideMenuItem);
+    }
 
-        public Link(Element linkElement, ModelMenuItem parentMenuItem) {
-            this.linkMenuItem = parentMenuItem;
-            setText(linkElement.getAttribute("text"));
-            setId(linkElement.getAttribute("id"));
-            setStyle(linkElement.getAttribute("style"));
-            setTarget(linkElement.getAttribute("target"));
-            setTargetWindow(linkElement.getAttribute("target-window"));
-            setPrefix(linkElement.getAttribute("prefix"));
-            setUrlMode(linkElement.getAttribute("url-mode"));
-            setFullPath(linkElement.getAttribute("full-path"));
-            setSecure(linkElement.getAttribute("secure"));
-            setEncode(linkElement.getAttribute("encode"));
-            setName(linkElement.getAttribute("name"));
-            Element imageElement = UtilXml.firstChildElement(linkElement, "image");
-            if (imageElement != null) {
-                this.image = new Image(imageElement);
-            }
-
-            this.linkType = linkElement.getAttribute("link-type");
-            this.parametersMapAcsr = FlexibleMapAccessor.getInstance(linkElement.getAttribute("parameters-map"));
-            List<? extends Element> parameterElementList = UtilXml.childElementList(linkElement, "parameter");
-            for (Element parameterElement: parameterElementList) {
-                this.parameterList.add(new WidgetWorker.Parameter(parameterElement));
-            }
-            setRequestConfirmation("true".equals(linkElement.getAttribute("request-confirmation")));
-            setConfirmationMsg(linkElement.getAttribute("confirmation-message"));
-            Element autoServiceParamsElement = UtilXml.firstChildElement(linkElement, "auto-parameters-service");
-            if (autoServiceParamsElement != null) {
-                autoServiceParameters = new WidgetWorker.AutoServiceParameters(autoServiceParamsElement);
-            }
-            Element autoEntityParamsElement = UtilXml.firstChildElement(linkElement, "auto-parameters-entity");
-            if (autoEntityParamsElement != null) {
-                autoEntityParameters = new WidgetWorker.AutoEntityParameters(autoEntityParamsElement);
+    public void renderMenuItemString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer)
+            throws IOException {
+        if (shouldBeRendered(context)) {
+            ModelWidgetAction.runSubActions(actions, context);
+            String parentPortalPageId = getParentPortalPageId(context);
+            if (UtilValidate.isNotEmpty(parentPortalPageId)) {
+                List<GenericValue> portalPages = PortalPageWorker.getPortalPages(parentPortalPageId, context);
+                if (UtilValidate.isNotEmpty(portalPages)) {
+                    Locale locale = (Locale) context.get("locale");
+                    for (GenericValue portalPage : portalPages) {
+                        if (UtilValidate.isNotEmpty(portalPage.getString("portalPageName"))) {
+                            ModelMenuItem localItem = new ModelMenuItem(portalPage, this, locale);
+                            menuStringRenderer.renderMenuItem(writer, context, localItem);
+                        }
+                    }
+                }
+            } else {
+                menuStringRenderer.renderMenuItem(writer, context, this);
             }
         }
+    }
 
-        public Link(ModelMenuItem parentMenuItem) {
-            this.linkMenuItem = parentMenuItem;
-            setText("");
-            setId("");
-            setStyle("");
-            setTarget("");
-            setTargetWindow("");
-            setPrefix("");
-            setUrlMode("");
-            setFullPath("");
-            setSecure("");
-            setEncode("");
-            setName("");
-            setConfirmationMsg("");
+    public boolean shouldBeRendered(Map<String, Object> context) {
+        if (this.condition != null) {
+            return this.condition.eval(context);
+        }
+        return true;
+    }
+
+    public static class Image {
+
+        private final FlexibleStringExpander borderExdr;
+        private final FlexibleStringExpander heightExdr;
+        private final FlexibleStringExpander idExdr;
+        private final FlexibleStringExpander srcExdr;
+        private final FlexibleStringExpander styleExdr;
+        private final String urlMode;
+        private final FlexibleStringExpander widthExdr;
+
+        public Image(Element imageElement) {
+            this.borderExdr = FlexibleStringExpander.getInstance(UtilXml.checkEmpty(imageElement.getAttribute("border"), "0"));
+            this.heightExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("height"));
+            this.idExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("id"));
+            this.srcExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("src"));
+            this.styleExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("style"));
+            this.urlMode = UtilXml.checkEmpty(imageElement.getAttribute("url-mode"), "content");
+            this.widthExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("width"));
         }
 
-        public void renderLinkString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer) throws IOException {
-            menuStringRenderer.renderLink(writer, context, this);
+        public String getBorder(Map<String, Object> context) {
+            return this.borderExdr.expandString(context);
         }
 
-        public String getText(Map<String, Object> context) {
-            String txt = this.textExdr.expandString(context);
-            if (UtilValidate.isEmpty(txt)) txt = linkMenuItem.getTitle(context);
-
-            StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
-            if (simpleEncoder != null) {
-                txt = simpleEncoder.encode(txt);
-            }
-
-            return txt;
+        public String getHeight(Map<String, Object> context) {
+            return this.heightExdr.expandString(context);
         }
 
         public String getId(Map<String, Object> context) {
             return this.idExdr.expandString(context);
         }
 
+        public String getSrc(Map<String, Object> context) {
+            return this.srcExdr.expandString(context);
+        }
+
+        public String getStyle(Map<String, Object> context) {
+            return this.styleExdr.expandString(context);
+        }
+
+        public String getUrlMode() {
+            return this.urlMode;
+        }
+
+        public String getWidth(Map<String, Object> context) {
+            return this.widthExdr.expandString(context);
+        }
+
+        public void renderImageString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer)
+                throws IOException {
+            menuStringRenderer.renderImage(writer, context, this);
+        }
+    }
+
+    public static class Link {
+        private final AutoEntityParameters autoEntityParameters;
+        private final AutoServiceParameters autoServiceParameters;
+        private final FlexibleStringExpander confirmationMsgExdr;
+        private final boolean encode;
+        private final boolean fullPath;
+        private final FlexibleStringExpander idExdr;
+        private final Image image;
+        private final ModelMenuItem linkMenuItem;
+        private final String linkType;
+        private final FlexibleStringExpander nameExdr;
+        private final List<Parameter> parameterList;
+        private final FlexibleMapAccessor<Map<String, String>> parametersMapAcsr;
+        private final FlexibleStringExpander prefixExdr;
+        private final boolean requestConfirmation;
+        private final boolean secure;
+        private final FlexibleStringExpander styleExdr;
+        private final FlexibleStringExpander targetExdr;
+        private final FlexibleStringExpander targetWindowExdr;
+        private final FlexibleStringExpander textExdr;
+        private final String urlMode;
+
+        public Link(Element linkElement, ModelMenuItem parentMenuItem) {
+            Element autoEntityParamsElement = UtilXml.firstChildElement(linkElement, "auto-parameters-entity");
+            if (autoEntityParamsElement != null) {
+                this.autoEntityParameters = new AutoEntityParameters(autoEntityParamsElement);
+            } else {
+                this.autoEntityParameters = null;
+            }
+            Element autoServiceParamsElement = UtilXml.firstChildElement(linkElement, "auto-parameters-service");
+            if (autoServiceParamsElement != null) {
+                this.autoServiceParameters = new AutoServiceParameters(autoServiceParamsElement);
+            } else {
+                this.autoServiceParameters = null;
+            }
+            this.confirmationMsgExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("confirmation-message"));
+            this.encode = "true".equals(linkElement.getAttribute("encode"));
+            this.fullPath = "true".equals(linkElement.getAttribute("full-path"));
+            this.idExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("id"));
+            Element imageElement = UtilXml.firstChildElement(linkElement, "image");
+            if (imageElement != null) {
+                this.image = new Image(imageElement);
+            } else {
+                this.image = null;
+            }
+            this.linkMenuItem = parentMenuItem;
+            this.linkType = linkElement.getAttribute("link-type");
+            this.nameExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("name"));
+            List<? extends Element> parameterElementList = UtilXml.childElementList(linkElement, "parameter");
+            if (!parameterElementList.isEmpty()) {
+                List<Parameter> parameterList = new ArrayList<Parameter>(parameterElementList.size());
+                for (Element parameterElement : parameterElementList) {
+                    parameterList.add(new Parameter(parameterElement));
+                }
+                this.parameterList = Collections.unmodifiableList(parameterList);
+            } else {
+                this.parameterList = Collections.emptyList();
+            }
+            this.parametersMapAcsr = FlexibleMapAccessor.getInstance(linkElement.getAttribute("parameters-map"));
+            this.prefixExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("prefix"));
+            this.requestConfirmation = "true".equals(linkElement.getAttribute("request-confirmation"));
+            this.secure = "true".equals(linkElement.getAttribute("secure"));
+            this.styleExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("style"));
+            this.targetExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target"));
+            this.targetWindowExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target-window"));
+            this.textExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("text"));
+            this.urlMode = UtilXml.checkEmpty(linkElement.getAttribute("url-mode"), "intra-app");
+        }
+
+        public Link(GenericValue portalPage, ModelMenuItem parentMenuItem, Locale locale) {
+            this.autoEntityParameters = null;
+            this.autoServiceParameters = null;
+            this.confirmationMsgExdr = FlexibleStringExpander.getInstance("");
+            this.encode = false;
+            this.fullPath = false;
+            this.idExdr = FlexibleStringExpander.getInstance("");
+            this.image = null;
+            this.linkMenuItem = parentMenuItem;
+            this.linkType = "";
+            this.nameExdr = FlexibleStringExpander.getInstance("");
+            ArrayList<Parameter> parameterList = new ArrayList<Parameter>();
+            if (parentMenuItem.link != null) {
+                parameterList.addAll(parentMenuItem.link.parameterList);
+            }
+            parameterList.add(new Parameter("portalPageId", portalPage.getString("portalPageId"), false));
+            parameterList.add(new Parameter("parentPortalPageId", portalPage.getString("parentPortalPageId"), false));
+            parameterList.trimToSize();
+            this.parameterList = Collections.unmodifiableList(parameterList);
+            this.parametersMapAcsr = FlexibleMapAccessor.getInstance("");
+            this.prefixExdr = FlexibleStringExpander.getInstance("");
+            this.requestConfirmation = false;
+            this.secure = false;
+            this.styleExdr = FlexibleStringExpander.getInstance("");
+            if (parentMenuItem.link != null) {
+                this.targetExdr = FlexibleStringExpander.getInstance("");
+            } else {
+                this.targetExdr = FlexibleStringExpander.getInstance("showPortalPage");
+            }
+            this.targetWindowExdr = FlexibleStringExpander.getInstance("");
+            this.textExdr = FlexibleStringExpander.getInstance((String) portalPage.get("portalPageName", locale));
+            this.urlMode = "intra-app";
+        }
+
+        public String getConfirmation(Map<String, Object> context) {
+            String message = getConfirmationMsg(context);
+            if (UtilValidate.isNotEmpty(message)) {
+                return message;
+            } else if (getRequestConfirmation()) {
+                FlexibleStringExpander defaultMessage = FlexibleStringExpander.getInstance(UtilProperties.getPropertyValue(
+                        "general", "default.confirmation.message", "${uiLabelMap.CommonConfirm}"));
+                return defaultMessage.expandString(context);
+            }
+            return "";
+        }
+
+        public String getConfirmationMsg(Map<String, Object> context) {
+            return this.confirmationMsgExdr.expandString(context);
+        }
+
+        public boolean getEncode() {
+            return this.encode;
+        }
+
+        public boolean getFullPath() {
+            return this.fullPath;
+        }
+
+        public String getId(Map<String, Object> context) {
+            return this.idExdr.expandString(context);
+        }
+
+        public Image getImage() {
+            return this.image;
+        }
+
+        public ModelMenuItem getLinkMenuItem() {
+            return linkMenuItem;
+        }
+
+        public String getLinkType() {
+            return this.linkType;
+        }
+
+        public String getName(Map<String, Object> context) {
+            return this.nameExdr.expandString(context);
+        }
+
+        public List<Parameter> getParameterList() {
+            return this.parameterList;
+        }
+
+        public Map<String, String> getParameterMap(Map<String, Object> context) {
+            Map<String, String> fullParameterMap = new HashMap<String, String>();
+            if (this.parametersMapAcsr != null) {
+                Map<String, String> addlParamMap = this.parametersMapAcsr.get(context);
+                if (addlParamMap != null) {
+                    fullParameterMap.putAll(addlParamMap);
+                }
+            }
+            for (Parameter parameter : this.parameterList) {
+                fullParameterMap.put(parameter.getName(), parameter.getValue(context));
+            }
+            if (autoServiceParameters != null) {
+                fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, null));
+            }
+            if (autoEntityParameters != null) {
+                fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, linkMenuItem.getModelMenu()
+                        .getDefaultEntityName()));
+            }
+            return fullParameterMap;
+        }
+
+        public String getPrefix(Map<String, Object> context) {
+            return this.prefixExdr.expandString(context);
+        }
+
+        public boolean getRequestConfirmation() {
+            return this.requestConfirmation;
+        }
+
+        public boolean getSecure() {
+            return this.secure;
+        }
+
         public String getStyle(Map<String, Object> context) {
             String style = this.styleExdr.expandString(context);
             if (UtilValidate.isEmpty(style)) {
@@ -667,14 +787,11 @@
             return style;
         }
 
-        public String getName(Map<String, Object> context) {
-            return this.nameExdr.expandString(context);
-        }
-
         public String getTarget(Map<String, Object> context) {
-            StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
+            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
             if (simpleEncoder != null) {
-                return this.targetExdr.expandString(StringUtil.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder));
+                return this.targetExdr.expandString(UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context,
+                        simpleEncoder));
             } else {
                 return this.targetExdr.expandString(context);
             }
@@ -684,246 +801,26 @@
             return this.targetWindowExdr.expandString(context);
         }
 
-        public String getUrlMode() {
-            return this.urlMode;
-        }
-
-        public String getPrefix(Map<String, Object> context) {
-            return this.prefixExdr.expandString(context);
-        }
-
-        public boolean getFullPath() {
-            return this.fullPath;
-        }
-
-        public boolean getSecure() {
-            return this.secure;
-        }
-
-        public boolean getEncode() {
-            return this.encode;
-        }
-
-        public Image getImage() {
-            return this.image;
-        }
-
-        public String getLinkType() {
-            return this.linkType;
-        }
-
-        public List<WidgetWorker.Parameter> getParameterList() {
-            return this.parameterList;
-        }
-        public Map<String, String> getParameterMap(Map<String, Object> context) {
-            Map<String, String> fullParameterMap = new HashMap<String, String>();
-
-            if (this.parametersMapAcsr != null) {
-                Map<String, String> addlParamMap = this.parametersMapAcsr.get(context);
-                if (addlParamMap != null) {
-                    fullParameterMap.putAll(addlParamMap);
-                }
+        public String getText(Map<String, Object> context) {
+            String txt = this.textExdr.expandString(context);
+            if (UtilValidate.isEmpty(txt)) {
+                txt = linkMenuItem.getTitle(context);
             }
-
-            for (WidgetWorker.Parameter parameter: this.parameterList) {
-                fullParameterMap.put(parameter.getName(), parameter.getValue(context));
+            // FIXME: Encoding should be done by the renderer, not by the model.
+            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+            if (simpleEncoder != null) {
+                txt = simpleEncoder.encode(txt);
             }
-            if (autoServiceParameters != null) {
-                fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, null));
-            }
-            if (autoEntityParameters != null) {
-                fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, linkMenuItem.getModelMenu().getDefaultEntityName()));
-            }
-            return fullParameterMap;
-        }
-
-        public String getConfirmation(Map<String, Object> context) {
-            String message = getConfirmationMsg(context);
-            if (UtilValidate.isNotEmpty(message)) {
-                return message;
-            }
-            else if (getRequestConfirmation()) {
-                String defaultMessage = UtilProperties.getPropertyValue("general", "default.confirmation.message", "${uiLabelMap.CommonConfirm}");
-                setConfirmationMsg(defaultMessage);
-                return getConfirmationMsg(context);
-            }
-            return "";
-        }
-
-        public boolean getRequestConfirmation() {
-            return this.requestConfirmation;
-        }
-
-        public String getConfirmationMsg(Map<String, Object> context) {
-            return this.confirmationMsgExdr.expandString(context);
-        }
-
-        public void setText(String val) {
-            String textAttr = UtilFormatOut.checkNull(val);
-            this.textExdr = FlexibleStringExpander.getInstance(textAttr);
-        }
-
-        public void setId(String val) {
-            this.idExdr = FlexibleStringExpander.getInstance(val);
-        }
-
-        public void setStyle(String val) {
-            this.styleExdr = FlexibleStringExpander.getInstance(val);
-        }
-
-        public void setTarget(String val) {
-            this.targetExdr = FlexibleStringExpander.getInstance(val);
-        }
-
-        public void setTargetWindow(String val) {
-            this.targetWindowExdr = FlexibleStringExpander.getInstance(val);
-        }
-
-        public void setPrefix(String val) {
-            this.prefixExdr = FlexibleStringExpander.getInstance(val);
-        }
-
-        public void setUrlMode(String val) {
-            if (UtilValidate.isNotEmpty(val))
-                this.urlMode = val;
-        }
-
-        public void setName(String val) {
-            this.nameExdr = FlexibleStringExpander.getInstance(val);
-        }
-
-        public void setFullPath(String val) {
-            String sFullPath = val;
-            if (sFullPath != null && sFullPath.equalsIgnoreCase("true"))
-                this.fullPath = true;
-            else
-                this.fullPath = false;
-        }
-
-        public void setSecure(String val) {
-            String sSecure = val;
-            if (sSecure != null && sSecure.equalsIgnoreCase("true"))
-                this.secure = true;
-            else
-                this.secure = false;
-        }
-
-        public void setEncode(String val) {
-            String sEncode = val;
-            if (sEncode != null && sEncode.equalsIgnoreCase("true"))
-                this.encode = true;
-            else
-                this.encode = false;
-        }
-
-        public void setImage(Image img) {
-            this.image = img;
-        }
-
-        public void setRequestConfirmation(boolean val) {
-            this.requestConfirmation = val;
-        }
-
-        public void setConfirmationMsg(String val) {
-            this.confirmationMsgExdr = FlexibleStringExpander.getInstance(val);
-        }
-
-        public ModelMenuItem getLinkMenuItem() {
-            return linkMenuItem;
-        }
-
-    }
-
-    public static class Image {
-
-        protected FlexibleStringExpander srcExdr;
-        protected FlexibleStringExpander idExdr;
-        protected FlexibleStringExpander styleExdr;
-        protected FlexibleStringExpander widthExdr;
-        protected FlexibleStringExpander heightExdr;
-        protected FlexibleStringExpander borderExdr;
-        protected String urlMode;
-
-        public Image(Element imageElement) {
-
-            setSrc(imageElement.getAttribute("src"));
-            setId(imageElement.getAttribute("id"));
-            setStyle(imageElement.getAttribute("style"));
-            setWidth(imageElement.getAttribute("width"));
-            setHeight(imageElement.getAttribute("height"));
-            setBorder(UtilFormatOut.checkEmpty(imageElement.getAttribute("border"), "0"));
-            setUrlMode(UtilFormatOut.checkEmpty(imageElement.getAttribute("url-mode"), "content"));
-
-        }
-
-        public void renderImageString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer) throws IOException {
-            menuStringRenderer.renderImage(writer, context, this);
-        }
-
-        public String getSrc(Map<String, Object> context) {
-            return this.srcExdr.expandString(context);
-        }
-
-        public String getId(Map<String, Object> context) {
-            return this.idExdr.expandString(context);
-        }
-
-        public String getStyle(Map<String, Object> context) {
-            return this.styleExdr.expandString(context);
-        }
-
-        public String getWidth(Map<String, Object> context) {
-            return this.widthExdr.expandString(context);
-        }
-
-        public String getHeight(Map<String, Object> context) {
-            return this.heightExdr.expandString(context);
-        }
-
-        public String getBorder(Map<String, Object> context) {
-            return this.borderExdr.expandString(context);
+            return txt;
         }
 
         public String getUrlMode() {
             return this.urlMode;
         }
 
-        public void setSrc(String val) {
-            String textAttr = UtilFormatOut.checkNull(val);
-            this.srcExdr = FlexibleStringExpander.getInstance(textAttr);
+        public void renderLinkString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer)
+                throws IOException {
+            menuStringRenderer.renderLink(writer, context, this);
         }
-
-        public void setId(String val) {
-            this.idExdr = FlexibleStringExpander.getInstance(val);
-        }
-
-        public void setStyle(String val) {
-            this.styleExdr = FlexibleStringExpander.getInstance(val);
-        }
-
-        public void setWidth(String val) {
-            this.widthExdr = FlexibleStringExpander.getInstance(val);
-        }
-
-        public void setHeight(String val) {
-            this.heightExdr = FlexibleStringExpander.getInstance(val);
-        }
-
-        public void setBorder(String val) {
-            this.borderExdr = FlexibleStringExpander.getInstance(val);
-        }
-
-        public void setUrlMode(String val) {
-            if (UtilValidate.isEmpty(val))
-                this.urlMode = "content";
-            else
-                this.urlMode = val;
-        }
-
-    }
-
-    @Override
-    public void accept(ModelWidgetVisitor visitor) throws Exception {
-        visitor.visit(this);
     }
 }
diff --git a/framework/widget/src/org/ofbiz/widget/screen/HtmlWidget.java b/framework/widget/src/org/ofbiz/widget/screen/HtmlWidget.java
index 7c8fd93..702096a 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/HtmlWidget.java
+++ b/framework/widget/src/org/ofbiz/widget/screen/HtmlWidget.java
@@ -30,6 +30,7 @@
 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;
@@ -88,7 +89,7 @@
         }
         @Override
         public String getAsString() {
-            return StringUtil.htmlEncoder.encode(super.getAsString());
+            return UtilCodec.getEncoder("html").encode(super.getAsString());
         }
     }
 
@@ -100,7 +101,7 @@
 
         @Override
         public String getAsString() {
-            return StringUtil.htmlEncoder.encode(super.getAsString());
+            return UtilCodec.getEncoder("html").encode(super.getAsString());
         }
 
     }
diff --git a/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java b/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java
index 60aab28..d6f1290 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java
+++ b/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java
@@ -20,6 +20,8 @@
 
 import java.io.IOException;
 import java.io.Writer;
+import java.util.List;
+import java.util.Map;
 
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
@@ -28,11 +30,16 @@
 
 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.UtilProperties;
 import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.collections.MapStack;
 import org.ofbiz.entity.Delegator;
 import org.ofbiz.entity.util.EntityUtilProperties;
+import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.service.ModelService;
+import org.ofbiz.service.ServiceUtil;
 import org.ofbiz.webapp.view.AbstractViewHandler;
 import org.ofbiz.webapp.view.ViewHandlerException;
 import org.ofbiz.widget.form.FormStringRenderer;
@@ -41,7 +48,6 @@
 import org.ofbiz.widget.menu.MenuStringRenderer;
 import org.ofbiz.widget.tree.MacroTreeRenderer;
 import org.ofbiz.widget.tree.TreeStringRenderer;
-import org.python.modules.re;
 import org.xml.sax.SAXException;
 
 import freemarker.template.TemplateException;
@@ -57,6 +63,65 @@
         this.servletContext = context;
     }
 
+    private ScreenStringRenderer loadRenderers(HttpServletRequest request, HttpServletResponse response,
+            Map<String, Object> context, Writer writer) throws GeneralException, TemplateException, IOException {
+        String screenMacroLibraryPath = UtilProperties.getPropertyValue("widget", getName() + ".screenrenderer");
+        String formMacroLibraryPath = UtilProperties.getPropertyValue("widget", getName() + ".formrenderer");
+        String treeMacroLibraryPath = UtilProperties.getPropertyValue("widget", getName() + ".treerenderer");
+        String menuMacroLibraryPath = UtilProperties.getPropertyValue("widget", getName() + ".menurenderer");
+        Map<String, Object> userPreferences = UtilGenerics.cast(context.get("userPreferences"));
+        if (userPreferences != null) {
+            String visualThemeId = (String) userPreferences.get("VISUAL_THEME");
+            if (visualThemeId != null) {
+                LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
+                Map<String, Object> serviceCtx = dispatcher.getDispatchContext().makeValidContext("getVisualThemeResources",
+                        ModelService.IN_PARAM, context);
+                serviceCtx.put("visualThemeId", visualThemeId);
+                Map<String, Object> serviceResult = dispatcher.runSync("getVisualThemeResources", serviceCtx);
+                if (ServiceUtil.isSuccess(serviceResult)) {
+                    Map<String, List<String>> themeResources = UtilGenerics.cast(serviceResult.get("themeResources"));
+                    List<String> resourceList = UtilGenerics.cast(themeResources.get("VT_SCRN_MACRO_LIB"));
+                    if (resourceList != null && !resourceList.isEmpty()) {
+                        String macroLibraryPath = resourceList.get(0);
+                        if (macroLibraryPath != null) {
+                            screenMacroLibraryPath = macroLibraryPath;
+                        }
+                    }
+                    resourceList = UtilGenerics.cast(themeResources.get("VT_FORM_MACRO_LIB"));
+                    if (resourceList != null && !resourceList.isEmpty()) {
+                        String macroLibraryPath = resourceList.get(0);
+                        if (macroLibraryPath != null) {
+                            formMacroLibraryPath = macroLibraryPath;
+                        }
+                    }
+                    resourceList = UtilGenerics.cast(themeResources.get("VT_TREE_MACRO_LIB"));
+                    if (resourceList != null && !resourceList.isEmpty()) {
+                        String macroLibraryPath = resourceList.get(0);
+                        if (macroLibraryPath != null) {
+                            treeMacroLibraryPath = macroLibraryPath;
+                        }
+                    }
+                    resourceList = UtilGenerics.cast(themeResources.get("VT_MENU_MACRO_LIB"));
+                    if (resourceList != null && !resourceList.isEmpty()) {
+                        String macroLibraryPath = resourceList.get(0);
+                        if (macroLibraryPath != null) {
+                            menuMacroLibraryPath = macroLibraryPath;
+                        }
+                    }
+                }
+            }
+        }
+        ScreenStringRenderer screenStringRenderer = new MacroScreenRenderer(UtilProperties.getPropertyValue("widget", getName()
+                + ".name"), screenMacroLibraryPath);
+        FormStringRenderer formStringRenderer = new MacroFormRenderer(formMacroLibraryPath, request, response);
+        context.put("formStringRenderer", formStringRenderer);
+        TreeStringRenderer treeStringRenderer = new MacroTreeRenderer(treeMacroLibraryPath, writer);
+        context.put("treeStringRenderer", treeStringRenderer);
+        MenuStringRenderer menuStringRenderer = new MacroMenuRenderer(menuMacroLibraryPath, request, response);
+        context.put("menuStringRenderer", menuStringRenderer);
+        return screenStringRenderer;
+    }
+
     public void render(String name, String page, String info, String contentType, String encoding, HttpServletRequest request, HttpServletResponse response) throws ViewHandlerException {
         try {
             Writer writer = response.getWriter();
@@ -77,28 +142,15 @@
                 // to speed up output.
                 writer = new StandardCompress().getWriter(writer, null);
             }
-            ScreenStringRenderer screenStringRenderer = new MacroScreenRenderer(EntityUtilProperties.getPropertyValue("widget", getName() + ".name", delegator), EntityUtilProperties.getPropertyValue("widget", getName() + ".screenrenderer", delegator));
-            ScreenRenderer screens = new ScreenRenderer(writer, null, screenStringRenderer);
-            screens.populateContextForRequest(request, response, servletContext);
-            String macroLibraryPath = EntityUtilProperties.getPropertyValue("widget", getName() + ".formrenderer", delegator);
-            if (UtilValidate.isNotEmpty(macroLibraryPath)) {
-                FormStringRenderer formStringRenderer = new MacroFormRenderer(macroLibraryPath, request, response);
-                screens.getContext().put("formStringRenderer", formStringRenderer);
-            }
-            macroLibraryPath = EntityUtilProperties.getPropertyValue("widget", getName() + ".treerenderer", delegator);
-            if (UtilValidate.isNotEmpty(macroLibraryPath)) {
-                TreeStringRenderer treeStringRenderer = new MacroTreeRenderer(macroLibraryPath, writer);
-                screens.getContext().put("treeStringRenderer", treeStringRenderer);
-            }
-            macroLibraryPath = EntityUtilProperties.getPropertyValue("widget", getName() + ".menurenderer", delegator);
-            if (UtilValidate.isNotEmpty(macroLibraryPath)) {
-                MenuStringRenderer menuStringRenderer = new MacroMenuRenderer(macroLibraryPath, request, response);
-                screens.getContext().put("menuStringRenderer", menuStringRenderer);
-            }
-            screens.getContext().put("simpleEncoder", StringUtil.getEncoder(EntityUtilProperties.getPropertyValue("widget", getName() + ".encoder", delegator)));
-            screenStringRenderer.renderScreenBegin(writer, screens.getContext());
+            MapStack<String> context = MapStack.create();
+            ScreenRenderer.populateContextForRequest(context, null, request, response, servletContext);
+            ScreenStringRenderer screenStringRenderer = loadRenderers(request, response, context, writer);
+            ScreenRenderer screens = new ScreenRenderer(writer, context, screenStringRenderer);
+            context.put("screens", screens);
+            context.put("simpleEncoder", UtilCodec.getEncoder(UtilProperties.getPropertyValue("widget", getName() + ".encoder")));
+            screenStringRenderer.renderScreenBegin(writer, context);
             screens.render(page);
-            screenStringRenderer.renderScreenEnd(writer, screens.getContext());
+            screenStringRenderer.renderScreenEnd(writer, context);
             writer.flush();
         } catch (TemplateException e) {
             Debug.logError(e, "Error initializing screen renderer", module);
diff --git a/framework/widget/src/org/ofbiz/widget/screen/ModelScreenAction.java b/framework/widget/src/org/ofbiz/widget/screen/ModelScreenAction.java
deleted file mode 100644
index 4048eb2..0000000
--- a/framework/widget/src/org/ofbiz/widget/screen/ModelScreenAction.java
+++ /dev/null
@@ -1,668 +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.screen;
-
-import java.io.Serializable;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-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;
-
-
-/**
- * Widget Library - Screen model class
- */
-@SuppressWarnings("serial")
-@Deprecated
-public abstract class ModelScreenAction implements Serializable {
-    public static final String module = ModelScreenAction.class.getName();
-
-    protected ModelScreen modelScreen;
-
-    public ModelScreenAction(ModelScreen modelScreen, Element actionElement) {
-        this.modelScreen = modelScreen;
-        if (Debug.verboseOn()) Debug.logVerbose("Reading Screen action with name: " + actionElement.getNodeName(), module);
-    }
-
-    @Deprecated
-    public abstract void runAction(Map<String, Object> context) throws GeneralException;
-
-    @Deprecated
-    public static List<ModelScreenAction> readSubActions(ModelScreen modelScreen, Element parentElement) {
-        List<? extends Element> actionElementList = UtilXml.childElementList(parentElement);
-        List<ModelScreenAction> actions = new ArrayList<ModelScreenAction>(actionElementList.size());
-        for (Element actionElement: actionElementList) {
-            if ("set".equals(actionElement.getNodeName())) {
-                actions.add(new SetField(modelScreen, actionElement));
-            } else if ("property-map".equals(actionElement.getNodeName())) {
-                actions.add(new PropertyMap(modelScreen, actionElement));
-            } else if ("property-to-field".equals(actionElement.getNodeName())) {
-                actions.add(new PropertyToField(modelScreen, actionElement));
-            } else if ("script".equals(actionElement.getNodeName())) {
-                actions.add(new Script(modelScreen, actionElement));
-            } else if ("service".equals(actionElement.getNodeName())) {
-                actions.add(new Service(modelScreen, actionElement));
-            } else if ("entity-one".equals(actionElement.getNodeName())) {
-                actions.add(new EntityOne(modelScreen, actionElement));
-            } else if ("entity-and".equals(actionElement.getNodeName())) {
-                actions.add(new EntityAnd(modelScreen, actionElement));
-            } else if ("entity-condition".equals(actionElement.getNodeName())) {
-                actions.add(new EntityCondition(modelScreen, actionElement));
-            } else if ("get-related-one".equals(actionElement.getNodeName())) {
-                actions.add(new GetRelatedOne(modelScreen, actionElement));
-            } else if ("get-related".equals(actionElement.getNodeName())) {
-                actions.add(new GetRelated(modelScreen, actionElement));
-            } else {
-                throw new IllegalArgumentException("Action element not supported with name: " + actionElement.getNodeName());
-            }
-        }
-
-        return actions;
-    }
-
-    @Deprecated
-    public static void runSubActions(List<ModelScreenAction> actions, Map<String, Object> context) throws GeneralException {
-        if (actions == null) return;
-
-        for (ModelScreenAction action: actions) {
-            if (Debug.verboseOn()) Debug.logVerbose("Running screen action " + action.getClass().getName(), module);
-            action.runAction(context);
-        }
-    }
-
-    @Deprecated
-    public static class SetField extends ModelScreenAction {
-        protected FlexibleMapAccessor<Object> field;
-        protected FlexibleMapAccessor<Object> fromField;
-        protected FlexibleStringExpander valueExdr;
-        protected FlexibleStringExpander defaultExdr;
-        protected FlexibleStringExpander globalExdr;
-        protected String type;
-        protected String toScope;
-        protected String fromScope;
-
-        public SetField(ModelScreen modelScreen, Element setElement) {
-            super (modelScreen, 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 screen widget");
-            }
-        }
-
-        @SuppressWarnings("rawtypes")
-        @Override
-        public void runAction(Map<String, Object> context) {
-            String globalStr = this.globalExdr.expandString(context);
-            // default to false
-            boolean global = "true".equals(globalStr);
-
-            Object newValue = null;
-            if (this.fromScope != null && this.fromScope.equals("user")) {
-                if (!this.fromField.isEmpty()) {
-                    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("In screen 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("In screen setting field [" + this.field.getOriginalName() + "] to value: " + newValue, module);
-                    this.field.put(context, newValue);
-                }
-            }
-
-            if (global) {
-                Map<String, Object> globalCtx = UtilGenerics.checkMap(context.get("globalContext"));
-                if (globalCtx != null) {
-                    this.field.put(globalCtx, newValue);
-                } 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 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;
-        }
-    }
-
-    @Deprecated
-    public static class PropertyMap extends ModelScreenAction {
-        protected FlexibleStringExpander resourceExdr;
-        protected FlexibleMapAccessor<ResourceBundleMapWrapper> mapNameAcsr;
-        protected FlexibleStringExpander globalExdr;
-
-        public PropertyMap(ModelScreen modelScreen, Element setElement) {
-            super (modelScreen, 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 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);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    @Deprecated
-    public static class PropertyToField extends ModelScreenAction {
-
-        protected FlexibleStringExpander resourceExdr;
-        protected FlexibleStringExpander propertyExdr;
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-        protected FlexibleStringExpander defaultExdr;
-        protected boolean noLocale;
-        protected FlexibleMapAccessor<List<? extends Object>> argListAcsr;
-        protected FlexibleStringExpander globalExdr;
-
-        public PropertyToField(ModelScreen modelScreen, Element setElement) {
-            super (modelScreen, 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 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);
-        }
-    }
-
-    @Deprecated
-    public static class Script extends ModelScreenAction {
-        protected String location;
-        protected String method;
-
-        public Script(ModelScreen modelScreen, Element scriptElement) {
-            super (modelScreen, scriptElement);
-            String scriptLocation = scriptElement.getAttribute("location");
-            this.location = WidgetWorker.getScriptLocation(scriptLocation);
-            this.method = WidgetWorker.getScriptMethodName(scriptLocation);
-        }
-
-        @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 = this.modelScreen.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);
-            }
-        }
-    }
-
-    @Deprecated
-    public static class Service extends ModelScreenAction {
-        protected FlexibleStringExpander serviceNameExdr;
-        protected FlexibleMapAccessor<Map<String, Object>> resultMapNameAcsr;
-        protected FlexibleStringExpander autoFieldMapExdr;
-        protected Map<FlexibleMapAccessor<Object>, Object> fieldMap;
-
-        public Service(ModelScreen modelScreen, Element serviceElement) {
-            super (modelScreen, serviceElement);
-            this.serviceNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
-            this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
-            if (this.resultMapNameAcsr.isEmpty()) this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map-name"));
-            this.autoFieldMapExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
-            this.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement);
-        }
-
-        @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 = this.modelScreen.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 = this.modelScreen.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 = this.modelScreen.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);
-            }
-        }
-    }
-
-    @Deprecated
-    public static class EntityOne extends ModelScreenAction {
-        protected PrimaryKeyFinder finder;
-
-        public EntityOne(ModelScreen modelScreen, Element entityOneElement) {
-            super (modelScreen, entityOneElement);
-            finder = new PrimaryKeyFinder(entityOneElement);
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            try {
-                finder.runFind(context, this.modelScreen.getDelegator(context));
-            } catch (GeneralException e) {
-                String errMsg = "Error doing entity query by condition: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-        }
-    }
-
-    @Deprecated
-    public static class EntityAnd extends ModelScreenAction {
-        protected ByAndFinder finder;
-
-        public EntityAnd(ModelScreen modelScreen, Element entityAndElement) {
-            super (modelScreen, entityAndElement);
-            finder = new ByAndFinder(entityAndElement);
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            try {
-                finder.runFind(context, this.modelScreen.getDelegator(context));
-            } catch (GeneralException e) {
-                String errMsg = "Error doing entity query by condition: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-        }
-    }
-
-    @Deprecated
-    public static class EntityCondition extends ModelScreenAction {
-        ByConditionFinder finder;
-
-        public EntityCondition(ModelScreen modelScreen, Element entityConditionElement) {
-            super (modelScreen, entityConditionElement);
-            finder = new ByConditionFinder(entityConditionElement);
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            try {
-                finder.runFind(context, this.modelScreen.getDelegator(context));
-            } catch (GeneralException e) {
-                String errMsg = "Error doing entity query by condition: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-        }
-    }
-
-    @Deprecated
-    public static class GetRelatedOne extends ModelScreenAction {
-        protected FlexibleMapAccessor<Object> valueNameAcsr;
-        protected FlexibleMapAccessor<Object> toValueNameAcsr;
-        protected String relationName;
-        protected boolean useCache;
-
-        public GetRelatedOne(ModelScreen modelScreen, Element getRelatedOneElement) {
-            super (modelScreen, getRelatedOneElement);
-            this.valueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-field"));
-            if (this.valueNameAcsr.isEmpty()) this.valueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-name"));
-            this.toValueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-field"));
-            if (this.toValueNameAcsr.isEmpty()) this.toValueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-name"));
-            this.relationName = getRelatedOneElement.getAttribute("relation-name");
-            this.useCache = "true".equals(getRelatedOneElement.getAttribute("use-cache"));
-        }
-
-        @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);
-            }
-        }
-
-    }
-
-    @Deprecated
-    public static class GetRelated extends ModelScreenAction {
-        protected FlexibleMapAccessor<Object> valueNameAcsr;
-        protected FlexibleMapAccessor<List<GenericValue>> listNameAcsr;
-        protected FlexibleMapAccessor<Map<String, Object>> mapAcsr;
-        protected FlexibleMapAccessor<List<String>> orderByListAcsr;
-        protected String relationName;
-        protected boolean useCache;
-
-        public GetRelated(ModelScreen modelScreen, Element getRelatedElement) {
-            super (modelScreen, getRelatedElement);
-            this.valueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-field"));
-            if (this.valueNameAcsr.isEmpty()) this.valueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-name"));
-            this.listNameAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list"));
-            if (this.listNameAcsr.isEmpty()) this.listNameAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list-name"));
-            this.relationName = getRelatedElement.getAttribute("relation-name");
-            this.mapAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map"));
-            if (this.mapAcsr.isEmpty()) this.mapAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map-name"));
-            this.orderByListAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list"));
-            if (this.orderByListAcsr.isEmpty()) this.orderByListAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list-name"));
-            this.useCache = "true".equals(getRelatedElement.getAttribute("use-cache"));
-        }
-
-        @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);
-            }
-        }
-    }
-
-}
diff --git a/framework/widget/src/org/ofbiz/widget/screen/ModelScreenCondition.java b/framework/widget/src/org/ofbiz/widget/screen/ModelScreenCondition.java
index 8265712..f4c6c33 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/ModelScreenCondition.java
+++ b/framework/widget/src/org/ofbiz/widget/screen/ModelScreenCondition.java
@@ -18,557 +18,70 @@
  *******************************************************************************/
 package org.ofbiz.widget.screen;
 
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
 import java.util.Map;
-import java.util.TimeZone;
 
-import org.apache.oro.text.regex.MalformedPatternException;
-import org.apache.oro.text.regex.Pattern;
-import org.apache.oro.text.regex.PatternMatcher;
-import org.apache.oro.text.regex.Perl5Matcher;
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.ObjectType;
-import org.ofbiz.base.util.PatternFactory;
 import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.collections.FlexibleMapAccessor;
 import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.entityext.permission.EntityPermissionChecker;
-import org.ofbiz.minilang.operation.BaseCompare;
-import org.ofbiz.security.Security;
-import org.ofbiz.service.DispatchContext;
-import org.ofbiz.service.GenericServiceException;
-import org.ofbiz.service.LocalDispatcher;
-import org.ofbiz.service.ModelService;
-import org.ofbiz.service.ServiceUtil;
+import org.ofbiz.widget.ModelWidget;
+import org.ofbiz.widget.ModelWidgetCondition;
 import org.w3c.dom.Element;
 
 /**
- * Widget Library - Screen model condition class
+ * Models the &lt;condition&gt; element.
+ * 
+ * @see <code>widget-screen.xsd</code>
  */
 @SuppressWarnings("serial")
-public class ModelScreenCondition implements Serializable {
-    public static final String module = ModelScreenCondition.class.getName();
+public class ModelScreenCondition extends ModelWidgetCondition {
 
-    protected ModelScreen modelScreen;
-    protected ScreenCondition rootCondition;
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     DEVELOPERS PLEASE READ
+     * ----------------------------------------------------------------------- *
+     * 
+     * This model is intended to be a read-only data structure that represents
+     * an XML element. Outside of object construction, the class should not
+     * have any behaviors.
+     * 
+     * Instances of this class will be shared by multiple threads - therefore
+     * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME!
+     * 
+     */
+
+    public static final String module = ModelScreenCondition.class.getName();
+    public static final ConditionFactory SCREEN_CONDITION_FACTORY = new ScreenConditionFactory();
 
     public ModelScreenCondition(ModelScreen modelScreen, Element conditionElement) {
-        this.modelScreen = modelScreen;
-        Element firstChildElement = UtilXml.firstChildElement(conditionElement);
-        this.rootCondition = readCondition(modelScreen, firstChildElement);
+        super(SCREEN_CONDITION_FACTORY, modelScreen, conditionElement);
     }
 
-    public boolean eval(Map<String, Object> context) {
-        if (rootCondition == null) {
-            return true;
-        }
-        return rootCondition.eval(context);
-    }
+    public static class IfEmptySection extends ModelWidgetCondition implements Condition {
+        private final FlexibleStringExpander sectionExdr;
 
-    public static abstract class ScreenCondition implements Serializable {
-        protected ModelScreen modelScreen;
-
-        public ScreenCondition(ModelScreen modelScreen, Element conditionElement) {
-            this.modelScreen = modelScreen;
-        }
-
-        public abstract boolean eval(Map<String, Object> context);
-    }
-
-    public static List<ScreenCondition> readSubConditions(ModelScreen modelScreen, Element conditionElement) {
-        List<? extends Element> subElementList = UtilXml.childElementList(conditionElement);
-        List<ScreenCondition> condList = new ArrayList<ScreenCondition>(subElementList.size());
-        for (Element subElement: subElementList) {
-            condList.add(readCondition(modelScreen, subElement));
-        }
-        return condList;
-    }
-
-    public static ScreenCondition readCondition(ModelScreen modelScreen, Element conditionElement) {
-        if (conditionElement == null) {
-            return null;
-        }
-        if ("and".equals(conditionElement.getNodeName())) {
-            return new And(modelScreen, conditionElement);
-        } else if ("xor".equals(conditionElement.getNodeName())) {
-            return new Xor(modelScreen, conditionElement);
-        } else if ("or".equals(conditionElement.getNodeName())) {
-            return new Or(modelScreen, conditionElement);
-        } else if ("not".equals(conditionElement.getNodeName())) {
-            return new Not(modelScreen, conditionElement);
-        } else if ("if-service-permission".equals(conditionElement.getNodeName())) {
-            return new IfServicePermission(modelScreen, conditionElement);
-        } else if ("if-has-permission".equals(conditionElement.getNodeName())) {
-            return new IfHasPermission(modelScreen, conditionElement);
-        } else if ("if-validate-method".equals(conditionElement.getNodeName())) {
-            return new IfValidateMethod(modelScreen, conditionElement);
-        } else if ("if-compare".equals(conditionElement.getNodeName())) {
-            return new IfCompare(modelScreen, conditionElement);
-        } else if ("if-compare-field".equals(conditionElement.getNodeName())) {
-            return new IfCompareField(modelScreen, conditionElement);
-        } else if ("if-regexp".equals(conditionElement.getNodeName())) {
-            return new IfRegexp(modelScreen, conditionElement);
-        } else if ("if-empty".equals(conditionElement.getNodeName())) {
-            return new IfEmpty(modelScreen, conditionElement);
-        } else if ("if-entity-permission".equals(conditionElement.getNodeName())) {
-            return new IfEntityPermission(modelScreen, conditionElement);
-        } else if ("if-empty-section".equals(conditionElement.getNodeName())) {
-            return new IfEmptySection(modelScreen, conditionElement);
-        } else {
-            throw new IllegalArgumentException("Condition element not supported with name: " + conditionElement.getNodeName());
-        }
-    }
-
-    public static class And extends ScreenCondition {
-        protected List<ScreenCondition> subConditions;
-
-        public And(ModelScreen modelScreen, Element condElement) {
-            super (modelScreen, condElement);
-            this.subConditions = readSubConditions(modelScreen, condElement);
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            // return false for the first one in the list that is false, basic and algo
-            for (ScreenCondition subCondition: this.subConditions) {
-                if (!subCondition.eval(context)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-
-    public static class Xor extends ScreenCondition {
-        protected List<ScreenCondition> subConditions;
-
-        public Xor(ModelScreen modelScreen, Element condElement) {
-            super (modelScreen, condElement);
-            this.subConditions = readSubConditions(modelScreen, condElement);
-        }
-
-        @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 (ScreenCondition subCondition: this.subConditions) {
-                if (subCondition.eval(context)) {
-                    if (foundOneTrue) {
-                        // now found two true, so return false
-                        return false;
-                    } else {
-                        foundOneTrue = true;
-                    }
-                }
-            }
-            return foundOneTrue;
-        }
-    }
-
-    public static class Or extends ScreenCondition {
-        protected List<ScreenCondition> subConditions;
-
-        public Or(ModelScreen modelScreen, Element condElement) {
-            super (modelScreen, condElement);
-            this.subConditions = readSubConditions(modelScreen, condElement);
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            // return true for the first one in the list that is true, basic or algo
-            for (ScreenCondition subCondition: this.subConditions) {
-                if (subCondition.eval(context)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
-    public static class Not extends ScreenCondition {
-        protected ScreenCondition subCondition;
-
-        public Not(ModelScreen modelScreen, Element condElement) {
-            super (modelScreen, condElement);
-            Element firstChildElement = UtilXml.firstChildElement(condElement);
-            this.subCondition = readCondition(modelScreen, firstChildElement);
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            return !this.subCondition.eval(context);
-        }
-    }
-
-    public static class IfServicePermission extends ScreenCondition {
-        protected FlexibleStringExpander serviceExdr;
-        protected FlexibleStringExpander actionExdr;
-        protected FlexibleStringExpander ctxMapExdr;
-        protected FlexibleStringExpander resExdr;
-
-        public IfServicePermission(ModelScreen modelScreen, Element condElement) {
-            super(modelScreen, condElement);
-            this.serviceExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("service-name"));
-            this.actionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("main-action"));
-            this.ctxMapExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("context-map"));
-            this.resExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("resource-description"));
-        }
-
-        @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");
-            if (userLogin != null) {
-                String serviceName = serviceExdr.expandString(context);
-                String mainAction = actionExdr.expandString(context);
-                String contextMap = ctxMapExdr.expandString(context);
-                String resource = resExdr.expandString(context);
-                if (UtilValidate.isEmpty(resource)) {
-                    resource = serviceName;
-                }
-
-                if (UtilValidate.isEmpty(serviceName)) {
-                    Debug.logWarning("No permission service-name specified!", module);
-                    return false;
-                }
-
-                Map<String, Object> serviceContext = UtilGenerics.toMap(context.get(contextMap));
-                if (serviceContext != null) {
-                    // copy the required internal fields
-                    serviceContext.put("userLogin", context.get("userLogin"));
-                    serviceContext.put("locale", context.get("locale"));
-                } else {
-                    serviceContext = context;
-                }
-
-                // get the service objects
-                LocalDispatcher dispatcher = this.modelScreen.getDispatcher(context);
-                DispatchContext dctx = dispatcher.getDispatchContext();
-
-                // get the service
-                ModelService permService;
-                try {
-                    permService = dctx.getModelService(serviceName);
-                } catch (GenericServiceException e) {
-                    Debug.logError(e, module);
-                    return false;
-                }
-
-                if (permService != null) {
-                    // build the context
-                    Map<String, Object> svcCtx = permService.makeValid(serviceContext, ModelService.IN_PARAM);
-                    svcCtx.put("resourceDescription", resource);
-                    if (UtilValidate.isNotEmpty(mainAction)) {
-                        svcCtx.put("mainAction", mainAction);
-                    }
-
-                    // invoke the service
-                    Map<String, Object> resp;
-                    try {
-                        resp = dispatcher.runSync(permService.name,  svcCtx, 300, true);
-                    } catch (GenericServiceException e) {
-                        Debug.logError(e, module);
-                        return false;
-                    }
-                    if (ServiceUtil.isError(resp) || ServiceUtil.isFailure(resp)) {
-                        Debug.logError(ServiceUtil.getErrorMessage(resp), module);
-                        return false;
-                    }
-                    Boolean hasPermission = (Boolean) resp.get("hasPermission");
-                    if (hasPermission != null) {
-                        return hasPermission.booleanValue();
-                    }
-                }
-            }
-            return false;
-        }
-    }
-
-    public static class IfHasPermission extends ScreenCondition {
-        protected FlexibleStringExpander permissionExdr;
-        protected FlexibleStringExpander actionExdr;
-
-        public IfHasPermission(ModelScreen modelScreen, Element condElement) {
-            super (modelScreen, condElement);
-            this.permissionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("permission"));
-            this.actionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("action"));
-        }
-
-        @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");
-            if (userLogin != null) {
-                String permission = permissionExdr.expandString(context);
-                String action = actionExdr.expandString(context);
-                Security security = (Security) context.get("security");
-                if (UtilValidate.isNotEmpty(action)) {
-                    // run hasEntityPermission
-                    if (security.hasEntityPermission(permission, action, userLogin)) {
-                        return true;
-                    }
-                } else {
-                    // run hasPermission
-                    if (security.hasPermission(permission, userLogin)) {
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-    }
-
-    public static class IfValidateMethod extends ScreenCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-        protected FlexibleStringExpander methodExdr;
-        protected FlexibleStringExpander classExdr;
-
-        public IfValidateMethod(ModelScreen modelScreen, Element condElement) {
-            super (modelScreen, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-            this.methodExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("method"));
-            this.classExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("class"));
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            String methodName = this.methodExdr.expandString(context);
-            String className = this.classExdr.expandString(context);
-
-            Object fieldVal = this.fieldAcsr.get(context);
-            String fieldString = null;
-            if (fieldVal != null) {
-                try {
-                    fieldString = (String) ObjectType.simpleTypeConvert(fieldVal, "String", null, (TimeZone) context.get("timeZone"), (Locale) context.get("locale"), true);
-                } catch (GeneralException e) {
-                    Debug.logError(e, "Could not convert object to String, using empty String", module);
-                }
-            }
-
-            // always use an empty string by default
-            if (fieldString == null) fieldString = "";
-
-            Class<?>[] paramTypes = new Class[] {String.class};
-            Object[] params = new Object[] {fieldString};
-
-            Class<?> valClass;
-            try {
-                valClass = ObjectType.loadClass(className);
-            } catch (ClassNotFoundException cnfe) {
-                Debug.logError("Could not find validation class: " + className, module);
-                return false;
-            }
-
-            Method valMethod;
-            try {
-                valMethod = valClass.getMethod(methodName, paramTypes);
-            } catch (NoSuchMethodException cnfe) {
-                Debug.logError("Could not find validation method: " + methodName + " of class " + className, module);
-                return false;
-            }
-
-            Boolean resultBool = Boolean.FALSE;
-            try {
-                resultBool = (Boolean) valMethod.invoke(null, params);
-            } catch (Exception e) {
-                Debug.logError(e, "Error in IfValidationMethod " + methodName + " of class " + className + ", defaulting to false ", module);
-            }
-
-            return resultBool.booleanValue();
-        }
-    }
-
-    public static class IfCompare extends ScreenCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-        protected FlexibleStringExpander valueExdr;
-
-        protected String operator;
-        protected String type;
-        protected FlexibleStringExpander formatExdr;
-
-        public IfCompare(ModelScreen modelScreen, Element condElement) {
-            super (modelScreen, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-            this.valueExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("value"));
-
-            this.operator = condElement.getAttribute("operator");
-            this.type = condElement.getAttribute("type");
-
-            this.formatExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("format"));
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            String value = this.valueExdr.expandString(context);
-            String format = this.formatExdr.expandString(context);
-
-            Object fieldVal = this.fieldAcsr.get(context);
-
-            // always use an empty string by default
-            if (fieldVal == null) {
-                fieldVal = "";
-            }
-
-            List<Object> messages = new LinkedList<Object>();
-            Boolean resultBool = BaseCompare.doRealCompare(fieldVal, value, operator, type, format, messages, null, null, true);
-            if (messages.size() > 0) {
-                messages.add(0, "Error with comparison in if-compare between field [" + fieldAcsr.toString() + "] with value [" + fieldVal + "] and value [" + value + "] with operator [" + operator + "] and type [" + type + "]: ");
-
-                StringBuilder fullString = new StringBuilder();
-                for (Object item: messages) {
-                    fullString.append(item.toString());
-                }
-                Debug.logWarning(fullString.toString(), module);
-
-                throw new IllegalArgumentException(fullString.toString());
-            }
-
-            return resultBool.booleanValue();
-        }
-    }
-
-    public static class IfCompareField extends ScreenCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-        protected FlexibleMapAccessor<Object> toFieldAcsr;
-
-        protected String operator;
-        protected String type;
-        protected FlexibleStringExpander formatExdr;
-
-        public IfCompareField(ModelScreen modelScreen, Element condElement) {
-            super (modelScreen, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-            this.toFieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("to-field"));
-            if (this.toFieldAcsr.isEmpty()) this.toFieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("to-field-name"));
-
-            this.operator = condElement.getAttribute("operator");
-            this.type = condElement.getAttribute("type");
-
-            this.formatExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("format"));
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            String format = this.formatExdr.expandString(context);
-
-            Object fieldVal = this.fieldAcsr.get(context);
-            Object toFieldVal = this.toFieldAcsr.get(context);
-
-            // always use an empty string by default
-            if (fieldVal == null) {
-                fieldVal = "";
-            }
-
-            List<Object> messages = new LinkedList<Object>();
-            Boolean resultBool = BaseCompare.doRealCompare(fieldVal, toFieldVal, operator, type, format, messages, null, null, false);
-            if (messages.size() > 0) {
-                messages.add(0, "Error with comparison in if-compare-field between field [" + fieldAcsr.toString() + "] with value [" + fieldVal + "] and to-field [" + toFieldAcsr.toString() + "] with value [" + toFieldVal + "] with operator [" + operator + "] and type [" + type + "]: ");
-
-                StringBuilder fullString = new StringBuilder();
-                for (Object item: messages) {
-                    fullString.append(item.toString());
-                }
-                Debug.logWarning(fullString.toString(), module);
-
-                throw new IllegalArgumentException(fullString.toString());
-            }
-
-            return resultBool.booleanValue();
-        }
-    }
-
-    public static class IfRegexp extends ScreenCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-        protected FlexibleStringExpander exprExdr;
-
-        public IfRegexp(ModelScreen modelScreen, Element condElement) {
-            super (modelScreen, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-            this.exprExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("expr"));
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            Object fieldVal = this.fieldAcsr.get(context);
-            String expr = this.exprExdr.expandString(context);
-            Pattern pattern;
-
-            try {
-                pattern = PatternFactory.createOrGetPerl5CompiledPattern(expr, true);
-            } catch (MalformedPatternException e) {
-                String errMsg = "Error in evaluation in if-regexp in screen: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-
-            String fieldString = null;
-            try {
-                fieldString = (String) ObjectType.simpleTypeConvert(fieldVal, "String", null, (TimeZone) context.get("timeZone"), (Locale) context.get("locale"), true);
-            } catch (GeneralException e) {
-                Debug.logError(e, "Could not convert object to String, using empty String", module);
-            }
-            // always use an empty string by default
-            if (fieldString == null) fieldString = "";
-
-            PatternMatcher matcher = new Perl5Matcher();
-            return matcher.matches(fieldString, pattern);
-        }
-    }
-
-    public static class IfEmpty extends ScreenCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-
-        public IfEmpty(ModelScreen modelScreen, Element condElement) {
-            super (modelScreen, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            Object fieldVal = this.fieldAcsr.get(context);
-            return ObjectType.isEmpty(fieldVal);
-        }
-    }
-    public static class IfEntityPermission extends ScreenCondition {
-        protected EntityPermissionChecker permissionChecker;
-
-        public IfEntityPermission(ModelScreen modelScreen, Element condElement) {
-            super (modelScreen, condElement);
-            this.permissionChecker = new EntityPermissionChecker(condElement);
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            return permissionChecker.runPermissionCheck(context);
-        }
-    }
-
-    public static class IfEmptySection extends ScreenCondition {
-        protected FlexibleStringExpander sectionExdr;
-
-        public IfEmptySection(ModelScreen modelScreen, Element condElement) {
-            super (modelScreen, condElement);
+        private IfEmptySection(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+            super (factory, modelWidget, condElement);
             this.sectionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("section-name"));
         }
 
         @Override
         public boolean eval(Map<String, Object> context) {
-            Map<String, Object> sectionsList = UtilGenerics.toMap(context.get("sections"));
-            return !sectionsList.containsKey(this.sectionExdr.expandString(context));
+            Map<String, Object> sectionsMap = UtilGenerics.toMap(context.get("sections"));
+            return !sectionsMap.containsKey(this.sectionExdr.expandString(context));
+        }
+    }
+
+    public static class ScreenConditionFactory extends DefaultConditionFactory {
+
+        @Override
+        public Condition newInstance(ModelWidget modelWidget, Element conditionElement) {
+            if (conditionElement == null) {
+                return DefaultConditionFactory.TRUE;
+            }
+            if ("if-empty-section".equals(conditionElement.getNodeName())) {
+                return new IfEmptySection(this, modelWidget, conditionElement);
+            } else {
+                return super.newInstance(modelWidget,conditionElement);
+            }
         }
     }
 }
diff --git a/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java b/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java
index adf125d..1aa2559 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java
+++ b/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java
@@ -33,16 +33,14 @@
 
 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.UtilMisc;
 import org.ofbiz.base.util.UtilXml;
 import org.ofbiz.base.util.collections.MapStack;
 import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.Delegator;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
-import org.ofbiz.entity.condition.EntityCondition;
 import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.widget.ModelWidget;
 import org.ofbiz.widget.ModelWidgetAction;
@@ -607,7 +605,7 @@
 
         public String getTitle(Map<String, Object> context) {
             String title = this.titleExdr.expandString(context);
-            StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
+            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
             if (simpleEncoder != null) {
                 title = simpleEncoder.encode(title);
             }
@@ -893,7 +891,8 @@
 
         public String getText(Map<String, Object> context) {
             String text = this.textExdr.expandString(context);
-            StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
+            // 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);
             }
@@ -1042,16 +1041,7 @@
                 Debug.logError(e, errMsg, module);
                 throw new RuntimeException(errMsg);
             }
-            StringBuffer renderBuffer = new StringBuffer();
-            modelTree.renderTreeString(renderBuffer, context, treeStringRenderer);
-            try {
-                writer.append(renderBuffer.toString());
-            } catch (IOException e) {
-                String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-
+            modelTree.renderTreeString(writer, context, treeStringRenderer);
             if (protectScope) {
                 UtilGenerics.<MapStack<String>>cast(context).pop();
             }
@@ -1470,7 +1460,8 @@
 
         public String getText(Map<String, Object> context) {
             String text = this.textExdr.expandString(context);
-            StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
+            // 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);
             }
@@ -1487,9 +1478,9 @@
 
         public String getTarget(Map<String, Object> context) {
             Map<String, Object> expanderContext = context;
-            StringUtil.SimpleEncoder simpleEncoder = context == null ? null : (StringUtil.SimpleEncoder) context.get("simpleEncoder");
+            UtilCodec.SimpleEncoder simpleEncoder = context == null ? null : (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
             if (simpleEncoder != null) {
-                expanderContext = StringUtil.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder);
+                expanderContext = UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder);
             }
             return this.targetExdr.expandString(expanderContext);
         }
@@ -1632,7 +1623,8 @@
 
         public String getAlt(Map<String, Object> context) {
             String alt = this.alt.expandString(context);
-            StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
+            // 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);
             }
@@ -1671,8 +1663,10 @@
                     portalPage = PortalPageWorker.getPortalPage(expandedPortalPageId, context);
                 } else {
                     try {
-                        portalPage = EntityQuery.use(delegator).from("PortalPage").where("portalPageId", expandedPortalPageId)
-                                .cache().queryOne();
+                        portalPage = EntityQuery.use(delegator)
+                                                .from("PortalPage")
+                                                .where("portalPageId", expandedPortalPageId)
+                                                .cache().queryOne();
                     } catch (GenericEntityException e) {
                         throw new RuntimeException(e);
                     }
@@ -1695,9 +1689,13 @@
                 List<GenericValue> portletAttributes = null;
                 GenericValue portalPage = getPortalPageValue(context);
                 String actualPortalPageId = portalPage.getString("portalPageId");
-                portalPageColumns = delegator.findByAnd("PortalPageColumn", UtilMisc.toMap("portalPageId", actualPortalPageId),
-                        UtilMisc.toList("columnSeqId"), true);
-
+                portalPageColumns = EntityQuery.use(delegator)
+                                               .from("PortalPageColumn")
+                                               .where("portalPageId", actualPortalPageId)
+                                               .orderBy("columnSeqId")
+                                               .cache(true)
+                                               .queryList();
+                
                 // Renders the portalPage header
                 screenStringRenderer.renderPortalPageBegin(writer, context, this);
                 
@@ -1714,8 +1712,11 @@
                     screenStringRenderer.renderPortalPageColumnBegin(writer, context, this, columnValue);
 
                     // Get the Portlets located in the current column
-                    portalPagePortlets = delegator.findByAnd("PortalPagePortletView", UtilMisc.toMap("portalPageId", portalPage.getString("portalPageId"), "columnSeqId", columnSeqId), UtilMisc.toList("sequenceNum"), false);
-                    
+                    portalPagePortlets = EntityQuery.use(delegator)
+                                                    .from("PortalPagePortletView")
+                                                    .where("portalPageId", portalPage.getString("portalPageId"), "columnSeqId", columnSeqId)
+                                                    .orderBy("sequenceNum")
+                                                    .queryList();
                     // First Portlet in a Column has no previous Portlet
                     String prevPortletId = "";
                     String prevPortletSeqId = "";
@@ -1748,9 +1749,11 @@
                         context.put("nextColumnSeqId", nextColumnSeqId);
                        
                         // Get portlet's attributes
-                        portletAttributes = delegator.findList("PortletAttribute",
-                            EntityCondition.makeCondition(UtilMisc.toMap("portalPageId", portletValue.get("portalPageId"), "portalPortletId", portletValue.get("portalPortletId"), "portletSeqId", portletValue.get("portletSeqId"))),
-                            null, null, null, false);
+                        portletAttributes = EntityQuery.use(delegator)
+                                                       .from("PortletAttribute")
+                                                       .where("portalPageId", portletValue.get("portalPageId"), "portalPortletId", portletValue.get("portalPortletId"), "portletSeqId", portletValue.get("portletSeqId"))
+                                                       .queryList();
+                        
                         ListIterator <GenericValue>attributesIterator = portletAttributes.listIterator();
                         while (attributesIterator.hasNext()) {
                             GenericValue attribute = attributesIterator.next();
diff --git a/framework/widget/src/org/ofbiz/widget/screen/ScreenFopViewHandler.java b/framework/widget/src/org/ofbiz/widget/screen/ScreenFopViewHandler.java
index 5b7f7af..c76018c 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/ScreenFopViewHandler.java
+++ b/framework/widget/src/org/ofbiz/widget/screen/ScreenFopViewHandler.java
@@ -32,7 +32,7 @@
 
 import org.apache.fop.apps.Fop;
 import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
 import org.ofbiz.base.util.UtilProperties;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.entity.Delegator;
@@ -57,6 +57,7 @@
     /**
      * @see org.ofbiz.webapp.view.ViewHandler#init(javax.servlet.ServletContext)
      */
+    @Override
     public void init(ServletContext context) throws ViewHandlerException {
         this.servletContext = context;
     }
@@ -64,9 +65,10 @@
     /**
      * @see org.ofbiz.webapp.view.ViewHandler#render(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
      */
+    @Override
     public void render(String name, String page, String info, String contentType, String encoding, HttpServletRequest request, HttpServletResponse response) throws ViewHandlerException {
 
-    	Delegator delegator = (Delegator) request.getAttribute("delegator");
+        Delegator delegator = (Delegator) request.getAttribute("delegator");
         // render and obtain the XSL-FO
         Writer writer = new StringWriter();
         try {
@@ -80,7 +82,7 @@
 
             // this is the object used to render forms from their definitions
             screens.getContext().put("formStringRenderer", formStringRenderer);
-            screens.getContext().put("simpleEncoder", StringUtil.getEncoder(EntityUtilProperties.getPropertyValue("widget", getName() + ".encoder", delegator)));
+            screens.getContext().put("simpleEncoder", UtilCodec.getEncoder(EntityUtilProperties.getPropertyValue("widget", getName() + ".encoder", delegator)));
             screens.render(page);
         } catch (Exception e) {
             renderError("Problems with the response writer/output stream", e, "[Not Yet Rendered]", request, response);
diff --git a/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java b/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java
index 301bf05..24d3f5c 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java
@@ -55,10 +55,8 @@
 public class MacroTreeRenderer implements TreeStringRenderer {
 
     public static final String module = MacroTreeRenderer.class.getName();
-    ScreenStringRenderer screenStringRenderer = null;
     private Template macroLibrary;
     private Environment environment;
-    protected boolean widgetCommentsEnabled = false;
 
 
     public MacroTreeRenderer(String macroLibraryPath, Appendable writer) throws TemplateException, IOException {
@@ -67,29 +65,20 @@
         this.environment = FreeMarkerWorker.renderTemplate(this.macroLibrary, input, writer);
     }
 
-    private void executeMacro(Appendable writer, String macro) throws IOException {
+    private void executeMacro(String macro) throws IOException {
         try {
             Reader templateReader = new StringReader(macro);
             // FIXME: I am using a Date as an hack to provide a unique name for the template...
-            Template template = new Template((new java.util.Date()).toString(), templateReader, FreeMarkerWorker.getDefaultOfbizConfig());
+            Template template = new Template((new java.util.Date()).toString(), templateReader,
+                    FreeMarkerWorker.getDefaultOfbizConfig());
             templateReader.close();
-            if (writer != null) {
-                Map<String, Object> input = UtilMisc.toMap("key", null);
-                Environment tmpEnvironment = FreeMarkerWorker.renderTemplate(this.macroLibrary, input, writer);
-                tmpEnvironment.include(template);
-            } else {
-                this.environment.include(template);
-            }
+            this.environment.include(template);
         } catch (TemplateException e) {
-            Debug.logError(e, "Error rendering screen thru ftl", module);
+            Debug.logError(e, "Error rendering tree thru ftl", module);
         } catch (IOException e) {
-            Debug.logError(e, "Error rendering screen thru ftl", module);
+            Debug.logError(e, "Error rendering tree thru ftl", module);
         }
     }
-    
-    private void executeMacro(String macro) throws IOException {
-        executeMacro(null, macro);
-    }
  
     /**
      * Renders the beginning boundary comment string.
@@ -98,18 +87,16 @@
      * @param modelWidget The widget
      */
     public void renderBeginningBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
-        if (this.widgetCommentsEnabled) {
-            StringWriter sr = new StringWriter();
-            sr.append("<@formatBoundaryComment ");
-            sr.append(" boundaryType=\"");
-            sr.append("Begin");
-            sr.append("\" widgetType=\"");
-            sr.append(widgetType);
-            sr.append("\" widgetName=\"");
-            sr.append(modelWidget.getBoundaryCommentName());
-            sr.append("\" />");
-            executeMacro(sr.toString());
-        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@formatBoundaryComment ");
+        sr.append(" boundaryType=\"");
+        sr.append("Begin");
+        sr.append("\" widgetType=\"");
+        sr.append(widgetType);
+        sr.append("\" widgetName=\"");
+        sr.append(modelWidget.getBoundaryCommentName());
+        sr.append("\" />");
+        executeMacro(sr.toString());
     }
     
     /**
@@ -119,28 +106,27 @@
      * @param modelWidget The widget
      */
     public void renderEndingBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
-        if (this.widgetCommentsEnabled) {
-            StringWriter sr = new StringWriter();
-            sr.append("<@formatBoundaryComment ");
-            sr.append(" boundaryType=\"");
-            sr.append("End");
-            sr.append("\" widgetType=\"");
-            sr.append(widgetType);
-            sr.append("\" widgetName=\"");
-            sr.append(modelWidget.getBoundaryCommentName());
-            sr.append("\" />");
-            executeMacro(sr.toString());
-        }
-    }    
+        StringWriter sr = new StringWriter();
+        sr.append("<@formatBoundaryComment ");
+        sr.append(" boundaryType=\"");
+        sr.append("End");
+        sr.append("\" widgetType=\"");
+        sr.append(widgetType);
+        sr.append("\" widgetName=\"");
+        sr.append(modelWidget.getBoundaryCommentName());
+        sr.append("\" />");
+        executeMacro(sr.toString());
+    }
     
     public void renderNodeBegin(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node, int depth) throws IOException {
         String currentNodeTrailPiped = null;
         List<String> currentNodeTrail = UtilGenerics.toList(context.get("currentNodeTrail"));
         
         String style = "";
-        if (node.isRootNode()) {           
-            this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
-            renderBeginningBoundaryComment(writer, "Tree Widget", node.getModelTree());
+        if (node.isRootNode()) {
+            if (ModelWidget.widgetBoundaryCommentsEnabled(context)) {
+                renderBeginningBoundaryComment(writer, "Tree Widget", node.getModelTree());
+            }
             style = "basic-tree";
         }
  
@@ -151,7 +137,7 @@
         sr.append("\" />");
         executeMacro(sr.toString());
 
-        String pkName = node.getPkName();
+        String pkName = node.getPkName(context);
         String entityId = null;
         String entryName = node.getEntryName();
         if (UtilValidate.isNotEmpty(entryName)) {
@@ -162,9 +148,10 @@
         }
         boolean hasChildren = node.hasChildren(context);
 
-        ModelTree.ModelNode.Link expandCollapseLink = new ModelTree.ModelNode.Link();
         // check to see if this node needs to be expanded.
         if (hasChildren && node.isExpandCollapse()) {
+            // FIXME: Using a widget model in this way is an ugly hack.
+            ModelTree.ModelNode.Link expandCollapseLink = null;
             String targetEntityId = null;
             List<String> targetNodeTrail = UtilGenerics.toList(context.get("targetNodeTrail"));
             if (depth < targetNodeTrail.size()) {
@@ -178,7 +165,6 @@
                     context.put("processChildren", Boolean.FALSE);
                     //expandCollapseLink.setText("&nbsp;+&nbsp;");
                     currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|");
-                    expandCollapseLink.setStyle("collapsed");
                     StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));
                     String trailName = node.getModelTree().getTrailName(context);
                     if (target.indexOf("?") < 0) {
@@ -187,7 +173,7 @@
                         target.append("&");
                     }
                     target.append(trailName).append("=").append(currentNodeTrailPiped);
-                    expandCollapseLink.setTarget(target.toString());
+                    expandCollapseLink = new ModelTree.ModelNode.Link("collapsed", target.toString(), " ");
                 }
             } else {
                 context.put("processChildren", Boolean.TRUE);
@@ -197,7 +183,6 @@
                 if (currentNodeTrailPiped == null) {
                     currentNodeTrailPiped = "";
                 }
-                expandCollapseLink.setStyle("expanded");
                 StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));
                 String trailName = node.getModelTree().getTrailName(context);
                 if (target.indexOf("?") < 0) {
@@ -206,32 +191,35 @@
                     target.append("&");
                 }
                 target.append(trailName).append("=").append(currentNodeTrailPiped);
-                expandCollapseLink.setTarget(target.toString());
+                expandCollapseLink = new ModelTree.ModelNode.Link("expanded", target.toString(), " ");
                 // add it so it can be remove in renderNodeEnd
                 currentNodeTrail.add(lastContentId);
             }
-            renderLink(writer, context, expandCollapseLink);
+            if (expandCollapseLink != null) {
+                renderLink(writer, context, expandCollapseLink);
+            }
         } else if (!hasChildren) {
             context.put("processChildren", Boolean.FALSE);
-            expandCollapseLink.setStyle("leafnode");
+            ModelTree.ModelNode.Link expandCollapseLink = new ModelTree.ModelNode.Link("leafnode", "", " ");
             renderLink(writer, context, expandCollapseLink);
         }
     }
 
     public void renderNodeEnd(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException {
         Boolean processChildren = (Boolean) context.get("processChildren");
-        if (node.isRootNode()) {            
-            renderEndingBoundaryComment(writer, "Tree Widget", node.getModelTree());
-        }
-        
         StringWriter sr = new StringWriter();
-        sr.append("<@renderNodeEnd ");        
+        sr.append("<@renderNodeEnd ");
         sr.append(" processChildren=");
         sr.append(Boolean.toString(processChildren.booleanValue()));
         sr.append(" isRootNode=");
         sr.append(Boolean.toString(node.isRootNode()));
         sr.append(" />");
-        executeMacro(sr.toString());        
+        executeMacro(sr.toString());
+        if (node.isRootNode()) {
+            if (ModelWidget.widgetBoundaryCommentsEnabled(context)) {
+                renderEndingBoundaryComment(writer, "Tree Widget", node.getModelTree());
+            }
+        }
     }
 
     public void renderLastElement(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException {
@@ -369,14 +357,14 @@
         sr.append("\" urlString=\"");
         sr.append(urlString);
         sr.append("\" />");
-        executeMacro(writer, sr.toString());        
+        executeMacro(sr.toString());        
     }
 
     public ScreenStringRenderer getScreenStringRenderer(Map<String, Object> context) {
         ScreenRenderer screenRenderer = (ScreenRenderer)context.get("screens");
         if (screenRenderer != null) {
-            this.screenStringRenderer = screenRenderer.getScreenStringRenderer();
+            return screenRenderer.getScreenStringRenderer();
         } 
-        return this.screenStringRenderer;
+        return null;
     }
 }
diff --git a/framework/widget/src/org/ofbiz/widget/tree/ModelTree.java b/framework/widget/src/org/ofbiz/widget/tree/ModelTree.java
index 82d3632..b95a5fd 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/ModelTree.java
+++ b/framework/widget/src/org/ofbiz/widget/tree/ModelTree.java
@@ -19,7 +19,6 @@
 package org.ofbiz.widget.tree;
 
 import java.io.IOException;
-import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -35,10 +34,9 @@
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.GeneralException;
 import org.ofbiz.base.util.StringUtil;
-import org.ofbiz.base.util.UtilFormatOut;
+import org.ofbiz.base.util.UtilCodec;
 import org.ofbiz.base.util.UtilGenerics;
 import org.ofbiz.base.util.UtilHttp;
-import org.ofbiz.base.util.UtilMisc;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.base.util.UtilXml;
 import org.ofbiz.base.util.collections.MapStack;
@@ -49,11 +47,12 @@
 import org.ofbiz.entity.model.ModelEntity;
 import org.ofbiz.entity.model.ModelField;
 import org.ofbiz.entity.util.EntityListIterator;
-import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.entity.util.EntityQuery;
 import org.ofbiz.widget.ModelWidget;
 import org.ofbiz.widget.ModelWidgetAction;
 import org.ofbiz.widget.ModelWidgetVisitor;
 import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.WidgetWorker.Parameter;
 import org.ofbiz.widget.screen.ModelScreen;
 import org.ofbiz.widget.screen.ScreenFactory;
 import org.ofbiz.widget.screen.ScreenRenderException;
@@ -62,114 +61,119 @@
 import org.xml.sax.SAXException;
 
 /**
- * Widget Library - Tree model class
+ * Models the &lt;tree&gt; element.
+ * 
+ * @see <code>widget-tree.xsd</code>
  */
 @SuppressWarnings("serial")
 public class ModelTree extends ModelWidget {
 
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     DEVELOPERS PLEASE READ
+     * ----------------------------------------------------------------------- *
+     * 
+     * This model is intended to be a read-only data structure that represents
+     * an XML element. Outside of object construction, the class should not
+     * have any behaviors.
+     * 
+     * Instances of this class will be shared by multiple threads - therefore
+     * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME!
+     * 
+     */
+
     public static final String module = ModelTree.class.getName();
 
-    protected String defaultEntityName;
-    protected String defaultPkName;
-    protected String defaultRenderStyle;
-    protected FlexibleStringExpander defaultWrapStyleExdr;
-    protected Delegator delegator;
-    protected LocalDispatcher dispatcher;
-    protected FlexibleStringExpander expandCollapseRequestExdr;
-    protected boolean forceChildCheck;
-    protected List<ModelNode> nodeList = new ArrayList<ModelNode>();
-    protected Map<String, ModelNode> nodeMap = new HashMap<String, ModelNode>();
-    protected int openDepth;
-    protected int postTrailOpenDepth;
-    protected String rootNodeName;
-    protected FlexibleStringExpander trailNameExdr;
-    protected String treeLocation;
+    private final String defaultEntityName;
+    private final String defaultRenderStyle;
+    private final FlexibleStringExpander defaultWrapStyleExdr;
+    private final FlexibleStringExpander expandCollapseRequestExdr;
+    private final boolean forceChildCheck;
+    private final String location;
+    private final Map<String, ModelNode> nodeMap;
+    private final int openDepth;
+    private final int postTrailOpenDepth;
+    private final String rootNodeName;
+    private final FlexibleStringExpander trailNameExdr;
 
-// ===== CONSTRUCTORS =====
-    /** Default Constructor */
-
-    public ModelTree(Element treeElement, Delegator delegator, LocalDispatcher dispatcher) {
+    public ModelTree(Element treeElement, String location) {
         super(treeElement);
+        this.location = location;
         this.rootNodeName = treeElement.getAttribute("root-node-name");
-        this.defaultRenderStyle = UtilFormatOut.checkEmpty(treeElement.getAttribute("default-render-style"), "simple");
+        String defaultRenderStyle = UtilXml.checkEmpty(treeElement.getAttribute("default-render-style"), "simple");
         // A temporary hack to accommodate those who might still be using "render-style" instead of "default-render-style"
-        if (UtilValidate.isEmpty(this.defaultRenderStyle) || this.defaultRenderStyle.equals("simple")) {
+        if (defaultRenderStyle.isEmpty() || defaultRenderStyle.equals("simple")) {
             String rStyle = treeElement.getAttribute("render-style");
-            if (UtilValidate.isNotEmpty(rStyle))
-                this.defaultRenderStyle = rStyle;
+            if (!rStyle.isEmpty())
+                defaultRenderStyle = rStyle;
         }
+        this.defaultRenderStyle = defaultRenderStyle;
         this.defaultWrapStyleExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("default-wrap-style"));
         this.expandCollapseRequestExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("expand-collapse-request"));
-        this.trailNameExdr = FlexibleStringExpander.getInstance(UtilFormatOut.checkEmpty(treeElement.getAttribute("trail-name"), "trail"));
-        this.delegator = delegator;
-        this.dispatcher = dispatcher;
+        this.trailNameExdr = FlexibleStringExpander.getInstance(UtilXml.checkEmpty(treeElement.getAttribute("trail-name"),
+                "trail"));
         this.forceChildCheck = !"false".equals(treeElement.getAttribute("force-child-check"));
-        setDefaultEntityName(treeElement.getAttribute("entity-name"));
-        try {
-            openDepth = Integer.parseInt(treeElement.getAttribute("open-depth"));
-        } catch (NumberFormatException e) {
-            openDepth = 0;
+        this.defaultEntityName = treeElement.getAttribute("entity-name");
+        int openDepth = 0;
+        if (treeElement.hasAttribute("open-depth")) {
+            try {
+                openDepth = Integer.parseInt(treeElement.getAttribute("open-depth"));
+            } catch (NumberFormatException e) {
+                throw new IllegalArgumentException("Invalid open-depth attribute value for the tree definition with name: "
+                        + getName());
+            }
         }
-
-        try {
-            postTrailOpenDepth = Integer.parseInt(treeElement.getAttribute("post-trail-open-depth"));
-        } catch (NumberFormatException e) {
-            postTrailOpenDepth = 999;
+        this.openDepth = openDepth;
+        int postTrailOpenDepth = 999;
+        if (treeElement.hasAttribute("post-trail-open-depth")) {
+            try {
+                postTrailOpenDepth = Integer.parseInt(treeElement.getAttribute("post-trail-open-depth"));
+            } catch (NumberFormatException e) {
+                throw new IllegalArgumentException(
+                        "Invalid post-trail-open-depth attribute value for the tree definition with name: " + getName());
+            }
         }
-
-        for (Element nodeElementEntry: UtilXml.childElementList(treeElement, "node")) {
-            ModelNode node = new ModelNode(nodeElementEntry, this);
-            String nodeName = node.getName();
-            nodeList.add(node);
-            nodeMap.put(nodeName,node);
-        }
-
-        if (nodeList.size() == 0) {
+        this.postTrailOpenDepth = postTrailOpenDepth;
+        List<? extends Element> nodeElements = UtilXml.childElementList(treeElement, "node");
+        if (nodeElements.size() == 0) {
             throw new IllegalArgumentException("No node elements found for the tree definition with name: " + getName());
         }
+        Map<String, ModelNode> nodeMap = new HashMap<String, ModelNode>();
+        for (Element nodeElementEntry : UtilXml.childElementList(treeElement, "node")) {
+            ModelNode node = new ModelNode(nodeElementEntry, this);
+            String nodeName = node.getName();
+            nodeMap.put(nodeName, node);
+        }
+        this.nodeMap = Collections.unmodifiableMap(nodeMap);
     }
 
-    public void setDefaultEntityName(String name) {
-        String nm = name;
-        if (UtilValidate.isEmpty(nm)) {
-            nm = "Content";
-        }
-        this.defaultEntityName = nm;
-        ModelEntity modelEntity = delegator.getModelEntity(this.defaultEntityName);
-        if (modelEntity.getPksSize() == 1) {
-            ModelField modelField = modelEntity.getOnlyPk();
-            this.defaultPkName = modelField.getName();
-        }
+    @Override
+    public void accept(ModelWidgetVisitor visitor) throws Exception {
+        visitor.visit(this);
+    }
+
+    @Override
+    public String getBoundaryCommentName() {
+        return location + "#" + getName();
     }
 
     public String getDefaultEntityName() {
         return this.defaultEntityName;
     }
 
-    public String getDefaultPkName() {
-        return this.defaultPkName;
-    }
-
-    public String getRootNodeName() {
-        return rootNodeName;
-    }
-
-    public String getWrapStyle(Map<String, Object> context) {
-        return this.defaultWrapStyleExdr.expandString(context);
-    }
-
-    public int getOpenDepth() {
-        return openDepth;
-    }
-
-    public int getPostTrailOpenDepth() {
-        return postTrailOpenDepth;
+    public String getDefaultPkName(Map<String, Object> context) {
+        ModelEntity modelEntity = WidgetWorker.getDelegator(context).getModelEntity(this.defaultEntityName);
+        if (modelEntity.getPksSize() == 1) {
+            ModelField modelField = modelEntity.getOnlyPk();
+            return modelField.getName();
+        }
+        return null;
     }
 
     public String getExpandCollapseRequest(Map<String, Object> context) {
         String expColReq = this.expandCollapseRequestExdr.expandString(context);
         if (UtilValidate.isEmpty(expColReq)) {
-            HttpServletRequest request = (HttpServletRequest)context.get("request");
+            HttpServletRequest request = (HttpServletRequest) context.get("request");
             String s1 = request.getRequestURI();
             int pos = s1.lastIndexOf("/");
             if (pos >= 0)
@@ -177,7 +181,6 @@
             else
                 expColReq = s1;
         }
-
         //append also the request parameters
         Map<String, Object> paramMap = UtilGenerics.checkMap(context.get("requestParameters"));
         if (UtilValidate.isNotEmpty(paramMap)) {
@@ -193,66 +196,64 @@
                 expColReq += queryString;
             }
         }
-
         return expColReq;
     }
 
+    public int getOpenDepth() {
+        return openDepth;
+    }
+
+    public int getPostTrailOpenDepth() {
+        return postTrailOpenDepth;
+    }
+
+    public String getRenderStyle() {
+        return this.defaultRenderStyle;
+    }
+
+    public String getRootNodeName() {
+        return rootNodeName;
+    }
+
     public String getTrailName(Map<String, Object> context) {
         return this.trailNameExdr.expandString(context);
     }
 
-    @Override
-    public String getBoundaryCommentName() {
-        return treeLocation + "#" + getName();
-    }
-
-    public void setTreeLocation(String treeLocation) {
-        this.treeLocation = treeLocation;
+    public String getWrapStyle(Map<String, Object> context) {
+        return this.defaultWrapStyleExdr.expandString(context);
     }
 
     /**
-     * Renders this tree to a String, i.e. in a text format, as defined with the
-     * TreeStringRenderer implementation.
+     * Renders this model.
      *
-     * @param buf the StringBuffer Object
-     * @param context Map containing the tree context; the following are
-     *   reserved words in this context: parameters (Map), isError (Boolean),
-     *   itemIndex (Integer, for lists only, otherwise null), bshInterpreter,
-     *   treeName (String, optional alternate name for tree, defaults to the
-     *   value of the name attribute)
-     * @param treeStringRenderer An implementation of the TreeStringRenderer
-     *   interface that is responsible for the actual text generation for
-     *   different tree elements; implementing your own makes it possible to
-     *   use the same tree definitions for many types of tree UIs
+     * @param writer
+     * @param context
+     * @param treeStringRenderer
      */
     @SuppressWarnings("rawtypes")
-    public void renderTreeString(StringBuffer buf, Map<String, Object> context, TreeStringRenderer treeStringRenderer) throws GeneralException {
+    public void renderTreeString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer)
+            throws GeneralException {
         Map<String, Object> parameters = UtilGenerics.checkMap(context.get("parameters"));
-
         ModelNode node = nodeMap.get(rootNodeName);
-
         String trailName = trailNameExdr.expandString(context);
-        String treeString = (String)context.get(trailName);
+        String treeString = (String) context.get(trailName);
         if (UtilValidate.isEmpty(treeString)) {
-            treeString = (String)parameters.get(trailName);
+            treeString = (String) parameters.get(trailName);
         }
         List<String> trail = null;
         if (UtilValidate.isNotEmpty(treeString)) {
             trail = StringUtil.split(treeString, "|");
             if (UtilValidate.isEmpty(trail))
                 throw new RuntimeException("Tree 'trail' value is empty.");
-
             context.put("rootEntityId", trail.get(0));
-            context.put(defaultPkName, trail.get(0));
+            context.put(getDefaultPkName(context), trail.get(0));
         } else {
             trail = new LinkedList<String>();
         }
         context.put("targetNodeTrail", trail);
         context.put("currentNodeTrail", new LinkedList());
-        StringWriter writer = new StringWriter();
         try {
             node.renderNodeString(writer, context, treeStringRenderer, 0);
-            buf.append(writer.toString());
         } catch (IOException e2) {
             String errMsg = "Error rendering included label with name [" + getName() + "] : " + e2.toString();
             Debug.logError(e2, errMsg, module);
@@ -260,38 +261,28 @@
         }
     }
 
-    public LocalDispatcher getDispatcher() {
-        return this.dispatcher;
-    }
-
-    public Delegator getDelegator() {
-        return this.delegator;
-    }
-
-    public String getRenderStyle() {
-        return this.defaultRenderStyle;
-    }
-
-
+    /**
+     * Models the &lt;node&gt; element.
+     * 
+     * @see <code>widget-tree.xsd</code>
+     */
     public static class ModelNode extends ModelWidget {
 
         private final List<ModelWidgetAction> actions;
-        protected ModelTreeCondition condition;
-        protected String entityName;
-        protected String entryName;
-        protected String expandCollapseStyle;
-        protected Image image;
-        protected Label label;
-        protected Link link;
-        protected ModelTree modelTree;
-        protected String pkName;
-        protected String renderStyle;
-        protected FlexibleStringExpander screenLocationExdr;
-        protected FlexibleStringExpander screenNameExdr;
-        protected String shareScope;
-        protected List<ModelSubNode> subNodeList = new ArrayList<ModelSubNode>();
-        protected List<Object []> subNodeValues;
-        protected FlexibleStringExpander wrapStyleExdr;
+        private final ModelTreeCondition condition;
+        private final String entityName;
+        private final String entryName;
+        private final String expandCollapseStyle;
+        private final Label label;
+        private final Link link;
+        private final ModelTree modelTree;
+        private final String pkName;
+        private final String renderStyle;
+        private final FlexibleStringExpander screenLocationExdr;
+        private final FlexibleStringExpander screenNameExdr;
+        private final String shareScope;
+        private final List<ModelSubNode> subNodeList;
+        private final FlexibleStringExpander wrapStyleExdr;
 
         public ModelNode(Element nodeElement, ModelTree modelTree) {
             super(nodeElement);
@@ -299,18 +290,18 @@
             this.expandCollapseStyle = nodeElement.getAttribute("expand-collapse-style");
             this.wrapStyleExdr = FlexibleStringExpander.getInstance(nodeElement.getAttribute("wrap-style"));
             this.renderStyle = nodeElement.getAttribute("render-style");
-            this.entryName = UtilFormatOut.checkEmpty(nodeElement.getAttribute("entry-name"), null);
-            setEntityName(nodeElement.getAttribute("entity-name"));
-            if (this.pkName == null || nodeElement.hasAttribute("join-field-name"))
-                this.pkName = nodeElement.getAttribute("join-field-name");
+            this.entryName = nodeElement.getAttribute("entry-name");
+            this.entityName = nodeElement.getAttribute("entity-name");
+            this.pkName = nodeElement.getAttribute("join-field-name");
             ArrayList<ModelWidgetAction> actions = new ArrayList<ModelWidgetAction>();
+            // FIXME: Validate child elements, should be only one of actions, entity-one, service, script.
             Element actionsElement = UtilXml.firstChildElement(nodeElement, "actions");
             if (actionsElement != null) {
                 actions.addAll(ModelTreeAction.readNodeActions(this, actionsElement));
             }
             Element actionElement = UtilXml.firstChildElement(nodeElement, "entity-one");
             if (actionElement != null) {
-               actions.add(new ModelWidgetAction.EntityOne(this, actionElement));
+                actions.add(new ModelWidgetAction.EntityOne(this, actionElement));
             }
             actionElement = UtilXml.firstChildElement(nodeElement, "service");
             if (actionElement != null) {
@@ -322,156 +313,135 @@
             }
             actions.trimToSize();
             this.actions = Collections.unmodifiableList(actions);
-
             Element screenElement = UtilXml.firstChildElement(nodeElement, "include-screen");
             if (screenElement != null) {
-                this.screenNameExdr =  FlexibleStringExpander.getInstance(screenElement.getAttribute("name"));
-                this.screenLocationExdr =  FlexibleStringExpander.getInstance(screenElement.getAttribute("location"));
-                this.shareScope =  screenElement.getAttribute("share-scope");
+                this.screenNameExdr = FlexibleStringExpander.getInstance(screenElement.getAttribute("name"));
+                this.screenLocationExdr = FlexibleStringExpander.getInstance(screenElement.getAttribute("location"));
+                this.shareScope = screenElement.getAttribute("share-scope");
+            } else {
+                this.screenNameExdr = FlexibleStringExpander.getInstance("");
+                this.screenLocationExdr = FlexibleStringExpander.getInstance("");
+                this.shareScope = "";
             }
-
             Element labelElement = UtilXml.firstChildElement(nodeElement, "label");
             if (labelElement != null) {
                 this.label = new Label(labelElement);
+            } else {
+                this.label = null;
             }
-
             Element linkElement = UtilXml.firstChildElement(nodeElement, "link");
             if (linkElement != null) {
                 this.link = new Link(linkElement);
+            } else {
+                this.link = null;
             }
-
-            Element imageElement = UtilXml.firstChildElement(nodeElement, "image");
-            if (imageElement != null) {
-                this.image = new Image(imageElement);
-            }
-
-            /* there are situations in which nothing should be displayed
-            if (screenElement == null && labelElement == null && linkElement == null) {
-                throw new IllegalArgumentException("Neither 'screen' nor 'label' nor 'link' found for the node definition with name: " + this.name);
-            }
-            */
             Element conditionElement = UtilXml.firstChildElement(nodeElement, "condition");
             if (conditionElement != null) {
                 this.condition = new ModelTreeCondition(modelTree, conditionElement);
+            } else {
+                this.condition = null;
             }
-
-            for (Element subNodeElementEntry: UtilXml.childElementList(nodeElement, "sub-node")) {
-                ModelSubNode subNode = new ModelSubNode(subNodeElementEntry, this);
-                subNodeList.add(subNode);
+            List<? extends Element> nodeElements = UtilXml.childElementList(nodeElement, "sub-node");
+            if (!nodeElements.isEmpty()) {
+                List<ModelSubNode> subNodeList = new ArrayList<ModelSubNode>();
+                for (Element subNodeElementEntry : nodeElements) {
+                    ModelSubNode subNode = new ModelSubNode(subNodeElementEntry, this);
+                    subNodeList.add(subNode);
+                }
+                this.subNodeList = Collections.unmodifiableList(subNodeList);
+            } else {
+                this.subNodeList = Collections.emptyList();
             }
-
-
         }
 
-        public void renderNodeString(Appendable writer, Map<String, Object> context,
-                TreeStringRenderer treeStringRenderer, int depth)
-                throws IOException, GeneralException {
-            boolean passed = true;
-            if (this.condition != null) {
-                if (!this.condition.eval(context)) {
-                    passed = false;
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        private List<Object[]> getChildren(Map<String, Object> context) {
+            List<Object[]> subNodeValues = new ArrayList<Object[]>();
+            for (ModelSubNode subNode : subNodeList) {
+                String nodeName = subNode.getNodeName(context);
+                ModelNode node = modelTree.nodeMap.get(nodeName);
+                List<ModelWidgetAction> subNodeActions = subNode.getActions();
+                //if (Debug.infoOn()) Debug.logInfo(" context.currentValue:" + context.get("currentValue"), module);
+                ModelWidgetAction.runSubActions(subNodeActions, context);
+                // List dataFound = (List)context.get("dataFound");
+                Iterator<? extends Map<String, ? extends Object>> dataIter = subNode.getListIterator(context);
+                if (dataIter instanceof EntityListIterator) {
+                    EntityListIterator eli = (EntityListIterator) dataIter;
+                    Map<String, Object> val = null;
+                    while ((val = eli.next()) != null) {
+                        Object[] arr = { node, val };
+                        subNodeValues.add(arr);
+                    }
+                    try {
+                        eli.close();
+                    } catch (GenericEntityException e) {
+                        Debug.logError(e, module);
+                        throw new RuntimeException(e.getMessage());
+                    }
+                } else if (dataIter != null) {
+                    while (dataIter.hasNext()) {
+                        Map<String, ? extends Object> val = dataIter.next();
+                        Object[] arr = { node, val };
+                        subNodeValues.add(arr);
+                    }
                 }
             }
-            //Debug.logInfo("in ModelMenu, name:" + this.getName(), module);
-            if (passed) {
-                List<String> currentNodeTrail = UtilGenerics.toList(context.get("currentNodeTrail"));
-                context.put("processChildren", Boolean.TRUE);
-                // this action will usually obtain the "current" entity
-                ModelTreeAction.runSubActions(this.actions, context);
-                String pkName = getPkName();
-                String id = null;
-                if (UtilValidate.isNotEmpty(this.entryName)) {
-                    id = UtilGenerics.<Map<String, String>>cast(context.get(this.entryName)).get(pkName);
-                } else {
-                    id = (String) context.get(pkName);
-                }
-                currentNodeTrail.add(id);
-                treeStringRenderer.renderNodeBegin(writer, context, this, depth);
-                //if (Debug.infoOn()) Debug.logInfo(" context:" +
-                // context.entrySet(), module);
-                try {
-                    String screenName = null;
-                    if (screenNameExdr != null)
-                        screenName = screenNameExdr.expandString(context);
-                    String screenLocation = null;
-                    if (screenLocationExdr != null)
-                        screenLocation = screenLocationExdr.expandString(context);
-                    if (screenName != null && screenLocation != null) {
-                        ScreenStringRenderer screenStringRenderer = treeStringRenderer.getScreenStringRenderer(context);
-                        ModelScreen modelScreen = ScreenFactory.getScreenFromLocation(screenLocation, screenName);
-                        modelScreen.renderScreenString(writer, context, screenStringRenderer);
-                    }
-                    if (label != null) {
-                        label.renderLabelString(writer, context, treeStringRenderer);
-                    }
-                    if (link != null) {
-                        link.renderLinkString(writer, context, treeStringRenderer);
-                    }
-                    treeStringRenderer.renderLastElement(writer, context, this);
-                    Boolean processChildren = (Boolean) context.get("processChildren");
-                    //if (Debug.infoOn()) Debug.logInfo(" processChildren:" + processChildren, module);
-                    if (processChildren.booleanValue()) {
-                        getChildren(context);
-                        int newDepth = depth + 1;
-                        for (Object[] arr: this.subNodeValues) {
-                            ModelNode node = (ModelNode) arr[0];
-                            Map<String, Object> val = UtilGenerics.checkMap(arr[1]);
-                            //GenericPK pk = val.getPrimaryKey();
-                            //if (Debug.infoOn()) Debug.logInfo(" pk:" + pk,
-                            // module);
-                            String thisPkName = node.getPkName();
-                            String thisEntityId = (String) val.get(thisPkName);
-                            MapStack<String> newContext = MapStack.create(context);
-                            newContext.push();
-                            String nodeEntryName = node.getEntryName();
-                            if (UtilValidate.isNotEmpty(nodeEntryName)) {
-                                newContext.put(nodeEntryName, val);
-                            } else {
-                                newContext.putAll(val);
-                            }
-                            String targetEntityId = null;
-                            List<String> targetNodeTrail = UtilGenerics.checkList(context.get("targetNodeTrail"));
-                            if (newDepth < targetNodeTrail.size()) {
-                                targetEntityId = targetNodeTrail.get(newDepth);
-                            }
-                            if ((targetEntityId != null && targetEntityId.equals(thisEntityId)) || this.showPeers(newDepth, context)) {
-                                node.renderNodeString(writer, newContext, treeStringRenderer, newDepth);
-                            }
-                        }
-                    }
-                } catch (ScreenRenderException e) {
-                    String errMsg = "Error rendering included label with name ["
-                            + getName() + "] : " + e.toString();
-                    Debug.logError(e, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                } catch (SAXException e) {
-                    String errMsg = "Error rendering included label with name ["
-                            + getName() + "] : " + e.toString();
-                    Debug.logError(e, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                } catch (ParserConfigurationException e3) {
-                    String errMsg = "Error rendering included label with name ["
-                            + getName() + "] : " + e3.toString();
-                    Debug.logError(e3, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                } catch (IOException e2) {
-                    String errMsg = "Error rendering included label with name ["
-                            + getName() + "] : " + e2.toString();
-                    Debug.logError(e2, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                }
-                treeStringRenderer.renderNodeEnd(writer, context, this);
-                int removeIdx = currentNodeTrail.size() - 1;
-                if (removeIdx >= 0) currentNodeTrail.remove(removeIdx);
+            return subNodeValues;
+        }
+
+        public String getEntityName() {
+            if (!this.entityName.isEmpty()) {
+                return this.entityName;
+            } else {
+                return this.modelTree.getDefaultEntityName();
             }
         }
 
+        public String getEntryName() {
+            return this.entryName;
+        }
+
+        public String getExpandCollapseStyle() {
+            return expandCollapseStyle;
+        }
+
+        public ModelTree getModelTree() {
+            return this.modelTree;
+        }
+
+        public String getPkName(Map<String, Object> context) {
+            if (UtilValidate.isNotEmpty(this.pkName)) {
+                return this.pkName;
+            } else {
+                return this.modelTree.getDefaultPkName(context);
+            }
+        }
+
+        public String getRenderStyle() {
+            if (this.renderStyle.isEmpty())
+                return modelTree.getRenderStyle();
+            return this.renderStyle;
+        }
+
+        public String getWrapStyle(Map<String, Object> context) {
+            String val = this.wrapStyleExdr.expandString(context);
+            if (val.isEmpty()) {
+                val = this.modelTree.getWrapStyle(context);
+            }
+            return val;
+        }
+
         public boolean hasChildren(Map<String, Object> context) {
+            List<Object[]> subNodeValues = getChildren(context);
             boolean hasChildren = false;
             Long nodeCount = null;
             String countFieldName = "childBranchCount";
             Object obj = null;
-            if (UtilValidate.isNotEmpty(this.entryName)) {
+            if (!this.entryName.isEmpty()) {
                 Map<String, Object> map = UtilGenerics.cast(context.get(this.entryName));
                 if (map instanceof GenericValue) {
                     ModelEntity modelEntity = ((GenericValue) map).getModelEntity();
@@ -486,7 +456,7 @@
                 nodeCount = (Long) obj;
             }
             String entName = this.getEntityName();
-            Delegator delegator = modelTree.getDelegator();
+            Delegator delegator = WidgetWorker.getDelegator(context);
             ModelEntity modelEntity = delegator.getModelEntity(entName);
             ModelField modelField = null;
             if (modelEntity.isField(countFieldName)) {
@@ -509,17 +479,17 @@
                     }
                 }
                 */
-                nodeCount = Long.valueOf(this.subNodeValues.size());
-                String pkName = this.getPkName();
+                nodeCount = Long.valueOf(subNodeValues.size());
+                String pkName = this.getPkName(context);
                 String id = null;
-                if (UtilValidate.isNotEmpty(this.entryName)) {
-                    id = UtilGenerics.<Map<String,String>>cast(context.get(this.entryName)).get(pkName);
+                if (!this.entryName.isEmpty()) {
+                    id = UtilGenerics.<Map<String, String>> cast(context.get(this.entryName)).get(pkName);
                 } else {
                     id = (String) context.get(pkName);
                 }
                 try {
                     if (id != null && modelEntity.getPksSize() == 1) {
-                        GenericValue entity = delegator.findOne(entName, UtilMisc.toMap(pkName, id), false);
+                        GenericValue entity = EntityQuery.use(delegator).from(entName).where(pkName, id).queryOne();
                         if (modelEntity.isField("childBranchCount")) {
                             entity.put("childBranchCount", nodeCount);
                             entity.store();
@@ -535,64 +505,17 @@
                     nodeCount = Long.valueOf(subNodeValues.size());
                 }
             }
-
             if (nodeCount != null && nodeCount.intValue() > 0) {
                 hasChildren = true;
             }
-
             return hasChildren;
         }
 
-        public void getChildren(Map<String, Object> context) {
-             this.subNodeValues = new ArrayList<Object []>();
-             for (ModelSubNode subNode: subNodeList) {
-                 String nodeName = subNode.getNodeName(context);
-                 ModelNode node = modelTree.nodeMap.get(nodeName);
-                 List<ModelWidgetAction> subNodeActions = subNode.getActions();
-                 //if (Debug.infoOn()) Debug.logInfo(" context.currentValue:" + context.get("currentValue"), module);
-                 ModelWidgetAction.runSubActions(subNodeActions, context);
-                 // List dataFound = (List)context.get("dataFound");
-                 Iterator<? extends Map<String, ? extends Object>> dataIter =  subNode.getListIterator();
-                 if (dataIter instanceof EntityListIterator) {
-                     EntityListIterator eli = (EntityListIterator) dataIter;
-                     Map<String, Object> val = null;
-                     while ((val = eli.next()) != null) {
-                         Object [] arr = {node, val};
-                         this.subNodeValues.add(arr);
-                     }
-                     try {
-                         eli.close();
-                     } catch (GenericEntityException e) {
-                         Debug.logError(e, module);
-                         throw new RuntimeException(e.getMessage());
-                     }
-                 } else if (dataIter != null) {
-                     while (dataIter.hasNext()) {
-                         Map<String, ? extends Object> val = dataIter.next();
-                         Object [] arr = {node, val};
-                         this.subNodeValues.add(arr);
-                     }
-                 }
-             }
-        }
-
-        public String getEntryName() {
-            return this.entryName;
-        }
-
-        public String getRenderStyle() {
-            String rStyle = this.renderStyle;
-            if (UtilValidate.isEmpty(rStyle))
-                rStyle = modelTree.getRenderStyle();
-            return rStyle;
-        }
-
         public boolean isExpandCollapse() {
             boolean isExpCollapse = false;
             String rStyle = getRenderStyle();
             if (rStyle != null && rStyle.equals("expand-collapse"))
                 isExpCollapse = true;
-
             return isExpCollapse;
         }
 
@@ -602,7 +525,6 @@
             if (rStyle != null && (rStyle.equals("follow-trail") || rStyle.equals("show-peers") || rStyle.equals("follow-trail"))) {
                 isFollowTrail = true;
             }
-
             return isFollowTrail;
         }
 
@@ -610,12 +532,113 @@
             return getName().equals(modelTree.getRootNodeName());
         }
 
+        public void renderNodeString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer,
+                int depth) throws IOException, GeneralException {
+            boolean passed = true;
+            if (this.condition != null) {
+                if (!this.condition.eval(context)) {
+                    passed = false;
+                }
+            }
+            //Debug.logInfo("in ModelMenu, name:" + this.getName(), module);
+            if (passed) {
+                List<String> currentNodeTrail = UtilGenerics.toList(context.get("currentNodeTrail"));
+                context.put("processChildren", Boolean.TRUE);
+                // this action will usually obtain the "current" entity
+                ModelTreeAction.runSubActions(this.actions, context);
+                String pkName = getPkName(context);
+                String id = null;
+                if (!this.entryName.isEmpty()) {
+                    id = UtilGenerics.<Map<String, String>> cast(context.get(this.entryName)).get(pkName);
+                } else {
+                    id = (String) context.get(pkName);
+                }
+                currentNodeTrail.add(id);
+                treeStringRenderer.renderNodeBegin(writer, context, this, depth);
+                //if (Debug.infoOn()) Debug.logInfo(" context:" +
+                // context.entrySet(), module);
+                try {
+                    String screenName = null;
+                    if (!screenNameExdr.isEmpty())
+                        screenName = screenNameExdr.expandString(context);
+                    String screenLocation = null;
+                    if (!screenLocationExdr.isEmpty())
+                        screenLocation = screenLocationExdr.expandString(context);
+                    if (screenName != null && screenLocation != null) {
+                        ScreenStringRenderer screenStringRenderer = treeStringRenderer.getScreenStringRenderer(context);
+                        ModelScreen modelScreen = ScreenFactory.getScreenFromLocation(screenLocation, screenName);
+                        modelScreen.renderScreenString(writer, context, screenStringRenderer);
+                    }
+                    if (label != null) {
+                        label.renderLabelString(writer, context, treeStringRenderer);
+                    }
+                    if (link != null) {
+                        link.renderLinkString(writer, context, treeStringRenderer);
+                    }
+                    treeStringRenderer.renderLastElement(writer, context, this);
+                    Boolean processChildren = (Boolean) context.get("processChildren");
+                    //if (Debug.infoOn()) Debug.logInfo(" processChildren:" + processChildren, module);
+                    if (processChildren.booleanValue()) {
+                        List<Object[]> subNodeValues = getChildren(context);
+                        int newDepth = depth + 1;
+                        for (Object[] arr : subNodeValues) {
+                            ModelNode node = (ModelNode) arr[0];
+                            Map<String, Object> val = UtilGenerics.checkMap(arr[1]);
+                            //GenericPK pk = val.getPrimaryKey();
+                            //if (Debug.infoOn()) Debug.logInfo(" pk:" + pk,
+                            // module);
+                            String thisPkName = node.getPkName(context);
+                            String thisEntityId = (String) val.get(thisPkName);
+                            MapStack<String> newContext = MapStack.create(context);
+                            newContext.push();
+                            String nodeEntryName = node.getEntryName();
+                            if (!nodeEntryName.isEmpty()) {
+                                newContext.put(nodeEntryName, val);
+                            } else {
+                                newContext.putAll(val);
+                            }
+                            String targetEntityId = null;
+                            List<String> targetNodeTrail = UtilGenerics.checkList(context.get("targetNodeTrail"));
+                            if (newDepth < targetNodeTrail.size()) {
+                                targetEntityId = targetNodeTrail.get(newDepth);
+                            }
+                            if ((targetEntityId != null && targetEntityId.equals(thisEntityId))
+                                    || this.showPeers(newDepth, context)) {
+                                node.renderNodeString(writer, newContext, treeStringRenderer, newDepth);
+                            }
+                        }
+                    }
+                } catch (ScreenRenderException e) {
+                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e.toString();
+                    Debug.logError(e, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                } catch (SAXException e) {
+                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e.toString();
+                    Debug.logError(e, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                } catch (ParserConfigurationException e3) {
+                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e3.toString();
+                    Debug.logError(e3, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                } catch (IOException e2) {
+                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e2.toString();
+                    Debug.logError(e2, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                }
+                treeStringRenderer.renderNodeEnd(writer, context, this);
+                int removeIdx = currentNodeTrail.size() - 1;
+                if (removeIdx >= 0)
+                    currentNodeTrail.remove(removeIdx);
+            }
+        }
+
         public boolean showPeers(int currentDepth, Map<String, Object> context) {
             int trailSize = 0;
             List<?> trail = UtilGenerics.checkList(context.get("targetNodeTrail"));
             int openDepth = modelTree.getOpenDepth();
             int postTrailOpenDepth = modelTree.getPostTrailOpenDepth();
-            if (trail != null) trailSize = trail.size();
+            if (trail != null)
+                trailSize = trail.size();
 
             boolean showPeers = false;
             String rStyle = getRenderStyle();
@@ -623,92 +646,328 @@
                 showPeers = true;
             } else if (!isFollowTrail()) {
                 showPeers = true;
-            } else if ((currentDepth < trailSize) && (rStyle != null) &&  (rStyle.equals("show-peers") || rStyle.equals("expand-collapse"))) {
+            } else if ((currentDepth < trailSize) && (rStyle != null)
+                    && (rStyle.equals("show-peers") || rStyle.equals("expand-collapse"))) {
                 showPeers = true;
             } else if (openDepth >= currentDepth) {
                 showPeers = true;
             } else {
                 int depthAfterTrail = currentDepth - trailSize;
-                if (depthAfterTrail >= 0 && depthAfterTrail <= postTrailOpenDepth) showPeers = true;
+                if (depthAfterTrail >= 0 && depthAfterTrail <= postTrailOpenDepth)
+                    showPeers = true;
             }
-
             return showPeers;
         }
 
-        public String getExpandCollapseStyle() {
-            return expandCollapseStyle;
-        }
+        /**
+         * Models the &lt;image&gt; element.
+         * 
+         * @see <code>widget-tree.xsd</code>
+         */
+        public static class Image {
 
-        public String getWrapStyle(Map<String, Object> context) {
-            String val = this.wrapStyleExdr.expandString(context);
-            if (UtilValidate.isEmpty(val)) {
-                val = this.modelTree.getWrapStyle(context);
+            private final FlexibleStringExpander borderExdr;
+            private final FlexibleStringExpander heightExdr;
+            private final FlexibleStringExpander idExdr;
+            private final FlexibleStringExpander srcExdr;
+            private final FlexibleStringExpander styleExdr;
+            private final String urlMode;
+            private final FlexibleStringExpander widthExdr;
+
+            public Image(Element imageElement) {
+                this.borderExdr = FlexibleStringExpander
+                        .getInstance(UtilXml.checkEmpty(imageElement.getAttribute("border"), "0"));
+                this.heightExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("height"));
+                this.idExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("id"));
+                this.srcExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("src"));
+                this.styleExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("style"));
+                this.urlMode = UtilXml.checkEmpty(imageElement.getAttribute("url-mode"), "content");
+                this.widthExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("width"));
             }
-            return val;
-        }
 
-        public ModelTree getModelTree() {
-            return this.modelTree;
-        }
+            public String getBorder(Map<String, Object> context) {
+                return this.borderExdr.expandString(context);
+            }
 
-        public void setEntityName(String name) {
-            this.entityName = name;
-            if (UtilValidate.isNotEmpty(this.entityName)) {
-                ModelEntity modelEntity = modelTree.delegator.getModelEntity(this.entityName);
-                if (modelEntity.getPksSize() == 1) {
-                    ModelField modelField = modelEntity.getOnlyPk();
-                    this.pkName = modelField.getName();
-                } else {
-                    List<String> pkFieldsName = modelEntity.getPkFieldNames();
-                    StringBuilder sb = new StringBuilder();
-                    for (String pk: pkFieldsName) {
-                            sb.append(pk);
-                            sb.append("|");
-                    }
-                    this.pkName = sb.toString();
+            public String getHeight(Map<String, Object> context) {
+                return this.heightExdr.expandString(context);
+            }
+
+            public String getId(Map<String, Object> context) {
+                return this.idExdr.expandString(context);
+            }
+
+            public String getSrc(Map<String, Object> context) {
+                return this.srcExdr.expandString(context);
+            }
+
+            public String getStyle(Map<String, Object> context) {
+                return this.styleExdr.expandString(context);
+            }
+
+            public String getUrlMode() {
+                return this.urlMode;
+            }
+
+            public String getWidth(Map<String, Object> context) {
+                return this.widthExdr.expandString(context);
+            }
+
+            public void renderImageString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
+                try {
+                    treeStringRenderer.renderImage(writer, context, this);
+                } catch (IOException e) {
+                    String errMsg = "Error rendering image with id [" + getId(context) + "]: " + e.toString();
+                    Debug.logError(e, errMsg, module);
+                    throw new RuntimeException(errMsg);
                 }
             }
         }
 
-        public String getEntityName() {
-            if (UtilValidate.isNotEmpty(this.entityName)) {
-                return this.entityName;
-            } else {
-                return this.modelTree.getDefaultEntityName();
+        /**
+         * Models the &lt;label&gt; element.
+         * 
+         * @see <code>widget-tree.xsd</code>
+         */
+        public static final class Label {
+            private final FlexibleStringExpander idExdr;
+            private final FlexibleStringExpander styleExdr;
+            private final FlexibleStringExpander textExdr;
+
+            public Label(Element labelElement) {
+                String textAttr = labelElement.getAttribute("text");
+                String pcdata = UtilXml.checkEmpty(UtilXml.elementValue(labelElement), "");
+                this.textExdr = FlexibleStringExpander.getInstance(textAttr + pcdata);
+                this.idExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("id"));
+                this.styleExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("style"));
+            }
+
+            public String getId(Map<String, Object> context) {
+                return this.idExdr.expandString(context);
+            }
+
+            public String getStyle(Map<String, Object> context) {
+                return this.styleExdr.expandString(context);
+            }
+
+            public String getText(Map<String, Object> context) {
+                String text = this.textExdr.expandString(context);
+                // FIXME: Encoding should be done by the renderer, not by the model.
+                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+                if (simpleEncoder != null) {
+                    text = simpleEncoder.encode(text);
+                }
+                return text;
+            }
+
+            public void renderLabelString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
+                try {
+                    treeStringRenderer.renderLabel(writer, context, this);
+                } catch (IOException e) {
+                    String errMsg = "Error rendering label with id [" + getId(context) + "]: " + e.toString();
+                    Debug.logError(e, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                }
             }
         }
 
-        public String getPkName() {
-            if (UtilValidate.isNotEmpty(this.pkName)) {
-                return this.pkName;
-            } else {
-                return this.modelTree.getDefaultPkName();
+        /**
+         * Models the &lt;link&gt; element.
+         * 
+         * @see <code>widget-tree.xsd</code>
+         */
+        public static class Link {
+            private final boolean encode;
+            private final boolean fullPath;
+            private final FlexibleStringExpander idExdr;
+            private final Image image;
+            private final String linkType;
+            private final FlexibleStringExpander nameExdr;
+            private final List<Parameter> parameterList;
+            private final FlexibleStringExpander prefixExdr;
+            private final boolean secure;
+            private final FlexibleStringExpander styleExdr;
+            private final FlexibleStringExpander targetExdr;
+            private final FlexibleStringExpander targetWindowExdr;
+            private final FlexibleStringExpander textExdr;
+            private final FlexibleStringExpander titleExdr;
+            private final String urlMode;
+
+            public Link(Element linkElement) {
+                this.encode = "true".equals(linkElement.getAttribute("encode"));
+                this.fullPath = "true".equals(linkElement.getAttribute("full-path"));
+                this.idExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("id"));
+                Element imageElement = UtilXml.firstChildElement(linkElement, "image");
+                if (imageElement != null) {
+                    this.image = new Image(imageElement);
+                } else {
+                    this.image = null;
+                }
+                this.linkType = linkElement.getAttribute("link-type");
+                this.nameExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("name"));
+                List<? extends Element> parameterElementList = UtilXml.childElementList(linkElement, "parameter");
+                if (!parameterElementList.isEmpty()) {
+                    List<Parameter> parameterList = new ArrayList<Parameter>(parameterElementList.size());
+                    for (Element parameterElement : parameterElementList) {
+                        parameterList.add(new Parameter(parameterElement));
+                    }
+                    this.parameterList = Collections.unmodifiableList(parameterList);
+                } else {
+                    this.parameterList = Collections.emptyList();
+                }
+                this.prefixExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("prefix"));
+                this.secure = "true".equals(linkElement.getAttribute("secure"));
+                this.styleExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("style"));
+                this.targetExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target"));
+                this.targetWindowExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target-window"));
+                this.textExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("text"));
+                this.titleExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("title"));
+                this.urlMode = UtilXml.checkEmpty(linkElement.getAttribute("link-type"), "intra-app");
+            }
+
+            // FIXME: Using a widget model in this way is an ugly hack.
+            public Link(String style, String target, String text) {
+                this.encode = false;
+                this.fullPath = false;
+                this.idExdr = FlexibleStringExpander.getInstance("");
+                this.image = null;
+                this.linkType = "";
+                this.nameExdr = FlexibleStringExpander.getInstance("");
+                this.parameterList = Collections.emptyList();
+                this.prefixExdr = FlexibleStringExpander.getInstance("");
+                this.secure = false;
+                this.styleExdr = FlexibleStringExpander.getInstance(style);
+                this.targetExdr = FlexibleStringExpander.getInstance(target);
+                this.targetWindowExdr = FlexibleStringExpander.getInstance("");
+                this.textExdr = FlexibleStringExpander.getInstance(text);
+                this.titleExdr = FlexibleStringExpander.getInstance("");
+                this.urlMode = "intra-app";
+            }
+
+            public boolean getEncode() {
+                return this.encode;
+            }
+
+            public boolean getFullPath() {
+                return this.fullPath;
+            }
+
+            public String getId(Map<String, Object> context) {
+                return this.idExdr.expandString(context);
+            }
+
+            public Image getImage() {
+                return this.image;
+            }
+
+            public String getLinkType() {
+                return this.linkType;
+            }
+
+            public String getName(Map<String, Object> context) {
+                return this.nameExdr.expandString(context);
+            }
+
+            public Map<String, String> getParameterMap(Map<String, Object> context) {
+                Map<String, String> fullParameterMap = new HashMap<String, String>();
+                /* leaving this here... may want to add it at some point like the hyperlink element:
+                Map<String, String> addlParamMap = this.parametersMapAcsr.get(context);
+                if (addlParamMap != null) {
+                    fullParameterMap.putAll(addlParamMap);
+                }
+                */
+                for (WidgetWorker.Parameter parameter : this.parameterList) {
+                    fullParameterMap.put(parameter.getName(), parameter.getValue(context));
+                }
+                return fullParameterMap;
+            }
+
+            public String getPrefix(Map<String, Object> context) {
+                return this.prefixExdr.expandString(context);
+            }
+
+            public boolean getSecure() {
+                return this.secure;
+            }
+
+            public String getStyle(Map<String, Object> context) {
+                return this.styleExdr.expandString(context);
+            }
+
+            public String getTarget(Map<String, Object> context) {
+                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+                if (simpleEncoder != null) {
+                    return this.targetExdr.expandString(UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context,
+                            simpleEncoder));
+                } else {
+                    return this.targetExdr.expandString(context);
+                }
+            }
+
+            public String getTargetWindow(Map<String, Object> context) {
+                return this.targetWindowExdr.expandString(context);
+            }
+
+            public String getText(Map<String, Object> context) {
+                String text = this.textExdr.expandString(context);
+                // FIXME: Encoding should be done by the renderer, not by the model.
+                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+                if (simpleEncoder != null) {
+                    text = simpleEncoder.encode(text);
+                }
+                return text;
+            }
+
+            public String getTitle(Map<String, Object> context) {
+                String title = this.titleExdr.expandString(context);
+                // FIXME: Encoding should be done by the renderer, not by the model.
+                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+                if (simpleEncoder != null) {
+                    title = simpleEncoder.encode(title);
+                }
+                return title;
+            }
+
+            public String getUrlMode() {
+                return this.urlMode;
+            }
+
+            public void renderLinkString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
+                try {
+                    treeStringRenderer.renderLink(writer, context, this);
+                } catch (IOException e) {
+                    String errMsg = "Error rendering link with id [" + getId(context) + "]: " + e.toString();
+                    Debug.logError(e, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                }
             }
         }
 
-        public void setPkName(String pkName) {
-            this.pkName = pkName;
-        }
-
+        /**
+         * Models the &lt;sub-node&gt; element.
+         * 
+         * @see <code>widget-tree.xsd</code>
+         */
         public static class ModelSubNode extends ModelWidget {
 
             private final List<ModelWidgetAction> actions;
-            protected ModelNode rootNode;
-            protected FlexibleStringExpander nodeNameExdr;
-            protected ListIterator<? extends Map<String, ? extends Object>> listIterator;
+            private final FlexibleStringExpander nodeNameExdr;
+            private final ModelNode rootNode;
+            private final String iteratorKey;
 
             public ModelSubNode(Element subNodeElement, ModelNode modelNode) {
                 super(subNodeElement);
                 this.rootNode = modelNode;
                 this.nodeNameExdr = FlexibleStringExpander.getInstance(subNodeElement.getAttribute("node-name"));
                 ArrayList<ModelWidgetAction> actions = new ArrayList<ModelWidgetAction>();
+                // FIXME: Validate child elements, should be only one of actions, entity-and, entity-condition, service, script.
                 Element actionsElement = UtilXml.firstChildElement(subNodeElement, "actions");
                 if (actionsElement != null) {
-                    actions.addAll(ModelTreeAction.readNodeActions(this, actionsElement));
+                    actions.addAll(ModelTreeAction.readSubNodeActions(this, actionsElement));
                 }
                 Element actionElement = UtilXml.firstChildElement(subNodeElement, "entity-and");
                 if (actionElement != null) {
-                   actions.add(new ModelTreeAction.EntityAnd(this, actionElement));
+                    actions.add(new ModelTreeAction.EntityAnd(this, actionElement));
                 }
                 actionElement = UtilXml.firstChildElement(subNodeElement, "service");
                 if (actionElement != null) {
@@ -724,6 +983,22 @@
                 }
                 actions.trimToSize();
                 this.actions = Collections.unmodifiableList(actions);
+                this.iteratorKey = this.rootNode.getName().concat(".").concat(this.nodeNameExdr.getOriginal())
+                        .concat(".ITERATOR");
+            }
+
+            @Override
+            public void accept(ModelWidgetVisitor visitor) throws Exception {
+                visitor.visit(this);
+            }
+
+            public List<ModelWidgetAction> getActions() {
+                return actions;
+            }
+
+            @SuppressWarnings("unchecked")
+            public ListIterator<? extends Map<String, ? extends Object>> getListIterator(Map<String, Object> context) {
+                return (ListIterator<? extends Map<String, ? extends Object>>) context.get(this.iteratorKey);
             }
 
             public ModelTree.ModelNode getNode() {
@@ -734,389 +1009,9 @@
                 return this.nodeNameExdr.expandString(context);
             }
 
-            public List<ModelWidgetAction> getActions() {
-                return actions;
-            }
-
-            public void setListIterator(ListIterator<? extends Map<String, ? extends Object>> iter) {
-                listIterator = iter;
-            }
-
-            public ListIterator<? extends Map<String, ? extends Object>> getListIterator() {
-                return listIterator;
-            }
-
-            @Override
-            public void accept(ModelWidgetVisitor visitor) throws Exception {
-                visitor.visit(this);
+            public void setListIterator(ListIterator<? extends Map<String, ? extends Object>> iter, Map<String, Object> context) {
+                context.put(this.iteratorKey, iter);
             }
         }
-
-        public static class Label {
-            protected FlexibleStringExpander textExdr;
-
-            protected FlexibleStringExpander idExdr;
-            protected FlexibleStringExpander styleExdr;
-
-            public Label(Element labelElement) {
-
-                // put the text attribute first, then the pcdata under the element, if both are there of course
-                String textAttr = UtilFormatOut.checkNull(labelElement.getAttribute("text"));
-                String pcdata = UtilFormatOut.checkNull(UtilXml.elementValue(labelElement));
-                this.textExdr = FlexibleStringExpander.getInstance(textAttr + pcdata);
-
-                this.idExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("id"));
-                this.styleExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("style"));
-            }
-
-            public void renderLabelString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
-                try {
-                    treeStringRenderer.renderLabel(writer, context, this);
-                } catch (IOException e) {
-                    String errMsg = "Error rendering label with id [" + getId(context) + "]: " + e.toString();
-                    Debug.logError(e, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                }
-            }
-
-            public String getText(Map<String, Object> context) {
-                String text = this.textExdr.expandString(context);
-                StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
-                if (simpleEncoder != null) {
-                    text = simpleEncoder.encode(text);
-                }
-                return text;
-            }
-
-            public String getId(Map<String, Object> context) {
-                return this.idExdr.expandString(context);
-            }
-
-            public String getStyle(Map<String, Object> context) {
-                return this.styleExdr.expandString(context);
-            }
-        }
-
-
-        public static class Link {
-            protected FlexibleStringExpander textExdr;
-            protected FlexibleStringExpander idExdr;
-            protected FlexibleStringExpander styleExdr;
-            protected FlexibleStringExpander targetExdr;
-            protected FlexibleStringExpander targetWindowExdr;
-            protected FlexibleStringExpander prefixExdr;
-            protected FlexibleStringExpander nameExdr;
-            protected FlexibleStringExpander titleExdr;
-            protected Image image;
-            protected String urlMode = "intra-app";
-            protected boolean fullPath = false;
-            protected boolean secure = false;
-            protected boolean encode = false;
-            protected String linkType;
-            protected List<WidgetWorker.Parameter> parameterList = new ArrayList<WidgetWorker.Parameter>();
-
-            public Link() {
-                setText(null);
-                setId(null);
-                setStyle(null);
-                setTarget(null);
-                setTargetWindow(null);
-                setPrefix(null);
-                setUrlMode(null);
-                setFullPath(null);
-                setSecure(null);
-                setEncode(null);
-                setName(null);
-                setTitle(null);
-            }
-
-            public Link(Element linkElement) {
-
-                setText(linkElement.getAttribute("text"));
-                setId(linkElement.getAttribute("id"));
-                setStyle(linkElement.getAttribute("style"));
-                setTarget(linkElement.getAttribute("target"));
-                setTargetWindow(linkElement.getAttribute("target-window"));
-                setPrefix(linkElement.getAttribute("prefix"));
-                setUrlMode(linkElement.getAttribute("url-mode"));
-                setFullPath(linkElement.getAttribute("full-path"));
-                setSecure(linkElement.getAttribute("secure"));
-                setEncode(linkElement.getAttribute("encode"));
-                setName(linkElement.getAttribute("name"));
-                setTitle(linkElement.getAttribute("title"));
-                Element imageElement = UtilXml.firstChildElement(linkElement, "image");
-                if (imageElement != null) {
-                    this.image = new Image(imageElement);
-                }
-                this.linkType = linkElement.getAttribute("link-type");
-                List<? extends Element> parameterElementList = UtilXml.childElementList(linkElement, "parameter");
-                for (Element parameterElement: parameterElementList) {
-                    this.parameterList.add(new WidgetWorker.Parameter(parameterElement));
-                }
-            }
-
-            public void renderLinkString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
-                try {
-                    treeStringRenderer.renderLink(writer, context, this);
-                } catch (IOException e) {
-                    String errMsg = "Error rendering link with id [" + getId(context) + "]: " + e.toString();
-                    Debug.logError(e, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                }
-            }
-
-            public String getText(Map<String, Object> context) {
-                String text = this.textExdr.expandString(context);
-                StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
-                if (simpleEncoder != null) {
-                    text = simpleEncoder.encode(text);
-                }
-                return text;
-            }
-
-            public String getId(Map<String, Object> context) {
-                return this.idExdr.expandString(context);
-            }
-
-            public String getStyle(Map<String, Object> context) {
-                return this.styleExdr.expandString(context);
-            }
-
-            public String getName(Map<String, Object> context) {
-                return this.nameExdr.expandString(context);
-            }
-            public String getTitle(Map<String, Object> context) {
-                String title = this.titleExdr.expandString(context);
-                StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
-                if (simpleEncoder != null) {
-                    title = simpleEncoder.encode(title);
-                }
-                return title;
-            }
-
-            public String getTarget(Map<String, Object> context) {
-                StringUtil.SimpleEncoder simpleEncoder = (StringUtil.SimpleEncoder) context.get("simpleEncoder");
-                if (simpleEncoder != null) {
-                    return this.targetExdr.expandString(StringUtil.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder));
-                } else {
-                    return this.targetExdr.expandString(context);
-                }
-            }
-
-            public String getTargetWindow(Map<String, Object> context) {
-                return this.targetWindowExdr.expandString(context);
-            }
-
-            public String getUrlMode() {
-                return this.urlMode;
-            }
-
-            public String getPrefix(Map<String, Object> context) {
-                return this.prefixExdr.expandString(context);
-            }
-
-            public boolean getFullPath() {
-                return this.fullPath;
-            }
-
-            public boolean getSecure() {
-                return this.secure;
-            }
-
-            public boolean getEncode() {
-                return this.encode;
-            }
-
-            public Image getImage() {
-                return this.image;
-            }
-
-            public String getLinkType() {
-                return this.linkType;
-            }
-
-            public Map<String, String> getParameterMap(Map<String, Object> context) {
-                Map<String, String> fullParameterMap = new HashMap<String, String>();
-
-                /* leaving this here... may want to add it at some point like the hyperlink element:
-                Map<String, String> addlParamMap = this.parametersMapAcsr.get(context);
-                if (addlParamMap != null) {
-                    fullParameterMap.putAll(addlParamMap);
-                }
-                */
-                
-                for (WidgetWorker.Parameter parameter: this.parameterList) {
-                    fullParameterMap.put(parameter.getName(), parameter.getValue(context));
-                }
-                
-                return fullParameterMap;
-            }
-
-            public void setText(String val) {
-                String textAttr = UtilFormatOut.checkNull(val);
-                this.textExdr = FlexibleStringExpander.getInstance(textAttr);
-            }
-            public void setId(String val) {
-                this.idExdr = FlexibleStringExpander.getInstance(val);
-            }
-            public void setStyle(String val) {
-                this.styleExdr = FlexibleStringExpander.getInstance(val);
-            }
-            public void setName(String val) {
-                this.nameExdr = FlexibleStringExpander.getInstance(val);
-            }
-            public void setTitle(String val) {
-                this.titleExdr = FlexibleStringExpander.getInstance(val);
-            }
-            public void setTarget(String val) {
-                this.targetExdr = FlexibleStringExpander.getInstance(val);
-            }
-            public void setTargetWindow(String val) {
-                this.targetWindowExdr = FlexibleStringExpander.getInstance(val);
-            }
-            public void setPrefix(String val) {
-                this.prefixExdr = FlexibleStringExpander.getInstance(val);
-            }
-            public void setUrlMode(String val) {
-                if (UtilValidate.isNotEmpty(val))
-                    this.urlMode = val;
-            }
-            public void setFullPath(String val) {
-                String sFullPath = val;
-                if (sFullPath != null && sFullPath.equalsIgnoreCase("true"))
-                    this.fullPath = true;
-                else
-                    this.fullPath = false;
-            }
-
-            public void setSecure(String val) {
-                String sSecure = val;
-                if (sSecure != null && sSecure.equalsIgnoreCase("true"))
-                    this.secure = true;
-                else
-                    this.secure = false;
-            }
-
-            public void setEncode(String val) {
-                String sEncode = val;
-                if (sEncode != null && sEncode.equalsIgnoreCase("true"))
-                    this.encode = true;
-                else
-                    this.encode = false;
-            }
-            public void setImage(Image img) {
-                this.image = img;
-            }
-
-        }
-
-        public static class Image {
-
-            protected FlexibleStringExpander srcExdr;
-            protected FlexibleStringExpander idExdr;
-            protected FlexibleStringExpander styleExdr;
-            protected FlexibleStringExpander widthExdr;
-            protected FlexibleStringExpander heightExdr;
-            protected FlexibleStringExpander borderExdr;
-            protected String urlMode;
-
-            public Image() {
-
-                setSrc(null);
-                setId(null);
-                setStyle(null);
-                setWidth(null);
-                setHeight(null);
-                setBorder("0");
-                setUrlMode(null);
-            }
-
-            public Image(Element imageElement) {
-
-                setSrc(imageElement.getAttribute("src"));
-                setId(imageElement.getAttribute("id"));
-                setStyle(imageElement.getAttribute("style"));
-                setWidth(imageElement.getAttribute("width"));
-                setHeight(imageElement.getAttribute("height"));
-                setBorder(UtilFormatOut.checkEmpty(imageElement.getAttribute("border"), "0"));
-                setUrlMode(UtilFormatOut.checkEmpty(imageElement.getAttribute("url-mode"), "content"));
-
-            }
-
-            public void renderImageString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
-                try {
-                    treeStringRenderer.renderImage(writer, context, this);
-                } catch (IOException e) {
-                    String errMsg = "Error rendering image with id [" + getId(context) + "]: " + e.toString();
-                    Debug.logError(e, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                }
-            }
-
-            public String getSrc(Map<String, Object> context) {
-                return this.srcExdr.expandString(context);
-            }
-
-            public String getId(Map<String, Object> context) {
-                return this.idExdr.expandString(context);
-            }
-
-            public String getStyle(Map<String, Object> context) {
-                return this.styleExdr.expandString(context);
-            }
-
-            public String getWidth(Map<String, Object> context) {
-                return this.widthExdr.expandString(context);
-            }
-
-            public String getHeight(Map<String, Object> context) {
-                return this.heightExdr.expandString(context);
-            }
-
-            public String getBorder(Map<String, Object> context) {
-                return this.borderExdr.expandString(context);
-            }
-
-            public String getUrlMode() {
-                return this.urlMode;
-            }
-
-            public void setSrc(String val) {
-                String textAttr = UtilFormatOut.checkNull(val);
-                this.srcExdr = FlexibleStringExpander.getInstance(textAttr);
-            }
-            public void setId(String val) {
-                this.idExdr = FlexibleStringExpander.getInstance(val);
-            }
-            public void setStyle(String val) {
-                this.styleExdr = FlexibleStringExpander.getInstance(val);
-            }
-            public void setWidth(String val) {
-                this.widthExdr = FlexibleStringExpander.getInstance(val);
-            }
-            public void setHeight(String val) {
-                this.heightExdr = FlexibleStringExpander.getInstance(val);
-            }
-            public void setBorder(String val) {
-                this.borderExdr = FlexibleStringExpander.getInstance(val);
-            }
-            public void setUrlMode(String val) {
-                if (UtilValidate.isEmpty(val)) {
-                    this.urlMode = "content";
-                } else {
-                    this.urlMode = val;
-                }
-            }
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-    }
-
-    @Override
-    public void accept(ModelWidgetVisitor visitor) throws Exception {
-        visitor.visit(this);
     }
 }
diff --git a/framework/widget/src/org/ofbiz/widget/tree/ModelTreeAction.java b/framework/widget/src/org/ofbiz/widget/tree/ModelTreeAction.java
index a041deb..23a9b98 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/ModelTreeAction.java
+++ b/framework/widget/src/org/ofbiz/widget/tree/ModelTreeAction.java
@@ -45,63 +45,250 @@
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.ModelService;
 import org.ofbiz.widget.ModelActionVisitor;
-import org.ofbiz.widget.ModelWidget;
 import org.ofbiz.widget.ModelWidgetAction;
 import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.tree.ModelTree.ModelNode;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 /**
- * Widget Library - Tree model class
+ * Abstract tree action.
  */
 @SuppressWarnings("serial")
 public abstract class ModelTreeAction extends ModelWidgetAction {
 
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     DEVELOPERS PLEASE READ
+     * ----------------------------------------------------------------------- *
+     * 
+     * This model is intended to be a read-only data structure that represents
+     * an XML element. Outside of object construction, the class should not
+     * have any behaviors.
+     * 
+     * Instances of this class will be shared by multiple threads - therefore
+     * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME!
+     * 
+     */
+
     public static final String module = ModelTreeAction.class.getName();
 
-    protected ModelTree modelTree;
-    protected ModelTree.ModelNode.ModelSubNode modelSubNode;
-
-    public ModelTreeAction(ModelTree.ModelNode modelNode, Element actionElement) {
-        if (Debug.verboseOn()) Debug.logVerbose("Reading Tree action with name: " + actionElement.getNodeName(), module);
-        this.modelTree = modelNode.getModelTree();
-    }
-
-    public ModelTreeAction(ModelTree.ModelNode.ModelSubNode modelSubNode, Element actionElement) {
-        if (Debug.verboseOn()) Debug.logVerbose("Reading Tree action with name: " + actionElement.getNodeName(), module);
-        this.modelSubNode = modelSubNode;
-        this.modelTree = modelSubNode.getNode().getModelTree();
-    }
-
-    public static List<ModelWidgetAction> readNodeActions(ModelWidget modelNode, Element actionsElement) {
+    public static List<ModelWidgetAction> readNodeActions(ModelNode modelNode, Element actionsElement) {
         List<? extends Element> actionElementList = UtilXml.childElementList(actionsElement);
         List<ModelWidgetAction> actions = new ArrayList<ModelWidgetAction>(actionElementList.size());
         for (Element actionElement : actionElementList) {
-            // TODO: Check for tree-specific actions
-            actions.add(ModelWidgetAction.toModelWidgetAction(modelNode, actionElement));
+            if ("service".equals(actionElement.getNodeName())) {
+                actions.add(new Service(modelNode, actionElement));
+            } else if ("script".equals(actionElement.getNodeName())) {
+                actions.add(new Script(modelNode, actionElement));
+            } else {
+                actions.add(ModelWidgetAction.newInstance(modelNode, actionElement));
+            }
         }
         return actions;
     }
 
-    public static class Script extends ModelTreeAction {
-        protected String location;
-        protected String method;
+    public static List<ModelWidgetAction> readSubNodeActions(ModelNode.ModelSubNode modelSubNode, Element actionsElement) {
+        List<? extends Element> actionElementList = UtilXml.childElementList(actionsElement);
+        List<ModelWidgetAction> actions = new ArrayList<ModelWidgetAction>(actionElementList.size());
+        for (Element actionElement : actionElementList) {
+            if ("service".equals(actionElement.getNodeName())) {
+                actions.add(new Service(modelSubNode, actionElement));
+            } else if ("entity-and".equals(actionElement.getNodeName())) {
+                actions.add(new EntityAnd(modelSubNode, actionElement));
+            } else if ("entity-condition".equals(actionElement.getNodeName())) {
+                actions.add(new EntityCondition(modelSubNode, actionElement));
+            } else if ("script".equals(actionElement.getNodeName())) {
+                actions.add(new Script(modelSubNode, actionElement));
+            } else {
+                actions.add(ModelWidgetAction.newInstance(modelSubNode, actionElement));
+            }
+        }
+        return actions;
+    }
 
-        public Script(ModelTree.ModelNode modelNode, Element scriptElement) {
-            super (modelNode, scriptElement);
+    private final ModelNode.ModelSubNode modelSubNode;
+    private final ModelTree modelTree;
+
+    protected ModelTreeAction(ModelNode modelNode, Element actionElement) {
+        if (Debug.verboseOn())
+            Debug.logVerbose("Reading Tree action with name: " + actionElement.getNodeName(), module);
+        this.modelTree = modelNode.getModelTree();
+        this.modelSubNode = null;
+    }
+
+    protected ModelTreeAction(ModelNode.ModelSubNode modelSubNode, Element actionElement) {
+        if (Debug.verboseOn())
+            Debug.logVerbose("Reading Tree action with name: " + actionElement.getNodeName(), module);
+        this.modelSubNode = modelSubNode;
+        this.modelTree = modelSubNode.getNode().getModelTree();
+    }
+
+    public ModelNode.ModelSubNode getModelSubNode() {
+        return modelSubNode;
+    }
+
+    public ModelTree getModelTree() {
+        return modelTree;
+    }
+
+    /**
+     * Models the &lt;entity-and&gt; element.
+     * 
+     * @see <code>widget-tree.xsd</code>
+     */
+    public static class EntityAnd extends ModelTreeAction {
+        private final ByAndFinder finder;
+        private final String listName;
+
+        public EntityAnd(ModelNode.ModelSubNode modelSubNode, Element entityAndElement) {
+            super(modelSubNode, entityAndElement);
+            boolean useCache = "true".equalsIgnoreCase(entityAndElement.getAttribute("use-cache"));
+            Document ownerDoc = entityAndElement.getOwnerDocument();
+            if (!useCache)
+                UtilXml.addChildElement(entityAndElement, "use-iterator", ownerDoc);
+            String listName = UtilFormatOut.checkEmpty(entityAndElement.getAttribute("list"),
+                    entityAndElement.getAttribute("list-name"));
+            if (UtilValidate.isEmpty(listName))
+                listName = "_LIST_ITERATOR_";
+            this.listName = listName;
+            entityAndElement.setAttribute("list-name", this.listName);
+            finder = new ByAndFinder(entityAndElement);
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        public ByAndFinder getFinder() {
+            return finder;
+        }
+
+        public String getListName() {
+            return listName;
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            try {
+                context.put(this.listName, null);
+                finder.runFind(context, WidgetWorker.getDelegator(context));
+                Object obj = context.get(this.listName);
+                if (obj != null && (obj instanceof EntityListIterator || obj instanceof ListIterator<?>)) {
+                    ListIterator<? extends Map<String, ? extends Object>> listIt = UtilGenerics.cast(obj);
+                    this.getModelSubNode().setListIterator(listIt, context);
+                } else {
+                    if (obj instanceof List<?>) {
+                        List<? extends Map<String, ? extends Object>> list = UtilGenerics.checkList(obj);
+                        this.getModelSubNode().setListIterator(list.listIterator(), context);
+                    }
+                }
+            } catch (GeneralException e) {
+                String errMsg = "Error doing entity query by condition: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new IllegalArgumentException(errMsg);
+            }
+        }
+    }
+
+    /**
+     * Models the &lt;entity-condition&gt; element.
+     * 
+     * @see <code>widget-tree.xsd</code>
+     */
+    public static class EntityCondition extends ModelTreeAction {
+        private final ByConditionFinder finder;
+        private final String listName;
+
+        public EntityCondition(ModelNode.ModelSubNode modelSubNode, Element entityConditionElement) {
+            super(modelSubNode, entityConditionElement);
+            Document ownerDoc = entityConditionElement.getOwnerDocument();
+            boolean useCache = "true".equalsIgnoreCase(entityConditionElement.getAttribute("use-cache"));
+            if (!useCache)
+                UtilXml.addChildElement(entityConditionElement, "use-iterator", ownerDoc);
+            String listName = UtilFormatOut.checkEmpty(entityConditionElement.getAttribute("list"),
+                    entityConditionElement.getAttribute("list-name"));
+            if (UtilValidate.isEmpty(listName))
+                listName = "_LIST_ITERATOR_";
+            this.listName = listName;
+            entityConditionElement.setAttribute("list-name", this.listName);
+            finder = new ByConditionFinder(entityConditionElement);
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        public ByConditionFinder getFinder() {
+            return finder;
+        }
+
+        public String getListName() {
+            return listName;
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            try {
+                context.put(this.listName, null);
+                finder.runFind(context, WidgetWorker.getDelegator(context));
+                Object obj = context.get(this.listName);
+                if (obj != null && (obj instanceof EntityListIterator || obj instanceof ListIterator<?>)) {
+                    ListIterator<? extends Map<String, ? extends Object>> listIt = UtilGenerics.cast(obj);
+                    this.getModelSubNode().setListIterator(listIt, context);
+                } else {
+                    if (obj instanceof List<?>) {
+                        List<? extends Map<String, ? extends Object>> list = UtilGenerics.cast(obj);
+                        this.getModelSubNode().setListIterator(list.listIterator(), context);
+                    }
+                }
+            } catch (GeneralException e) {
+                String errMsg = "Error doing entity query by condition: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new IllegalArgumentException(errMsg);
+            }
+        }
+    }
+
+    /**
+     * Models the &lt;script&gt; element.
+     * 
+     * @see <code>widget-tree.xsd</code>
+     */
+    public static class Script extends ModelTreeAction {
+        private final String location;
+        private final String method;
+
+        public Script(ModelNode modelNode, Element scriptElement) {
+            super(modelNode, scriptElement);
             String scriptLocation = scriptElement.getAttribute("location");
             this.location = WidgetWorker.getScriptLocation(scriptLocation);
             this.method = WidgetWorker.getScriptMethodName(scriptLocation);
         }
 
-        public Script(ModelTree.ModelNode.ModelSubNode modelSubNode, Element scriptElement) {
-            super (modelSubNode, scriptElement);
+        public Script(ModelNode.ModelSubNode modelSubNode, Element scriptElement) {
+            super(modelSubNode, scriptElement);
             String scriptLocation = scriptElement.getAttribute("location");
             this.location = WidgetWorker.getScriptLocation(scriptLocation);
             this.method = WidgetWorker.getScriptMethodName(scriptLocation);
         }
 
         @Override
+        public void accept(ModelActionVisitor visitor) {
+            visitor.visit(this);
+        }
+
+        public String getLocation() {
+            return location;
+        }
+
+        public String getMethod() {
+            return method;
+        }
+
+        @Override
         public void runAction(Map<String, Object> context) {
             context.put("_LIST_ITERATOR_", null);
             if (location.endsWith(".xml")) {
@@ -119,58 +306,87 @@
                 ScriptUtil.executeScript(this.location, this.method, context);
             }
             Object obj = context.get("_LIST_ITERATOR_");
-            if (this.modelSubNode != null) {
+            if (this.getModelSubNode() != null) {
                 if (obj != null && (obj instanceof EntityListIterator || obj instanceof ListIterator<?>)) {
                     ListIterator<? extends Map<String, ? extends Object>> listIt = UtilGenerics.cast(obj);
-                    this.modelSubNode.setListIterator(listIt);
+                    this.getModelSubNode().setListIterator(listIt, context);
                 } else {
                     if (obj instanceof List<?>) {
                         List<? extends Map<String, ? extends Object>> list = UtilGenerics.checkList(obj);
-                        this.modelSubNode.setListIterator(list.listIterator());
+                        this.getModelSubNode().setListIterator(list.listIterator(), context);
                     }
                 }
             }
         }
+    }
+
+    /**
+     * Models the &lt;service&gt; element.
+     * 
+     * @see <code>widget-tree.xsd</code>
+     */
+    public static class Service extends ModelTreeAction {
+        private final FlexibleStringExpander autoFieldMapExdr;
+        private final Map<FlexibleMapAccessor<Object>, Object> fieldMap;
+        private final FlexibleStringExpander resultMapListNameExdr;
+        private final FlexibleMapAccessor<Map<String, Object>> resultMapNameAcsr;
+        private final FlexibleStringExpander resultMapValueNameExdr;
+        private final FlexibleStringExpander serviceNameExdr;
+        private final FlexibleStringExpander valueNameExdr;
+
+        public Service(ModelNode modelNode, Element serviceElement) {
+            super(modelNode, serviceElement);
+            this.serviceNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
+            this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
+            this.autoFieldMapExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
+            this.resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list"));
+            this.resultMapValueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-value"));
+            this.valueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("value"));
+            this.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement);
+        }
+
+        public Service(ModelNode.ModelSubNode modelSubNode, Element serviceElement) {
+            super(modelSubNode, serviceElement);
+            this.serviceNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
+            this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
+            this.autoFieldMapExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
+            this.resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list"));
+            this.resultMapValueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-value"));
+            this.valueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("value"));
+            this.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement);
+        }
 
         @Override
         public void accept(ModelActionVisitor visitor) {
             visitor.visit(this);
         }
-    }
 
-    public static class Service extends ModelTreeAction {
-        protected FlexibleStringExpander serviceNameExdr;
-        protected FlexibleMapAccessor<Map<String, Object>> resultMapNameAcsr;
-        protected FlexibleStringExpander autoFieldMapExdr;
-        protected FlexibleStringExpander resultMapListNameExdr;
-        protected FlexibleStringExpander resultMapValueNameExdr;
-        protected FlexibleStringExpander valueNameExdr;
-        protected Map<FlexibleMapAccessor<Object>, Object> fieldMap;
-
-        public Service(ModelTree.ModelNode modelNode, Element serviceElement) {
-            super (modelNode, serviceElement);
-            initService(serviceElement);
+        public FlexibleStringExpander getAutoFieldMapExdr() {
+            return autoFieldMapExdr;
         }
 
-        public Service(ModelTree.ModelNode.ModelSubNode modelSubNode, Element serviceElement) {
-            super (modelSubNode, serviceElement);
-            initService(serviceElement);
+        public Map<FlexibleMapAccessor<Object>, Object> getFieldMap() {
+            return fieldMap;
         }
 
-        public void initService(Element serviceElement) {
+        public FlexibleStringExpander getResultMapListNameExdr() {
+            return resultMapListNameExdr;
+        }
 
-            this.serviceNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
-            this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
-            if (this.resultMapNameAcsr.isEmpty()) this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map-name"));
-            this.autoFieldMapExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
-            this.resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list"));
-            if (this.resultMapListNameExdr.isEmpty()) this.resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list-name"));
-            if (this.resultMapListNameExdr.isEmpty()) this.resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list-iterator-name"));
-            this.resultMapValueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-value"));
-            if (this.resultMapValueNameExdr.isEmpty()) this.resultMapValueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-value-name"));
-            this.valueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("value"));
-            if (this.valueNameExdr.isEmpty()) this.valueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("value-name"));
-            this.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement);
+        public FlexibleMapAccessor<Map<String, Object>> getResultMapNameAcsr() {
+            return resultMapNameAcsr;
+        }
+
+        public FlexibleStringExpander getResultMapValueNameExdr() {
+            return resultMapValueNameExdr;
+        }
+
+        public FlexibleStringExpander getServiceNameExdr() {
+            return serviceNameExdr;
+        }
+
+        public FlexibleStringExpander getValueNameExdr() {
+            return valueNameExdr;
         }
 
         @Override
@@ -179,27 +395,23 @@
             if (UtilValidate.isEmpty(serviceNameExpanded)) {
                 throw new IllegalArgumentException("Service name was empty, expanded from: " + this.serviceNameExdr.getOriginal());
             }
-
             String autoFieldMapString = this.autoFieldMapExdr.expandString(context);
             boolean autoFieldMapBool = !"false".equals(autoFieldMapString);
-
             try {
                 Map<String, Object> serviceContext = null;
                 if (autoFieldMapBool) {
-                    serviceContext = this.modelTree.getDispatcher().getDispatchContext().makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, context);
+                    serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext()
+                            .makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, context);
                 } else {
                     serviceContext = new HashMap<String, Object>();
                 }
-
                 if (this.fieldMap != null) {
                     EntityFinderUtil.expandFieldMapToContext(this.fieldMap, context, serviceContext);
                 }
-
-                Map<String, Object> result = this.modelTree.getDispatcher().runSync(serviceNameExpanded, 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");
+                    String queryString = (String) result.get("queryString");
                     context.put("queryString", queryString);
                     context.put("queryStringMap", result.get("queryStringMap"));
                     if (UtilValidate.isNotEmpty(queryString)) {
@@ -217,17 +429,16 @@
                 //String resultMapListIteratorName = resultMapListIteratorNameExdr.expandString(context);
                 String resultMapValueName = resultMapValueNameExdr.expandString(context);
                 String valueName = valueNameExdr.expandString(context);
-
-                if (this.modelSubNode != null) {
+                if (this.getModelSubNode() != null) {
                     //ListIterator iter = null;
                     if (UtilValidate.isNotEmpty(resultMapListName)) {
                         List<? extends Map<String, ? extends Object>> lst = UtilGenerics.checkList(result.get(resultMapListName));
                         if (lst != null) {
                             if (lst instanceof ListIterator<?>) {
                                 ListIterator<? extends Map<String, ? extends Object>> listIt = UtilGenerics.cast(lst);
-                                this.modelSubNode.setListIterator(listIt);
+                                this.getModelSubNode().setListIterator(listIt, context);
                             } else {
-                                this.modelSubNode.setListIterator(lst.listIterator());
+                                this.getModelSubNode().setListIterator(lst.listIterator(), context);
                             }
                         }
                     }
@@ -247,100 +458,5 @@
                 throw new IllegalArgumentException(errMsg);
             }
         }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-    }
-
-    public static class EntityAnd extends ModelTreeAction {
-        protected ByAndFinder finder;
-        String listName;
-
-        public EntityAnd(ModelTree.ModelNode.ModelSubNode modelSubNode, Element entityAndElement) {
-            super (modelSubNode, entityAndElement);
-            boolean useCache = "true".equalsIgnoreCase(entityAndElement.getAttribute("use-cache"));
-            Document ownerDoc = entityAndElement.getOwnerDocument();
-            if (!useCache) UtilXml.addChildElement(entityAndElement, "use-iterator", ownerDoc);
-
-            this.listName = UtilFormatOut.checkEmpty(entityAndElement.getAttribute("list"), entityAndElement.getAttribute("list-name"));
-            if (UtilValidate.isEmpty(this.listName)) this.listName = "_LIST_ITERATOR_";
-            entityAndElement.setAttribute("list-name", this.listName);
-
-            finder = new ByAndFinder(entityAndElement);
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            try {
-                context.put(this.listName, null);
-                finder.runFind(context, this.modelTree.getDelegator());
-                Object obj = context.get(this.listName);
-                if (obj != null && (obj instanceof EntityListIterator || obj instanceof ListIterator<?>)) {
-                    ListIterator<? extends Map<String, ? extends Object>> listIt = UtilGenerics.cast(obj);
-                    this.modelSubNode.setListIterator(listIt);
-                } else {
-                    if (obj instanceof List<?>) {
-                        List<? extends Map<String, ? extends Object>> list = UtilGenerics.checkList(obj);
-                        this.modelSubNode.setListIterator(list.listIterator());
-                    }
-                }
-            } catch (GeneralException e) {
-                String errMsg = "Error doing entity query by condition: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-    }
-
-    public static class EntityCondition extends ModelTreeAction {
-        ByConditionFinder finder;
-        String listName;
-
-        public EntityCondition(ModelTree.ModelNode.ModelSubNode modelSubNode, Element entityConditionElement) {
-            super (modelSubNode, entityConditionElement);
-            Document ownerDoc = entityConditionElement.getOwnerDocument();
-            boolean useCache = "true".equalsIgnoreCase(entityConditionElement.getAttribute("use-cache"));
-            if (!useCache) UtilXml.addChildElement(entityConditionElement, "use-iterator", ownerDoc);
-
-            this.listName = UtilFormatOut.checkEmpty(entityConditionElement.getAttribute("list"), entityConditionElement.getAttribute("list-name"));
-            if (UtilValidate.isEmpty(this.listName)) this.listName = "_LIST_ITERATOR_";
-            entityConditionElement.setAttribute("list-name", this.listName);
-
-            finder = new ByConditionFinder(entityConditionElement);
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            try {
-                context.put(this.listName, null);
-                finder.runFind(context, this.modelTree.getDelegator());
-                Object obj = context.get(this.listName);
-                if (obj != null && (obj instanceof EntityListIterator || obj instanceof ListIterator<?>)) {
-                    ListIterator<? extends Map<String, ? extends Object>> listIt = UtilGenerics.cast(obj);
-                    this.modelSubNode.setListIterator(listIt);
-                } else {
-                    if (obj instanceof List<?>) {
-                        List<? extends Map<String, ? extends Object>> list = UtilGenerics.cast(obj);
-                        this.modelSubNode.setListIterator(list.listIterator());
-                    }
-                }
-            } catch (GeneralException e) {
-                String errMsg = "Error doing entity query by condition: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
     }
 }
diff --git a/framework/widget/src/org/ofbiz/widget/tree/ModelTreeCondition.java b/framework/widget/src/org/ofbiz/widget/tree/ModelTreeCondition.java
index bb420a1..bf2db5b 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/ModelTreeCondition.java
+++ b/framework/widget/src/org/ofbiz/widget/tree/ModelTreeCondition.java
@@ -18,447 +18,19 @@
  *******************************************************************************/
 package org.ofbiz.widget.tree;
 
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TimeZone;
-
-import org.apache.oro.text.regex.MalformedPatternException;
-import org.apache.oro.text.regex.Pattern;
-import org.apache.oro.text.regex.PatternMatcher;
-import org.apache.oro.text.regex.Perl5Matcher;
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.ObjectType;
-import org.ofbiz.base.util.PatternFactory;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.collections.FlexibleMapAccessor;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.entityext.permission.EntityPermissionChecker;
-import org.ofbiz.minilang.operation.BaseCompare;
-import org.ofbiz.security.Security;
+import org.ofbiz.widget.ModelWidgetCondition;
 import org.w3c.dom.Element;
 
 /**
- * Widget Library - Screen model condition class
+ * Models the &lt;condition&gt; element.
+ * 
+ * @see <code>widget-tree.xsd</code>
  */
-public class ModelTreeCondition {
+@SuppressWarnings("serial")
+public class ModelTreeCondition extends ModelWidgetCondition {
     public static final String module = ModelTreeCondition.class.getName();
 
-    protected ModelTree modelTree;
-    protected TreeCondition rootCondition;
-
     public ModelTreeCondition(ModelTree modelTree, Element conditionElement) {
-        this.modelTree = modelTree;
-        Element firstChildElement = UtilXml.firstChildElement(conditionElement);
-        this.rootCondition = readCondition(modelTree, firstChildElement);
-    }
-
-    public boolean eval(Map<String, ? extends Object> context) {
-        if (rootCondition == null) {
-            return true;
-        }
-        return rootCondition.eval(context);
-    }
-
-    public static abstract class TreeCondition {
-        protected ModelTree modelTree;
-
-        public TreeCondition(ModelTree modelTree, Element conditionElement) {
-            this.modelTree = modelTree;
-        }
-
-        public abstract boolean eval(Map<String, ? extends Object> context);
-    }
-
-    public static List<TreeCondition> readSubConditions(ModelTree modelTree, Element conditionElement) {
-        List<TreeCondition> condList = new ArrayList<TreeCondition>();
-        for (Element subElement: UtilXml.childElementList(conditionElement)) {
-            condList.add(readCondition(modelTree, subElement));
-        }
-        return condList;
-    }
-
-    public static TreeCondition readCondition(ModelTree modelTree, Element conditionElement) {
-        if (conditionElement == null) {
-            return null;
-        }
-        if ("and".equals(conditionElement.getNodeName())) {
-            return new And(modelTree, conditionElement);
-        } else if ("xor".equals(conditionElement.getNodeName())) {
-            return new Xor(modelTree, conditionElement);
-        } else if ("or".equals(conditionElement.getNodeName())) {
-            return new Or(modelTree, conditionElement);
-        } else if ("not".equals(conditionElement.getNodeName())) {
-            return new Not(modelTree, conditionElement);
-        } else if ("if-has-permission".equals(conditionElement.getNodeName())) {
-            return new IfHasPermission(modelTree, conditionElement);
-        } else if ("if-validate-method".equals(conditionElement.getNodeName())) {
-            return new IfValidateMethod(modelTree, conditionElement);
-        } else if ("if-compare".equals(conditionElement.getNodeName())) {
-            return new IfCompare(modelTree, conditionElement);
-        } else if ("if-compare-field".equals(conditionElement.getNodeName())) {
-            return new IfCompareField(modelTree, conditionElement);
-        } else if ("if-regexp".equals(conditionElement.getNodeName())) {
-            return new IfRegexp(modelTree, conditionElement);
-        } else if ("if-empty".equals(conditionElement.getNodeName())) {
-            return new IfEmpty(modelTree, conditionElement);
-        } else if ("if-entity-permission".equals(conditionElement.getNodeName())) {
-            return new IfEntityPermission(modelTree, conditionElement);
-        } else {
-            throw new IllegalArgumentException("Condition element not supported with name: " + conditionElement.getNodeName());
-        }
-    }
-
-    public static class And extends TreeCondition {
-        protected List<? extends TreeCondition> subConditions;
-
-        public And(ModelTree modelTree, Element condElement) {
-            super (modelTree, condElement);
-            this.subConditions = readSubConditions(modelTree, condElement);
-        }
-
-        @Override
-        public boolean eval(Map<String, ? extends Object> context) {
-            // return false for the first one in the list that is false, basic and algo
-            for (TreeCondition subCondition: subConditions) {
-                if (!subCondition.eval(context)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-
-    public static class Xor extends TreeCondition {
-        protected List<? extends TreeCondition> subConditions;
-
-        public Xor(ModelTree modelTree, Element condElement) {
-            super (modelTree, condElement);
-            this.subConditions = readSubConditions(modelTree, condElement);
-        }
-
-        @Override
-        public boolean eval(Map<String, ? extends 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 (TreeCondition subCondition: subConditions) {
-                if (subCondition.eval(context)) {
-                    if (foundOneTrue) {
-                        // now found two true, so return false
-                        return false;
-                    } else {
-                        foundOneTrue = true;
-                    }
-                }
-            }
-            return foundOneTrue;
-        }
-    }
-
-    public static class Or extends TreeCondition {
-        protected List<? extends TreeCondition> subConditions;
-
-        public Or(ModelTree modelTree, Element condElement) {
-            super (modelTree, condElement);
-            this.subConditions = readSubConditions(modelTree, condElement);
-        }
-
-        @Override
-        public boolean eval(Map<String, ? extends Object> context) {
-            // return true for the first one in the list that is true, basic or algo
-            for (TreeCondition subCondition: subConditions) {
-                if (subCondition.eval(context)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
-    public static class Not extends TreeCondition {
-        protected TreeCondition subCondition;
-
-        public Not(ModelTree modelTree, Element condElement) {
-            super (modelTree, condElement);
-            Element firstChildElement = UtilXml.firstChildElement(condElement);
-            this.subCondition = readCondition(modelTree, firstChildElement);
-        }
-
-        @Override
-        public boolean eval(Map<String, ? extends Object> context) {
-            return !this.subCondition.eval(context);
-        }
-    }
-
-    public static class IfHasPermission extends TreeCondition {
-        protected FlexibleStringExpander permissionExdr;
-        protected FlexibleStringExpander actionExdr;
-
-        public IfHasPermission(ModelTree modelTree, Element condElement) {
-            super (modelTree, condElement);
-            this.permissionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("permission"));
-            this.actionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("action"));
-        }
-
-        @Override
-        public boolean eval(Map<String, ? extends Object> context) {
-            // if no user is logged in, treat as if the user does not have permission
-            GenericValue userLogin = (GenericValue) context.get("userLogin");
-            if (userLogin != null) {
-                String permission = permissionExdr.expandString(context);
-                String action = actionExdr.expandString(context);
-                Security security = (Security) context.get("security");
-                if (UtilValidate.isNotEmpty(action)) {
-                    // run hasEntityPermission
-                    if (security.hasEntityPermission(permission, action, userLogin)) {
-                        return true;
-                    }
-                } else {
-                    // run hasPermission
-                    if (security.hasPermission(permission, userLogin)) {
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-    }
-
-    public static class IfValidateMethod extends TreeCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-        protected FlexibleStringExpander methodExdr;
-        protected FlexibleStringExpander classExdr;
-
-        public IfValidateMethod(ModelTree modelTree, Element condElement) {
-            super (modelTree, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-            this.methodExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("method"));
-            this.classExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("class"));
-        }
-
-        @Override
-        public boolean eval(Map<String, ? extends Object> context) {
-            String methodName = this.methodExdr.expandString(context);
-            String className = this.classExdr.expandString(context);
-
-            Object fieldVal = this.fieldAcsr.get(context);
-            String fieldString = null;
-            if (fieldVal != null) {
-                try {
-                    fieldString = (String) ObjectType.simpleTypeConvert(fieldVal, "String", null, (TimeZone) context.get("timeZone"), (Locale) context.get("locale"), true);
-                } catch (GeneralException e) {
-                    Debug.logError(e, "Could not convert object to String, using empty String", module);
-                }
-            }
-
-            // always use an empty string by default
-            if (fieldString == null) fieldString = "";
-
-            Class<?>[] paramTypes = new Class[] {String.class};
-            Object[] params = new Object[] {fieldString};
-
-            Class<?> valClass;
-            try {
-                valClass = ObjectType.loadClass(className);
-            } catch (ClassNotFoundException cnfe) {
-                Debug.logError("Could not find validation class: " + className, module);
-                return false;
-            }
-
-            Method valMethod;
-            try {
-                valMethod = valClass.getMethod(methodName, paramTypes);
-            } catch (NoSuchMethodException cnfe) {
-                Debug.logError("Could not find validation method: " + methodName + " of class " + className, module);
-                return false;
-            }
-
-            Boolean resultBool = Boolean.FALSE;
-            try {
-                resultBool = (Boolean) valMethod.invoke(null, params);
-            } catch (Exception e) {
-                Debug.logError(e, "Error in IfValidationMethod " + methodName + " of class " + className + ", defaulting to false ", module);
-            }
-
-            return resultBool.booleanValue();
-        }
-    }
-
-    public static class IfCompare extends TreeCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-        protected FlexibleStringExpander valueExdr;
-
-        protected String operator;
-        protected String type;
-        protected FlexibleStringExpander formatExdr;
-
-        public IfCompare(ModelTree modelTree, Element condElement) {
-            super (modelTree, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-            this.valueExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("value"));
-
-            this.operator = condElement.getAttribute("operator");
-            this.type = condElement.getAttribute("type");
-
-            this.formatExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("format"));
-        }
-
-        @Override
-        public boolean eval(Map<String, ? extends Object> context) {
-            String value = this.valueExdr.expandString(context);
-            String format = this.formatExdr.expandString(context);
-
-            Object fieldVal = this.fieldAcsr.get(context);
-
-            // always use an empty string by default
-            if (fieldVal == null) {
-                fieldVal = "";
-            }
-
-            List<Object> messages = new LinkedList<Object>();
-            Boolean resultBool = BaseCompare.doRealCompare(fieldVal, value, operator, type, format, messages, null, null, true);
-            if (messages.size() > 0) {
-                messages.add(0, "Error with comparison in if-compare between field [" + fieldAcsr.toString() + "] with value [" + fieldVal + "] and value [" + value + "] with operator [" + operator + "] and type [" + type + "]: ");
-
-                StringBuilder fullString = new StringBuilder();
-                for (Object message: messages) {
-                    fullString.append((String) message);
-                }
-                Debug.logWarning(fullString.toString(), module);
-
-                throw new IllegalArgumentException(fullString.toString());
-            }
-
-            return resultBool.booleanValue();
-        }
-    }
-
-    public static class IfCompareField extends TreeCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-        protected FlexibleMapAccessor<Object> toFieldAcsr;
-
-        protected String operator;
-        protected String type;
-        protected FlexibleStringExpander formatExdr;
-
-        public IfCompareField(ModelTree modelTree, Element condElement) {
-            super (modelTree, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-            this.toFieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("to-field"));
-            if (this.toFieldAcsr.isEmpty()) this.toFieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("to-field-name"));
-
-            this.operator = condElement.getAttribute("operator");
-            this.type = condElement.getAttribute("type");
-
-            this.formatExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("format"));
-        }
-
-        @Override
-        public boolean eval(Map<String, ? extends Object> context) {
-            String format = this.formatExdr.expandString(context);
-
-            Object fieldVal = this.fieldAcsr.get(context);
-            Object toFieldVal = this.toFieldAcsr.get(context);
-
-            // always use an empty string by default
-            if (fieldVal == null) {
-                fieldVal = "";
-            }
-
-            List<Object> messages = new LinkedList<Object>();
-            Boolean resultBool = BaseCompare.doRealCompare(fieldVal, toFieldVal, operator, type, format, messages, null, null, false);
-            if (messages.size() > 0) {
-                messages.add(0, "Error with comparison in if-compare-field between field [" + fieldAcsr.toString() + "] with value [" + fieldVal + "] and to-field [" + toFieldVal.toString() + "] with value [" + toFieldVal + "] with operator [" + operator + "] and type [" + type + "]: ");
-
-                StringBuilder fullString = new StringBuilder();
-                for (Object message: messages) {
-                    fullString.append((String) message);
-                }
-                Debug.logWarning(fullString.toString(), module);
-
-                throw new IllegalArgumentException(fullString.toString());
-            }
-
-            return resultBool.booleanValue();
-        }
-    }
-
-    public static class IfRegexp extends TreeCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-        protected FlexibleStringExpander exprExdr;
-
-        public IfRegexp(ModelTree modelTree, Element condElement) {
-            super (modelTree, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-            this.exprExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("expr"));
-        }
-
-        @Override
-        public boolean eval(Map<String, ? extends Object> context) {
-            Object fieldVal = this.fieldAcsr.get(context);
-            String expr = this.exprExdr.expandString(context);
-            Pattern pattern = null;
-
-            try {
-                pattern = PatternFactory.createOrGetPerl5CompiledPattern(expr, true);
-            } catch (MalformedPatternException e) {
-                String errMsg = "Error in evaluation in if-regexp in screen: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-
-            String fieldString = null;
-            try {
-                fieldString = (String) ObjectType.simpleTypeConvert(fieldVal, "String", null, (TimeZone) context.get("timeZone"), (Locale) context.get("locale"), true);
-            } catch (GeneralException e) {
-                Debug.logError(e, "Could not convert object to String, using empty String", module);
-            }
-            // always use an empty string by default
-            if (fieldString == null) fieldString = "";
-
-            PatternMatcher matcher = new Perl5Matcher();
-            return matcher.matches(fieldString, pattern);
-        }
-    }
-
-    public static class IfEmpty extends TreeCondition {
-        protected FlexibleMapAccessor<Object> fieldAcsr;
-
-        public IfEmpty(ModelTree modelTree, Element condElement) {
-            super (modelTree, condElement);
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field"));
-            if (this.fieldAcsr.isEmpty()) this.fieldAcsr = FlexibleMapAccessor.getInstance(condElement.getAttribute("field-name"));
-        }
-
-        @Override
-        public boolean eval(Map<String, ? extends Object> context) {
-            Object fieldVal = this.fieldAcsr.get(context);
-            return ObjectType.isEmpty(fieldVal);
-        }
-    }
-    public static class IfEntityPermission extends TreeCondition {
-        protected EntityPermissionChecker permissionChecker;
-
-        public IfEntityPermission(ModelTree modelTree, Element condElement) {
-            super (modelTree, condElement);
-            this.permissionChecker = new EntityPermissionChecker(condElement);
-        }
-
-        @Override
-        public boolean eval(Map<String, ? extends Object> context) {
-
-            boolean passed = permissionChecker.runPermissionCheck(context);
-            return passed;
-        }
+        super(ModelWidgetCondition.DEFAULT_CONDITION_FACTORY, modelTree, conditionElement);
     }
 }
diff --git a/framework/widget/src/org/ofbiz/widget/tree/TreeFactory.java b/framework/widget/src/org/ofbiz/widget/tree/TreeFactory.java
index 6d33da3..9e64cae 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/TreeFactory.java
+++ b/framework/widget/src/org/ofbiz/widget/tree/TreeFactory.java
@@ -78,8 +78,7 @@
             // read document and construct ModelTree for each tree element
             Element rootElement = treeFileDoc.getDocumentElement();
             for (Element treeElement: UtilXml.childElementList(rootElement, "tree")) {
-                ModelTree modelTree = new ModelTree(treeElement, delegator, dispatcher);
-                modelTree.setTreeLocation(treeLocation);
+                ModelTree modelTree = new ModelTree(treeElement, treeLocation);
                 modelTreeMap.put(modelTree.getName(), modelTree);
             }
         }
diff --git a/specialpurpose/assetmaint/webapp/assetmaint/WEB-INF/actions/assetmaint/EditMaint.groovy b/specialpurpose/assetmaint/webapp/assetmaint/WEB-INF/actions/assetmaint/EditMaint.groovy
index 67bccc6..8782684 100644
--- a/specialpurpose/assetmaint/webapp/assetmaint/WEB-INF/actions/assetmaint/EditMaint.groovy
+++ b/specialpurpose/assetmaint/webapp/assetmaint/WEB-INF/actions/assetmaint/EditMaint.groovy
@@ -29,7 +29,7 @@
 workEffortId = parameters.workEffortId;
 
 if (!maintHistSeqId && workEffortId) {
-    fixedAssetMaint = EntityUtil.getFirst(delegator.findList("FixedAssetMaint", EntityCondition.makeCondition([scheduleWorkEffortId : workEffortId]), null, null, null, false));
+    fixedAssetMaint = from("FixedAssetMaint").where("scheduleWorkEffortId", workEffortId).queryFirst();
     if (fixedAssetMaint) {
         parameters.fixedAssetId = fixedAssetMaint.fixedAssetId;
         parameters.maintHistSeqId = fixedAssetMaint.maintHistSeqId;
diff --git a/specialpurpose/assetmaint/webapp/assetmaint/WEB-INF/actions/assetmaint/PrintFixedAssetMaint.groovy b/specialpurpose/assetmaint/webapp/assetmaint/WEB-INF/actions/assetmaint/PrintFixedAssetMaint.groovy
index 83eb539..8faf9b9 100644
--- a/specialpurpose/assetmaint/webapp/assetmaint/WEB-INF/actions/assetmaint/PrintFixedAssetMaint.groovy
+++ b/specialpurpose/assetmaint/webapp/assetmaint/WEB-INF/actions/assetmaint/PrintFixedAssetMaint.groovy
@@ -23,7 +23,7 @@
 facility = fixedAsset.getRelatedOne("LocatedAtFacility", false);
 context.locatedAtFacility = facility;
 
-fixedAssetIdents = delegator.findList("FixedAssetIdent", EntityCondition.makeCondition([fixedAssetId : fixedAssetId]), null, null, null, false);
+fixedAssetIdents = from("FixedAssetIdent").where("fixedAssetId", fixedAssetId).queryList();
 fixedAssetIdentValue = "";
 if (fixedAssetIdents) {
     fixedAssetIdents.each { ident ->
@@ -46,13 +46,13 @@
 instanceOfProductId = fixedAsset.instanceOfProductId;
 productMaintSeqId = fixedAssetMaint.productMaintSeqId;
 if (productMaintSeqId) {
-    productMaint = delegator.findOne("ProductMaint", [productId : instanceOfProductId, productMaintSeqId : productMaintSeqId], false);
+    productMaint = from("ProductMaint").where("productId", instanceOfProductId, "productMaintSeqId", productMaintSeqId).queryOne();
     context.productMaintName = productMaint.maintName;
 }
 
 productMaintTypeId = fixedAssetMaint.productMaintTypeId;
 if (productMaintTypeId) {
-    productMaintType = delegator.findOne("ProductMaintType", [productMaintTypeId : productMaintTypeId], false);
+    productMaintType = from("ProductMaintType").where("productMaintTypeId", productMaintTypeId).queryOne();
     if (productMaintType) {
         productMaintTypeDesc = productMaintType.description;
         context.productMaintTypeDesc = productMaintTypeDesc;
@@ -62,7 +62,7 @@
 intervalMeterTypeId = fixedAssetMaint.intervalMeterTypeId;
 productMeterTypeDesc = "";
 if (intervalMeterTypeId) {
-    productMeterType = delegator.findOne("ProductMeterType", [productMeterTypeId : intervalMeterTypeId], false);
+    productMeterType = from("ProductMeterType").where("productMeterTypeId", intervalMeterTypeId).queryOne();
     productMeterTypeDesc  = productMeterType.description;
 }
 context.productMeterTypeDesc = productMeterTypeDesc;
diff --git a/specialpurpose/assetmaint/webapp/assetmaint/WEB-INF/actions/workeffort/EditWorkEfforts.groovy b/specialpurpose/assetmaint/webapp/assetmaint/WEB-INF/actions/workeffort/EditWorkEfforts.groovy
index 0e32ee4..d80e4b3 100644
--- a/specialpurpose/assetmaint/webapp/assetmaint/WEB-INF/actions/workeffort/EditWorkEfforts.groovy
+++ b/specialpurpose/assetmaint/webapp/assetmaint/WEB-INF/actions/workeffort/EditWorkEfforts.groovy
@@ -44,16 +44,16 @@
 rootWorkEffortId = null;
 
 if (workEffortId) {
-    workEffort = delegator.findOne("WorkEffort", [workEffortId : workEffortId], false);
+    workEffort = from("WorkEffort").where("workEffortId", workEffortId).queryOne();
     if (workEffort) {
         if (!fixedAssetId) {
             fixedAssetId = workEffort.fixedAssetId;
         }
         // If this is a child workeffort, locate the "root" workeffort
-        parentWorkEffort = EntityUtil.getFirst(delegator.findList("WorkEffortAssoc", EntityCondition.makeCondition([workEffortIdTo : workEffortId]), null, null, null, false));
+        parentWorkEffort = from("WorkEffortAssoc").where("workEffortIdTo", workEffortId).queryFirst();
         while (parentWorkEffort) {
             rootWorkEffortId = parentWorkEffort.workEffortIdFrom;
-            parentWorkEffort = EntityUtil.getFirst(delegator.findList("WorkEffortAssoc", EntityCondition.makeCondition([workEffortIdTo : rootWorkEffortId]), null, null, null, false));
+            parentWorkEffort = from("WorkEffortAssoc").where("workEffortIdTo", rootWorkEffortId).queryFirst();
         }
     }
 }
@@ -63,7 +63,7 @@
 }
 
 if (rootWorkEffortId) {
-    fixedAssetMaint = EntityUtil.getFirst(delegator.findList("FixedAssetMaint", EntityCondition.makeCondition([scheduleWorkEffortId : rootWorkEffortId]), null, null, null, false));
+    fixedAssetMaint = from("FixedAssetMaint").where("scheduleWorkEffortId", rootWorkEffortId).queryFirst();
     if (fixedAssetMaint) {
         maintHistSeqId = fixedAssetMaint.maintHistSeqId;
         if (!fixedAssetId) {
@@ -73,7 +73,7 @@
 }
 
 if (fixedAssetId) {
-    fixedAsset = delegator.findOne("FixedAsset", [fixedAssetId : fixedAssetId], false);
+    fixedAsset = from("FixedAsset").where("fixedAssetId", fixedAssetId).queryOne();
 }
 
 context.fixedAssetMaint = fixedAssetMaint;
diff --git a/specialpurpose/bi/webapp/bi/WEB-INF/actions/reportbuilder/RunStarSchemaQuery.groovy b/specialpurpose/bi/webapp/bi/WEB-INF/actions/reportbuilder/RunStarSchemaQuery.groovy
index d4831b1..8650a8d 100644
--- a/specialpurpose/bi/webapp/bi/WEB-INF/actions/reportbuilder/RunStarSchemaQuery.groovy
+++ b/specialpurpose/bi/webapp/bi/WEB-INF/actions/reportbuilder/RunStarSchemaQuery.groovy
@@ -41,21 +41,7 @@
   columnNames.add(selectedField.selectedFieldName);
 }
 context.columnNames = columnNames;
-List conditionList = null;
-EntityConditionList condition =  null;
-List orderByFields = null;
-EntityFindOptions findOptions = null;
-
 List records = FastList.newInstance();
-
-//conditionList.add(...);
-//condition =  EntityCondition.makeCondition(conditionList, EntityOperator.AND);
-
-orderByFields = null;
-
-findOptions = new EntityFindOptions();
-findOptions.setDistinct(false);
-
-records = delegator.findList(starSchemaName, condition, context.columnNames, orderByFields, findOptions, false);
+records = select(context.columnNames).from(starSchemaName).distinct(false).queryList();
 
 context.records = records;
diff --git a/specialpurpose/ebay/src/org/ofbiz/ebay/ProductsExportToEbay.java b/specialpurpose/ebay/src/org/ofbiz/ebay/ProductsExportToEbay.java
index 1c5e777..390c284 100755
--- a/specialpurpose/ebay/src/org/ofbiz/ebay/ProductsExportToEbay.java
+++ b/specialpurpose/ebay/src/org/ofbiz/ebay/ProductsExportToEbay.java
@@ -34,6 +34,7 @@
 
 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.UtilMisc;
 import org.ofbiz.base.util.UtilProperties;
@@ -179,7 +180,7 @@
             Delegator delegator = dctx.getDelegator();
             String webSiteUrl = (String)context.get("webSiteUrl");
 
-            StringUtil.SimpleEncoder encoder = StringUtil.getEncoder("xml");
+            UtilCodec.SimpleEncoder encoder = UtilCodec.getEncoder("xml");
 
             // Get the list of products to be exported to eBay
             try {
diff --git a/specialpurpose/ebay/webapp/ebay/WEB-INF/actions/find/EbayAdvancedSearch.groovy b/specialpurpose/ebay/webapp/ebay/WEB-INF/actions/find/EbayAdvancedSearch.groovy
index e33d4a2..d946085 100644
--- a/specialpurpose/ebay/webapp/ebay/WEB-INF/actions/find/EbayAdvancedSearch.groovy
+++ b/specialpurpose/ebay/webapp/ebay/WEB-INF/actions/find/EbayAdvancedSearch.groovy
@@ -31,12 +31,12 @@
 } else {
     productStoreId = ProductStoreWorker.getProductStoreId(request);
 }
-ebayConfigList = delegator.findList("EbayConfig", null, null, null, null, false);
+ebayConfigList = from("EbayConfig").queryList();
 if (productStoreId) {
     productStoreCatalogs = CatalogWorker.getStoreCatalogs(delegator, productStoreId);
     if (productStoreCatalogs) {
         productStoreCatalogs.each { productStoreCatalog ->
-            prodCatalog = delegator.findOne("ProdCatalog", [prodCatalogId : productStoreCatalog.prodCatalogId], true);
+            prodCatalog = from("ProdCatalog").where("prodCatalogId", productStoreCatalog.prodCatalogId).cache(true).queryOne();
             prodCatalogList.add(prodCatalog);
         }
     }
diff --git a/specialpurpose/ebay/webapp/ebay/WEB-INF/actions/find/ProductsExportToEbay.groovy b/specialpurpose/ebay/webapp/ebay/WEB-INF/actions/find/ProductsExportToEbay.groovy
index 0e8dc7b..bad4821 100644
--- a/specialpurpose/ebay/webapp/ebay/WEB-INF/actions/find/ProductsExportToEbay.groovy
+++ b/specialpurpose/ebay/webapp/ebay/WEB-INF/actions/find/ProductsExportToEbay.groovy
@@ -24,9 +24,9 @@
 webSite = null;
 if (parameters.productStoreId) {
     productStoreId = parameters.productStoreId;
-    webSiteList = delegator.findList("WebSite", EntityCondition.makeCondition("productStoreId", EntityOperator.EQUALS, productStoreId), null, null, null, false);
+    webSiteList = from("WebSite").where("productStoreId", productStoreId).queryList();
     if (parameters.webSiteId) {
-        webSite = delegator.findOne("WebSite", ["webSiteId" : parameters.webSiteId], true);
+        webSite = from("WebSite").where("webSiteId", parameters.webSiteId).cache(true).queryOne();
         context.selectedWebSiteId = parameters.webSiteId;
     } else if (webSiteList) {
         webSite = EntityUtil.getFirst(webSiteList);
@@ -42,7 +42,7 @@
     }
     context.countryCode = countryCode;
     if (webSite) {
-        eBayConfig = delegator.findOne("EbayConfig", [productStoreId : productStoreId], false);
+        eBayConfig = from("EbayConfig").where("productStoreId", productStoreId).queryOne();
         context.customXml = eBayConfig.customXml;
         context.webSiteUrl = webSite.getString("standardContentPrefix");
         
@@ -51,7 +51,7 @@
         userLogin = parameters.userLogin;
         
         if (productStoreId) {
-            results = dispatcher.runSync("getEbayCategories", [categoryCode : categoryCode, userLogin : userLogin, productStoreId : productStoreId]);
+            results = runService('getEbayCategories', [categoryCode : categoryCode, userLogin : userLogin, productStoreId : productStoreId]);
         }
         
         if (results.categories) {
diff --git a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/automationPreferences/GetEbayJobsandbox.groovy b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/automationPreferences/GetEbayJobsandbox.groovy
index 51bcc73..b6c7568 100644
--- a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/automationPreferences/GetEbayJobsandbox.groovy
+++ b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/automationPreferences/GetEbayJobsandbox.groovy
@@ -19,7 +19,7 @@
 
 import org.ofbiz.base.util.*;
 
-jobSandboxs = delegator.findByAnd("JobSandbox", UtilMisc.toMap("authUserLoginId", userLoginId), null, false);
+jobSandboxs = from("JobSandbox").where("authUserLoginId", userLoginId).queryList();
 job = null
 jobId = null;
 if(jobSandboxs) {
diff --git a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/email/GetProductStoreEmailTemplate.groovy b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/email/GetProductStoreEmailTemplate.groovy
index 70bd3fb..a406e13 100644
--- a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/email/GetProductStoreEmailTemplate.groovy
+++ b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/email/GetProductStoreEmailTemplate.groovy
@@ -20,10 +20,10 @@
 import org.ofbiz.base.util.*;
 
 contentId = null;
-contentRoles = delegator.findByAnd("ContentRole", UtilMisc.toMap("partyId", partyId, "roleTypeId", "OWNER"), null, false);
+contentRoles = from("ContentRole").where("partyId", partyId, "roleTypeId", "OWNER").queryList();
 if (contentRoles.size() != 0) {
     contentRoles.each { contentRole->
-        contents = delegator.findByAnd("Content", UtilMisc.toMap("contentId", contentRole.getString("contentId"), "ownerContentId", emailType), null, false);
+        contents = from("Content").where("contentId", contentRole.getString("contentId"), "ownerContentId", emailType).queryList();
         if (contents.size() != 0) {
             if (emailType.equals(contents.get(0).getString("ownerContentId"))) {
                 contentId = contents.get(0).getString("contentId");
diff --git a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/feedback/FeedbackList.groovy b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/feedback/FeedbackList.groovy
index 1b5079b..f0c8546 100644
--- a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/feedback/FeedbackList.groovy
+++ b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/feedback/FeedbackList.groovy
@@ -25,12 +25,9 @@
 import javolution.util.FastMap;
 
 partyId = null
-inMap = FastMap.newInstance();
-inMap.put("productStoreId", parameters.productStoreId);
-inMap.put("userLogin", context.get("userLogin"));
-resultUser = dispatcher.runSync("getEbayStoreUser", inMap);
+resultUser = runService('getEbayStoreUser', ["productStoreId": parameters.productStoreId, "userLogin": context.get("userLogin")]);
 ownerUser = resultUser.get("userLoginId");
-userLogin = delegator.findOne("UserLogin", UtilMisc.toMap("userLoginId", ownerUser), false);
+userLogin = from("UserLogin").where("userLoginId", ownerUser).queryOne();
 if (userLogin) {
     partyId = userLogin.get("partyId");
 }
@@ -55,23 +52,22 @@
 } else if (!fromDate && thruDate) {
     expr.add(EntityCondition.makeCondition("createdDate",EntityOperator.LESS_THAN, UtilDateTime.getDayEnd(Timestamp.valueOf(thruDate + " 23:59:59.999"))));
 }
-contentRoles = delegator.findByAnd("ContentRole", UtilMisc.toMap("roleTypeId","OWNER", "partyId", partyId), null, false);
+contentRoles = from("ContentRole").where("roleTypeId","OWNER", "partyId", partyId).queryList();
 contentIds = [];
 contentRoles.each{ content ->
     contentIds.add(content.getString("contentId"));
 }
 expr.add(EntityCondition.makeCondition("contentId", EntityOperator.IN, contentIds));
-cond = EntityCondition.makeCondition(expr, EntityOperator.AND);
-contents = delegator.findList("Content", cond, null, null, null, false);
+contents = from("Content").where(expr).queryList();
 
 recentFeedbackList = [];
 ownerUser = null;
 commentator = null;
 contents.each{ content ->
-    commentatorContents = delegator.findByAnd("ContentRole", UtilMisc.toMap("contentId",content.contentId, "roleTypeId","COMMENTATOR"), null, false);
+    commentatorContents = from("ContentRole").where("contentId",content.contentId, "roleTypeId","COMMENTATOR").queryList();
     if(commentatorContents){
         commentatorPartyId = commentatorContents.get(0).get("partyId");
-        commentatorUsers = delegator.findByAnd("UserLogin", UtilMisc.toMap("partyId", commentatorPartyId), null, false);
+        commentatorUsers = from("UserLogin").where("partyId", commentatorPartyId).queryList();
         if(commentatorUsers){
             commentator = commentatorUsers.get(0).get("userLoginId");
         }
diff --git a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/CheckOrderStatus.groovy b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/CheckOrderStatus.groovy
index 2682366..f098a28 100644
--- a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/CheckOrderStatus.groovy
+++ b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/CheckOrderStatus.groovy
@@ -19,7 +19,7 @@
 import org.ofbiz.entity.util.EntityUtil;
 
 context.importStatus = "NOT_IMPORT";
-orderHeaders = delegator.findByAnd("OrderHeader", [externalId : externalId], null, false);
+orderHeaders = from("OrderHeader").where("externalId", externalId).queryList();
 if (orderHeaders.size() > 0) {
     orderHeader = EntityUtil.getFirst(orderHeaders);
     context.orderId = orderHeader.get("orderId");
diff --git a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/OrderListPrepare.groovy b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/OrderListPrepare.groovy
index 2cd2600..458f58c 100644
--- a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/OrderListPrepare.groovy
+++ b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/OrderListPrepare.groovy
@@ -28,7 +28,7 @@
     for (orderCount = 0; orderCount < orderList.size(); orderCount++) {
         orderItem = orderList[orderCount];
         orderId = null;
-        orderHeaders = delegator.findByAnd("OrderHeader", [externalId : orderItem.("externalId")], null, false);
+        orderHeaders = from("OrderHeader").where("externalId", orderItem.("externalId")).queryList();
         if (orderHeaders.size() > 0) {
             orderHeader = EntityUtil.getFirst(orderHeaders);
             orderId = orderHeader.get("orderId").toString();
@@ -44,7 +44,7 @@
             item = items[itemCount];
             title = null;
             if (!(item.get("title"))) {
-                product = delegator.findOne("Product", [productId : item.get("productId")], true);
+                product = from("Product").where("productId", item.get("productId")).cache(true).queryOne();
                 title = product.get("internalName");
             }
             orderMap = FastMap.newInstance();
diff --git a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/PrepareProductListing.groovy b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/PrepareProductListing.groovy
index e57a887..48c649d 100644
--- a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/PrepareProductListing.groovy
+++ b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/PrepareProductListing.groovy
@@ -64,7 +64,7 @@
          content = [:];
          item = addItem.getItem();
          productId = item.getSKU();
-         product = delegator.findOne("Product", [productId : productId], true);
+         product = from("Product").where("productId", productId).cache(true).queryOne();
          contentWrapper = new ProductContentWrapper(product, request);
          content.productContentWrapper = contentWrapper;
          content.product = product;
@@ -94,7 +94,7 @@
          }
          context.isProductId = productId;
          // get product default price form product price 
-         productPrices = delegator.findByAnd("ProductPrice",["productId":productId,"productPricePurposeId":"EBAY"], null, false);
+         productPrices = from("ProductPrice").where("productId", productId, "productPricePurposeId", "EBAY").queryList();
          if (productPrices) {
              context.productPrices = productPrices;
          }
diff --git a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/RetrieveStoreOptions.groovy b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/RetrieveStoreOptions.groovy
index 987a836..7de8974 100644
--- a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/RetrieveStoreOptions.groovy
+++ b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/RetrieveStoreOptions.groovy
@@ -26,7 +26,7 @@
 if (productStoreId != null) {
     flag = null;
     storeBasicThemes = null;
-    resultsBasicThemes = dispatcher.runSync("retrieveBasicThemeArray",["productStoreId":productStoreId, "userLogin": userLogin]);
+    resultsBasicThemes = runService('retrieveBasicThemeArray',["productStoreId":productStoreId, "userLogin": userLogin]);
     if(resultsBasicThemes){
         storeBasicThemes = resultsBasicThemes.get("storeThemeList");
         //check what kind of theme?
@@ -41,7 +41,7 @@
     }
     storeAdvanceThemes = null;
     storeAdvancedThemeColorOptList = null;
-    resultsAdvanceThemes = dispatcher.runSync("retrieveAdvancedThemeArray",["productStoreId":productStoreId, "userLogin": userLogin]);
+    resultsAdvanceThemes = runService('retrieveAdvancedThemeArray',["productStoreId":productStoreId, "userLogin": userLogin]);
     if (resultsAdvanceThemes) {
         storeAdvanceThemes = resultsAdvanceThemes.get("storeThemeList");
         storeAdvancedThemeColorOptList = resultsAdvanceThemes.get("storeAdvancedThemeColorOptList");
@@ -56,7 +56,7 @@
             }
         }
     }
-    resultsFontTheme = dispatcher.runSync("retrieveStoreFontTheme",["productStoreId":productStoreId, "userLogin": userLogin]);
+    resultsFontTheme = runService('retrieveStoreFontTheme',["productStoreId":productStoreId, "userLogin": userLogin]);
     if (resultsFontTheme) {
         storeFontTheme = resultsFontTheme.get("advanceFontTheme");
         context.put("storeFontTheme",storeFontTheme);
diff --git a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/StoreAccount.groovy b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/StoreAccount.groovy
index 360180d..a10e9d5 100644
--- a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/StoreAccount.groovy
+++ b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/StoreAccount.groovy
@@ -22,8 +22,8 @@
 import javolution.util.FastMap;
 
 results =  FastList.newInstance();
-ebayAccountList = delegator.findByAnd("PartyRoleAndPartyDetail",["roleTypeId":"EBAY_ACCOUNT"], null, false);
-productStoreRoles = delegator.findByAnd("ProductStoreRole",["roleTypeId":"EBAY_ACCOUNT"], null, false);
+ebayAccountList = from("PartyRoleAndPartyDetail").where("roleTypeId", "EBAY_ACCOUNT").queryList();
+productStoreRoles = from("ProductStoreRole").where("roleTypeId", "EBAY_ACCOUNT").queryList();
 
 if (productStoreRoles != null && ebayAccountList != null) {
     ebayAccountList.each{ebayAccount->
diff --git a/specialpurpose/ebaystore/widget/EbayAccountForms.xml b/specialpurpose/ebaystore/widget/EbayAccountForms.xml
index e498a83..6dd2773 100644
--- a/specialpurpose/ebaystore/widget/EbayAccountForms.xml
+++ b/specialpurpose/ebaystore/widget/EbayAccountForms.xml
@@ -55,7 +55,7 @@
     <form name="RecentFeedback" type="list" list-name="recentFeedbackList"
         odd-row-style="alternate-row" header-row-style="header-row-2" default-table-style="basic-table hover-bar">
         <field name="contentId" title="Feedback Id"><display/></field>
-        <field name="dataResourceId" title="Comment Text">
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" title="Comment Text">
             <display-entity entity-name="ElectronicText" key-field-name="dataResourceId" description="${textData}"/>
         </field>
         <field name="commentator" title="Commentator"><display/></field>
diff --git a/specialpurpose/ecommerce/config/EcommerceUiLabels.xml b/specialpurpose/ecommerce/config/EcommerceUiLabels.xml
index bdae497..3ae4092 100644
--- a/specialpurpose/ecommerce/config/EcommerceUiLabels.xml
+++ b/specialpurpose/ecommerce/config/EcommerceUiLabels.xml
@@ -1759,6 +1759,9 @@
         <value xml:lang="zh">最近浏览</value>
         <value xml:lang="zh_TW">最近看過</value>
     </property>
+    <property key="EcommerceLayeredNavigation">
+        <value xml:lang="en">Layered Navigation</value>
+    </property>
     <property key="EcommerceLength">
         <value xml:lang="da">Længde</value>
         <value xml:lang="de">Länge</value>
diff --git a/specialpurpose/ecommerce/templates/email/ContactListVerifyEmail.ftl b/specialpurpose/ecommerce/templates/email/ContactListVerifyEmail.ftl
index 6d3da13..1fa9a78 100644
--- a/specialpurpose/ecommerce/templates/email/ContactListVerifyEmail.ftl
+++ b/specialpurpose/ecommerce/templates/email/ContactListVerifyEmail.ftl
@@ -34,7 +34,7 @@
 <p>We have received a request for subscription to the ${contactList.contactListName} contact list.</p>
 <p>To complete your subscription click the on the following link:</p>
 
-<#assign verifyUrl = baseEcommerceSecureUrl+'updateContactListPartyNoUserLogin?contactListId='+contactListParty.contactListId+'&amp;partyId='+contactListParty.partyId+'&amp;fromDate='+contactListParty.fromDate+'&amp;statusId=CLPT_ACCEPTED&amp;optInVerifyCode='+contactListPartyStatus.optInVerifyCode+'&amp;baseLocation='+baseLocation!>
+<#assign verifyUrl = baseEcommerceSecureUrl+'/'+'updateContactListPartyNoUserLogin?contactListId='+contactListParty.contactListId+'&amp;partyId='+contactListParty.partyId+'&amp;fromDate='+contactListParty.fromDate+'&amp;statusId=CLPT_ACCEPTED&amp;optInVerifyCode='+contactListPartyStatus.optInVerifyCode+'&amp;baseLocation='+baseLocation!>
 <#if (contactListParty.preferredContactMechId)??>
     <#assign verifyUrl= verifyUrl+"&amp;preferredContactMechId="+contactListParty.preferredContactMechId>
 </#if>
diff --git a/specialpurpose/ecommerce/templates/survey/minisurvey.ftl b/specialpurpose/ecommerce/templates/survey/minisurvey.ftl
index 79b7f0c..89402ea 100644
--- a/specialpurpose/ecommerce/templates/survey/minisurvey.ftl
+++ b/specialpurpose/ecommerce/templates/survey/minisurvey.ftl
@@ -61,8 +61,8 @@
               <#if surveyQuestionAndAppl.requiredField?default("N") != "Y">
                 <option value=""></option>
               </#if>
-              <option <#if "Y" == selectedOption>selected="selected"</#if>>Y</option>
-              <option <#if "N" == selectedOption>selected="selected"</#if>>N</option>
+              <option value="Y" <#if "Y" == selectedOption>selected="selected"</#if>>Y</option>
+              <option value="N" <#if "N" == selectedOption>selected="selected"</#if>>N</option>
             </select>
           <#elseif surveyQuestionAndAppl.surveyQuestionTypeId == "TEXTAREA">
             <textarea class="textAreaBox" cols="40" rows="5" name="answers_${surveyQuestionAndAppl.surveyQuestionId}">${(answer.textResponse)!}</textarea>
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/cart/ShowCart.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/cart/ShowCart.groovy
index f0c09d7..ac25b74 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/cart/ShowCart.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/cart/ShowCart.groovy
@@ -34,20 +34,18 @@
 
 if (parameters.add_product_id) { // check if a parameter is passed
     add_product_id = parameters.add_product_id;
-    product = delegator.findOne("Product", [productId : add_product_id], true);
+    product = from("Product").where("productId", add_product_id).cache(true).queryOne();
     context.product = product;
 }
 
 // get all the possible gift wrap options
-allgiftWraps = delegator.findByAnd("ProductFeature", [productFeatureTypeId : "GIFT_WRAP"], ["defaultSequenceNum"], false);
+allgiftWraps = from("ProductFeature").where("productFeatureTypeId", "GIFT_WRAP").orderBy("defaultSequenceNum").queryList();
 context.allgiftWraps = allgiftWraps;
 
 // get the shopping lists for the logged in user
 if (userLogin) {
-    exprList = [EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, userLogin.partyId),
-                EntityCondition.makeCondition("listName", EntityOperator.NOT_EQUAL, "auto-save")];
-    condition = EntityCondition.makeCondition(exprList, EntityOperator.AND);
-    allShoppingLists = delegator.findList("ShoppingList", condition, null, ["listName"], null, false);
+    allShoppingLists = from("ShoppingList").where(EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, userLogin.partyId),
+                EntityCondition.makeCondition("listName", EntityOperator.NOT_EQUAL, "auto-save")).orderBy("listName").queryList();
     context.shoppingLists = allShoppingLists;
 }
 
@@ -70,7 +68,7 @@
             }
             context.parentProductId = parentProductId;
         }
-        productCategoryMembers = delegator.findList("ProductCategoryMember", EntityCondition.makeCondition("productId", EntityOperator.EQUALS, parentProductId), null, null, null, false);
+        productCategoryMembers = from("ProductCategoryMember").where("productId", parentProductId).queryList();
         if (productCategoryMembers) {
             productCategoryMember = EntityUtil.getFirst(productCategoryMembers);
             productCategory = productCategoryMember.getRelatedOne("ProductCategory", false);
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/LayeredNavigation.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/LayeredNavigation.groovy
index 6996329..3582b2c 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/LayeredNavigation.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/LayeredNavigation.groovy
@@ -30,7 +30,7 @@
     searchCategoryId = context.productCategoryId;
 }
 if (searchCategoryId) {
-    currentSearchCategory = delegator.findOne("ProductCategory", [productCategoryId: searchCategoryId], false);
+    currentSearchCategory = from("ProductCategory").where("productCategoryId", searchCategoryId).queryOne();
     CategoryWorker.getRelatedCategories(request, "subCategoryList", searchCategoryId, false);
     subCategoryList = request.getAttribute("subCategoryList");
     CategoryContentWrapper categoryContentWrapper = new CategoryContentWrapper(currentSearchCategory, request);
@@ -39,7 +39,7 @@
 }
 productCategoryId = context.productCategoryId;
 if (productCategoryId)  {
-   context.productCategory = delegator.findOne("ProductCategory", [productCategoryId: productCategoryId], false);
+   context.productCategory = from("ProductCategory").where("productCategoryId", productCategoryId).queryOne();
    parameters.SEARCH_CATEGORY_ID = productCategoryId;
 }
 
@@ -56,8 +56,7 @@
 searchConstraintList = ProductSearchSession.getProductSearchOptions(session).getConstraintList();
 
 if (searchCategoryId) {
-    productCategoryRollups = delegator.findByAnd("ProductCategoryRollup", [productCategoryId: searchCategoryId], null, false);
-    productCategoryRollups = EntityUtil.filterByDate(productCategoryRollups);
+    productCategoryRollups = from("ProductCategoryRollup").where("productCategoryId", searchCategoryId).filterByDate().queryList();
     previousCategoryId = null;
     if (productCategoryRollups) {
         for (GenericValue categoryRollup : productCategoryRollups) {
@@ -91,7 +90,7 @@
 
 context.showColors = true;
 colors = ProductSearchSession.listCountByFeatureForType("COLOR", session, delegator);
-colorFeatureType = delegator.findOne("ProductFeatureType", [productFeatureTypeId: "COLOR"], false);
+colorFeatureType = from("ProductFeatureType").where("productFeatureTypeId", "COLOR").queryOne();
 if (colors) {
     colors.each { color ->
         featureConstraint = new ProductSearch.FeatureConstraint(color.productFeatureId, false);
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/MiniProductSummary.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/MiniProductSummary.groovy
index ec9d83a..758aae5 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/MiniProductSummary.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/MiniProductSummary.groovy
@@ -39,7 +39,7 @@
 context.remove("totalPrice");
 
 if (optProductId) {
-    miniProduct = delegator.findOne("Product", [productId : optProductId], false);
+    miniProduct = from("Product").where("productId", optProductId).queryOne();
 }
 
 if (miniProduct && productStoreId && prodCatalogId ) {
@@ -51,12 +51,12 @@
                    autoUserLogin : autoUserLogin,
                    productStoreId : productStoreId];
     if (userLogin) priceParams.partyId = userLogin.partyId;
-    priceResult = dispatcher.runSync("calculateProductPrice", priceParams);
+    priceResult = runService('calculateProductPrice', priceParams);
     // returns: isSale, price, orderItemPriceInfos
     context.priceResult = priceResult;
     // Check if Price has to be displayed with tax
     if (productStore.get("showPricesWithVatTax").equals("Y")) {
-        Map priceMap = dispatcher.runSync("calcTaxForDisplay", UtilMisc.toMap("basePrice", priceResult.get("price"), "locale", locale, "productId", optProductId, "productStoreId", productStoreId));
+        Map priceMap = runServic('calcTaxForDisplay', ["basePrice": priceResult.get("price"), "locale": locale, "productId": optProductId, "productStoreId": productStoreId]);
         context.price = priceMap.get("priceWithTax");
     } else {
         context.price = priceResult.get("price");
@@ -70,7 +70,7 @@
             // Check if Config Price has to be displayed with tax
             if (productStore.get("showPricesWithVatTax").equals("Y")) {
                 BigDecimal totalPriceNoTax = configWrapper.getTotalPrice();
-                Map totalPriceMap = dispatcher.runSync("calcTaxForDisplay", UtilMisc.toMap("basePrice", totalPriceNoTax, "locale", locale, "productId", optProductId, "productStoreId", productStoreId));
+                Map totalPriceMap = runService('calcTaxForDisplay', ["basePrice": totalPriceNoTax, "locale": locale, "productId": optProductId, "productStoreId": productStoreId]);
                 context.totalPrice = totalPriceMap.get("priceWithTax");
             } else {
                 context.totalPrice = configWrapper.getTotalPrice();
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/PopularTags.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/PopularTags.groovy
index 3d3256d..926a417 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/PopularTags.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/PopularTags.groovy
@@ -36,16 +36,16 @@
 tagCloudList = [] as LinkedList;
 tagList = [] as LinkedList;
 
-keywordConditions = EntityCondition.makeCondition([keywordTypeId : "KWT_TAG", statusId : "KW_APPROVED"], EntityOperator.AND);
-keywordOrder = ["keyword"];
-keywordFields = ["keyword", "keywordTypeId", "statusId"] as Set;
-keywordFindOptions = new EntityFindOptions();
-keywordFindOptions.setDistinct(true);
-productKeywords = delegator.findList("ProductKeyword", keywordConditions, keywordFields, keywordOrder, keywordFindOptions, false);
+productKeywords = select("keyword", "keywordTypeId", "statusId")
+                    .from("ProductKeyword")
+                    .where(keywordTypeId : "KWT_TAG", statusId : "KW_APPROVED")
+                    .orderBy("keyword")
+                    .distinct(true)
+                    .queryList();
 
 if (UtilValidate.isNotEmpty(productKeywords)) {
     productKeywords.each { productKeyword ->
-        productTags = delegator.findByAnd("ProductKeyword", ["keyword": productKeyword.keyword, "keywordTypeId" : "KWT_TAG", "statusId" : "KW_APPROVED"], null, false);
+        productTags = from("ProductKeyword").where("keyword", productKeyword.keyword, "keywordTypeId", "KWT_TAG", "statusId", "KW_APPROVED").queryList();
         searchResult = [:];
         searchResult.tag = productKeyword.keyword;
         searchResult.countTag = productTags.size();
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/ProductCategories.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/ProductCategories.groovy
index ae4140b..b7546e7 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/ProductCategories.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/ProductCategories.groovy
@@ -36,7 +36,7 @@
         rootCat.sort{ it.productCategoryId }
         def listTree = FastList.newInstance();
         for(root in rootCat) {
-            preCatChilds = delegator.findByAnd("ProductCategoryRollup", ["parentProductCategoryId": root.productCategoryId], null, false);
+            preCatChilds = from("ProductCategoryRollup").where("parentProductCategoryId", root.productCategoryId).queryList();
             catChilds = EntityUtil.getRelated("CurrentProductCategory",null,preCatChilds,false);
             def childList = FastList.newInstance();
             
@@ -51,12 +51,12 @@
                     childList = fillTree(catChilds,CatLvl+1, parentCategoryId+'/'+root.productCategoryId);
             }
             
-            productsInCat  = delegator.findByAnd("ProductCategoryAndMember", ["productCategoryId": root.productCategoryId], null, false);
+            productsInCat  = from("ProductCategoryAndMember").where("productCategoryId", root.productCategoryId).queryList();
             
             // Display the category if this category containing products or contain the category that's containing products
             if(productsInCat || childList) {
                 def rootMap = FastMap.newInstance();
-                category = delegator.findOne("ProductCategory", ["productCategoryId": root.productCategoryId], false);
+                category = from("ProductCategory").where("productCategoryId", root.productCategoryId).queryOne();
                 categoryContentWrapper = new CategoryContentWrapper(category, request);
                 context.title = categoryContentWrapper.CATEGORY_NAME;
                 categoryDescription = categoryContentWrapper.DESCRIPTION;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/ajaxbreadcrumbs.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/ajaxbreadcrumbs.groovy
index 08b3307..8a6efcb 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/ajaxbreadcrumbs.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/catalog/ajaxbreadcrumbs.groovy
@@ -29,7 +29,7 @@
     pathTemp = '';
     for(path in pathList) {
         cateMap = FastMap.newInstance();
-        category = delegator.findOne("ProductCategory", ["productCategoryId": path], false);
+        category = from("ProductCategory").where("productCategoryId", path).queryOne();
         categoryContentWrapper = new CategoryContentWrapper(category, request);
         
         pathTemp = pathTemp + path;
@@ -44,7 +44,7 @@
 
     context.productCategoryTrail = cateList;
 }
-currentCategory = delegator.findOne("ProductCategory", ["productCategoryId": productCategoryId], false);
+currentCategory = from("ProductCategory").where("productCategoryId", productCategoryId).queryOne();
 currentCategoryContentWrapper = new CategoryContentWrapper(currentCategory, request);
 context.currentCategoryName = currentCategoryContentWrapper.CATEGORY_NAME;
 context.currentCategoryDescription = currentCategoryContentWrapper.DESCRIPTION;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Mrv.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Mrv.groovy
index 00c8101..b2d3958 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Mrv.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Mrv.groovy
@@ -59,7 +59,7 @@
 
 lifoSet.each { pk0 ->
     pk = pk0.getPrimaryKey();
-    gv = delegator.findOne(pk.getEntityName(), pk, true);
+    gv = from(pk.getEntityName()).where(pk).cache(true).queryOne();
     if (gv) {
         arr = [gv.contentId, gv.contentName] as String[];
         mrvList.add(arr);
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Search.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Search.groovy
index ee1c93c..969fa80 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Search.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Search.groovy
@@ -105,7 +105,7 @@
     for (int start = 0; start < collector.getTotalHits(); start++) {
         Document doc = searcher.doc(hits[start].doc)
         contentId = doc.get("contentId");
-        content = delegator.findOne("Content", [contentId : contentId], true);
+        content = from("Content").where("contentId", contentId).cache(true).queryOne();
         if (!hitSet.contains(contentId)) {
             contentList.add(content);
             hitSet.add(contentId);
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/ContactList.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/ContactList.groovy
index e631404..0513df0 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/ContactList.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/ContactList.groovy
@@ -39,8 +39,7 @@
 exprListThruDate.add(EntityCondition.makeCondition("thruDate", EntityOperator.GREATER_THAN_EQUAL_TO, UtilDateTime.nowTimestamp()));

 orCond = EntityCondition.makeCondition(exprListThruDate, EntityOperator.OR);

 exprList.add(orCond);

-topCond = EntityCondition.makeCondition(exprList, EntityOperator.AND);

-webSiteContactList = delegator.findList("WebSiteContactList", topCond, null, null, null, false);

+webSiteContactList = from("WebSiteContactList").where(exprList).queryList();

 

 publicEmailContactLists = [];

 webSiteContactList.each { webSiteContactList ->

@@ -54,8 +53,7 @@
 context.publicEmailContactLists = publicEmailContactLists;

 

 if (userLogin) {

-    partyAndContactMechList = delegator.findByAnd("PartyAndContactMech", [partyId : partyId, contactMechTypeId : "EMAIL_ADDRESS"], ["-fromDate"], false);

-    partyAndContactMechList = EntityUtil.filterByDate(partyAndContactMechList);

+    partyAndContactMechList = from("PartyAndContactMech").where("partyId", partyId, "contactMechTypeId", "EMAIL_ADDRESS").orderBy("-fromDate").filterByDate().queryList();

     context.partyAndContactMechList = partyAndContactMechList;

 }

 

diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/CustomerReviews.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/CustomerReviews.groovy
index bd76b72..58fdfd9 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/CustomerReviews.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/CustomerReviews.groovy
@@ -22,8 +22,7 @@
 
 // get the product review(s) for the given user
 if (userLogin) {
-  condition = EntityCondition.makeCondition("userLoginId", EntityOperator.EQUALS, userLogin.userLoginId);
-  reviews = delegator.findList("ProductReview", condition, null, null, null, true);
+  reviews = from("ProductReview").where("userLoginId", userLogin.userLoginId).cache(true).queryList();
 
   context.reviews = reviews;
 }
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/CustomerSurvey.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/CustomerSurvey.groovy
index 5449b11..e7fd30f 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/CustomerSurvey.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/CustomerSurvey.groovy
@@ -27,7 +27,7 @@
 
 productStoreSurveyId = parameters.productStoreSurveyId;
 
-surveyAppl = delegator.findOne("ProductStoreSurveyAppl", [productStoreSurveyId : productStoreSurveyId], false);
+surveyAppl = from("ProductStoreSurveyAppl").where("productStoreSurveyId", productStoreSurveyId).queryOne();
 if (surveyAppl) {
     survey = surveyAppl.getRelatedOne("Survey", false);
     context.survey = survey;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditBillingAddress.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditBillingAddress.groovy
index 6fc570d..dff9cce 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditBillingAddress.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditBillingAddress.groovy
@@ -36,17 +36,17 @@
         context.billToPostalCode = postalAddress.postalCode;
         context.billToStateProvinceGeoId = postalAddress.stateProvinceGeoId;
         context.billToCountryGeoId = postalAddress.countryGeoId;
-        billToStateProvinceGeo = delegator.findOne("Geo", [geoId : postalAddress.stateProvinceGeoId], false);
+        billToStateProvinceGeo = from("Geo").where("geoId", postalAddress.stateProvinceGeoId).queryOne();
         if (billToStateProvinceGeo) {
             context.billToStateProvinceGeo = billToStateProvinceGeo.geoName;
         }
-        billToCountryProvinceGeo = delegator.findOne("Geo", [geoId : postalAddress.countryGeoId], false);
+        billToCountryProvinceGeo = from("Geo").where("geoId", postalAddress.countryGeoId).queryOne();
         if (billToCountryProvinceGeo) {
             context.billToCountryProvinceGeo = billToCountryProvinceGeo.geoName;
         }
 
         creditCards = [];
-        paymentMethod = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findList("PaymentMethod", EntityCondition.makeCondition([partyId : party.partyId, paymentMethodTypeId : "CREDIT_CARD"]), null, ["fromDate"], null, false)));
+        paymentMethod = from("PaymentMethod").where("partyId", party.partyId, "paymentMethodTypeId", "CREDIT_CARD").orderBy("fromDate").filterByDate().queryFirst();
         if (paymentMethod) {
             creditCard = paymentMethod.getRelatedOne("CreditCard", false);
             context.paymentMethodTypeId = "CREDIT_CARD";
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditContactMech.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditContactMech.groovy
index d5b22a2..51384b0 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditContactMech.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditContactMech.groovy
@@ -46,7 +46,7 @@
 
 cmNewPurposeTypeId = parameters.contactMechPurposeTypeId;
 if (cmNewPurposeTypeId) {
-    contactMechPurposeType = delegator.findOne("ContactMechPurposeType", [contactMechPurposeTypeId : cmNewPurposeTypeId], false);
+    contactMechPurposeType = from("ContactMechPurposeType").where("contactMechPurposeTypeId", cmNewPurposeTypeId).queryOne();
     if (contactMechPurposeType) {
         context.contactMechPurposeType = contactMechPurposeType;
     } else {
@@ -79,24 +79,24 @@
 
 // load the geo names for selected countries and states/regions
 if (parameters.countryGeoId) {
-    geoValue = delegator.findOne("Geo", [geoId : parameters.countryGeoId], true);
+    geoValue = from("Geo").where("geoId", parameters.countryGeoId).cache(true).queryOne();
     if (geoValue) {
         context.selectedCountryName = geoValue.geoName;
     }
 } else if (postalAddressData?.countryGeoId) {
-    geoValue = delegator.findOne("Geo", [geoId : postalAddressData.countryGeoId], true);
+    geoValue = from("Geo").where("geoId", postalAddressData.countryGeoId).cache(true).queryOne();
     if (geoValue) {
         context.selectedCountryName = geoValue.geoName;
     }
 }
 
 if (parameters.stateProvinceGeoId) {
-    geoValue = delegator.findOne("Geo", [geoId : parameters.stateProvinceGeoId], true);
+    geoValue = from("Geo").where("geoId", parameters.stateProvinceGeoId).cache(true).queryOne();
     if (geoValue) {
         context.selectedStateName = geoValue.geoId;
     }
 } else if (postalAddressData?.stateProvinceGeoId) {
-    geoValue = delegator.findOne("Geo", [geoId : postalAddressData.stateProvinceGeoId], true);
+    geoValue = from("Geo").where("geoId", postalAddressData.stateProvinceGeoId).cache(true).queryOne();
     if (geoValue) {
         context.selectedStateName = geoValue.geoId;
     }
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditEmailAndTelecomNumber.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditEmailAndTelecomNumber.groovy
index be4feed..53c00ea 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditEmailAndTelecomNumber.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditEmailAndTelecomNumber.groovy
@@ -31,7 +31,7 @@
 
     contactMech = EntityUtil.getFirst(ContactHelper.getContactMech(party, "PRIMARY_PHONE", "TELECOM_NUMBER", false));
     if (contactMech) {
-        partyContactMech = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("PartyContactMech", [partyId : party.partyId, contactMechId : contactMech.contactMechId], null, false)));
+        partyContactMech = from("PartyContactMech").where("partyId", party.partyId, "contactMechId", contactMech.contactMechId).filterByDate().queryFirst();
         if (partyContactMech) {
             telecomNumber = partyContactMech.getRelatedOne("TelecomNumber", false);
             context.phoneContactMechId = telecomNumber.contactMechId;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditShippingAddress.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditShippingAddress.groovy
index 134831a..ffba69d 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditShippingAddress.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/EditShippingAddress.groovy
@@ -24,11 +24,11 @@
     party = userLogin.getRelatedOne("Party", false);
     context.partyId = party.partyId
     if ("PERSON".equals(party.partyTypeId)) {
-        person = delegator.findOne("Person", [partyId : party.partyId], false);
+        person = from("Person").where("partyId", party.partyId).queryOne();
         context.firstName = person.firstName;
         context.lastName = person.lastName;
     } else {
-        group = delegator.findOne("PartyGroup", [partyId : party.partyId], false);   
+        group = from("PartyGroup").where("partyId", party.partyId).queryOne();
         context.firstName = group.groupName;
         context.lastName = "";    
     }
@@ -46,11 +46,11 @@
         context.shipToPostalCode = postalAddress.postalCode;
         context.shipToStateProvinceGeoId = postalAddress.stateProvinceGeoId;
         context.shipToCountryGeoId = postalAddress.countryGeoId;
-        shipToStateProvinceGeo = delegator.findOne("Geo", [geoId : postalAddress.stateProvinceGeoId], false);
+        shipToStateProvinceGeo = from("Geo").where("geoId", postalAddress.stateProvinceGeoId).queryOne();
         if (shipToStateProvinceGeo) {
             context.shipToStateProvinceGeo =  shipToStateProvinceGeo.geoName;
         }
-        shipToCountryProvinceGeo = delegator.findOne("Geo", [geoId : postalAddress.countryGeoId], false);
+        shipToCountryProvinceGeo = from("Geo").where("geoId", postalAddress.countryGeoId).queryOne();
         if (shipToCountryProvinceGeo) {
             context.shipToCountryProvinceGeo =  shipToCountryProvinceGeo.geoName;
         }
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/ViewProfile.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/ViewProfile.groovy
index 18b7ed4..9e0c395 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/ViewProfile.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/customer/ViewProfile.groovy
@@ -31,7 +31,7 @@
 context.productStoreId = productStoreId;
 
 if (userLogin) {
-    profiledefs = delegator.findOne("PartyProfileDefault", [partyId : partyId, productStoreId : productStoreId], false);
+    profiledefs = from("PartyProfileDefault").where("partyId", partyId, "productStoreId", productStoreId).queryOne();
 
     showOld = "true".equals(parameters.SHOW_OLD);
 
@@ -45,7 +45,7 @@
 
     // shipping methods - for default selection
     if (profiledefs?.defaultShipAddr) {
-        shipAddress = delegator.findOne("PostalAddress", [contactMechId : profiledefs.defaultShipAddr], false);
+        shipAddress = from("PostalAddress").where("contactMechId", profiledefs.defaultShipAddr).queryOne();
         if (shipAddress) {
             carrierShipMeths = ProductStoreWorker.getAvailableStoreShippingMethods(delegator, productStoreId, shipAddress, [1], null, 0, 1);
             context.carrierShipMethods = carrierShipMeths;
@@ -55,42 +55,35 @@
     profileSurveys = ProductStoreWorker.getProductSurveys(delegator, productStoreId, null, "CUSTOMER_PROFILE");
     context.surveys = profileSurveys;
 
-    orderBy = ["-entryDate"];
-    findOpts = new EntityFindOptions();
-    findOpts.setMaxRows(5);
     exprs = [EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, partyId)];
     exprs.add(EntityCondition.makeCondition("roleStatusId", EntityOperator.NOT_EQUAL, "COM_ROLE_READ"));
-    condition = EntityCondition.makeCondition(exprs, EntityOperator.AND);
-    messages = delegator.findList("CommunicationEventAndRole", condition, null, orderBy, findOpts, false);
+    messages = from("CommunicationEventAndRole").where(exprs).orderBy("-entryDate").maxRows(5).queryList();
     context.messages = messages;
     context.profileMessages = true;
 
-    partyContent = delegator.findByAnd("ContentRole", [partyId : partyId, roleTypeId : "OWNER"], null, false);
-    partyContent = EntityUtil.filterByDate(partyContent);
+    partyContent = from("ContentRole").where("partyId", partyId, "roleTypeId", "OWNER").filterByDate().queryList();
     context.partyContent = partyContent;
 
-    mimeTypes = delegator.findList("MimeType", null, null, ["description", "mimeTypeId"], null, false);
+    mimeTypes = from("MimeType").orderBy("description", "mimeTypeId").queryList();
     context.mimeTypes = mimeTypes;
 
-    partyContentTypes = delegator.findList("PartyContentType", null, null, ["description"], null, false);
+    partyContentTypes = from("PartyContentType").orderBy("description").queryList();
     context.partyContentTypes = partyContentTypes;
 
     // call the getOrderedSummaryInformation service to get the sub-total of valid orders in last X months
     monthsToInclude = 12;
-    serviceIn = [partyId : partyId, roleTypeId : "PLACING_CUSTOMER", orderTypeId : "SALES_ORDER", statusId : "ORDER_COMPLETED", monthsToInclude : monthsToInclude, userLogin : userLogin];
-    result = dispatcher.runSync("getOrderedSummaryInformation", serviceIn);
+    result = runService('getOrderedSummaryInformation', [partyId : partyId, roleTypeId : "PLACING_CUSTOMER", orderTypeId : "SALES_ORDER", statusId : "ORDER_COMPLETED", monthsToInclude : monthsToInclude, userLogin : userLogin]);
     context.monthsToInclude = monthsToInclude;
     context.totalSubRemainingAmount = result.totalSubRemainingAmount;
     context.totalOrders = result.totalOrders;
 
-    contactListPartyList = delegator.findByAnd("ContactListParty", [partyId : partyId], ["-fromDate"], false);
+    contactListPartyList = from("ContactListParty").where("partyId", partyId).orderBy("-fromDate").queryList();
     // show all, including history, ie don't filter: contactListPartyList = EntityUtil.filterByDate(contactListPartyList, true);
     context.contactListPartyList = contactListPartyList;
 
-    publicContactLists = delegator.findByAnd("ContactList", [isPublic : "Y"], ["contactListName"], false);
+    publicContactLists = from("ContactList").where("isPublic", "Y").orderBy("contactListName").queryList();
     context.publicContactLists = publicContactLists;
 
-    partyAndContactMechList = delegator.findByAnd("PartyAndContactMech", [partyId : partyId], ["-fromDate"], false);
-    partyAndContactMechList = EntityUtil.filterByDate(partyAndContactMechList);
+    partyAndContactMechList = from("PartyAndContactMech").where("partyId", partyId).orderBy("-fromDate").filterByDate().queryList();
     context.partyAndContactMechList = partyAndContactMechList;
 }
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentAddPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentAddPrep.groovy
index 3d48626..e6626a9 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentAddPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentAddPrep.groovy
@@ -54,7 +54,7 @@
 context.contentIdTo = contentIdTo;
 //Debug.logInfo("in contentaddprep, contentIdTo:" + contentIdTo,"");
 //Debug.logInfo("in contentaddprep, paramMap:" + paramMap,"");
-attrList = delegator.findByAnd("ContentAttribute", [contentId : contentIdTo, attrName : "publishOperation"], null, true);
+attrList = from("ContentAttribute").where("contentId", contentIdTo, "attrName", "publishOperation").cache(true).queryList();
 publishOperation = null;
 if (attrList) {
     contentAttribute = attrList.get(0);
@@ -76,7 +76,7 @@
 singleWrapper.putInContext("contentPurpose", contentPurpose);
 singleWrapper.putInContext("forumId", contentIdTo);
 
-forumContent = delegator.findOne("Content", [contentId : contentIdTo], true);
+forumContent = from("Content").where("contentId", contentIdTo).cache(true).queryOne();
 statusId = "CTNT_PUBLISHED";
 if (forumContent) {
     statusId = forumContent.statusId;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentPrep.groovy
index 4c46f0a..3690b25 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentPrep.groovy
@@ -61,7 +61,7 @@
     contentId = currentValue.contentId;
 }
 if (contentId && !currentValue) {
-    currentValue = delegator.findOne("Content", [contentId : contentId], true);
+    currentValue = from("Content").where("contentId", contentId).cache(true).queryOne();
 }
 //Debug.logInfo("in contentprep, currentValue(1):" + currentValue, "");
 //Debug.logInfo("in contentprep, contentId(4):" + contentId, "");
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/CurrentValPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/CurrentValPrep.groovy
index 530503a..58e925e 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/CurrentValPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/CurrentValPrep.groovy
@@ -120,7 +120,7 @@
 currentEntityMap[currentEntityName] = currentPK;
 request.setAttribute("currentPK", currentPK);
 context.currentPK = currentPK;
-currentValue = delegator.findOne(currentPK.getPrimaryKey().getEntityName(), currentPK.getPrimaryKey(), false);
+currentValue = from(currentPK.getPrimaryKey().getEntityName()).where(currentPK.getPrimaryKey()).queryOne();
 context.currentValue = currentValue;
 request.setAttribute("currentValue", currentValue);
 
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/EditAddPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/EditAddPrep.groovy
index 96fa91a..39c6301 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/EditAddPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/EditAddPrep.groovy
@@ -68,7 +68,7 @@
 //Debug.logInfo("in editaddprep, currentValue:" + currentValue,"");
 
 if (!currentValue) {
-    parentValue = delegator.findOne("Content", [contentId : contentIdTo], true);
+    parentValue = from("Content").where("contentId", contentIdTo).cache(true).queryOne();
     currentValue = delegator.makeValue("Content");
     subject =  parentValue.contentName;
     if ("SUMMARY".equals(mapKey)) {
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/PermPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/PermPrep.groovy
index e3a9599..54defd4 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/PermPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/PermPrep.groovy
@@ -102,7 +102,7 @@
 
     if (!currentValue || !"Content".equals(entityName)) {
         if (thisContentId) {
-            currentValue = delegator.findOne("Content", [contentId : thisContentId], false);
+            currentValue = from("Content").where("contentId", thisContentId).queryOne();
         }
     }
     if ("add".equals(mode)) {
@@ -128,7 +128,7 @@
     }
 
     //org.ofbiz.base.util.Debug.logInfo("in permprep, mapIn:" + mapIn, null);
-    result = dispatcher.runSync("checkContentPermission", mapIn);
+    result = runService('checkContentPermission', mapIn);
     permissionStatus = result.permissionStatus;
     //org.ofbiz.base.util.Debug.logInfo("in permprep, permissionStatus:" + permissionStatus, null);
     if ("granted".equals(permissionStatus)) {
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/RespondPermAndPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/RespondPermAndPrep.groovy
index df941e6..22d5a48 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/RespondPermAndPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/RespondPermAndPrep.groovy
@@ -55,7 +55,7 @@
 }
 */
 
-contentToValue = delegator.findOne("Content", [contentId : contentIdTo], false);
+contentToValue = from("Content").where("contentId", contentIdTo).queryOne();
 contentToPurposeList = contentToValue.getRelated("ContentPurpose", null, null, true);
 currentValue = delegator.makeValue("Content", [contentTypeId : "DOCUMENT", statusId : "CTNT_PUBLISHED", privilegeEnumId : "_00_"]);
 
@@ -79,7 +79,7 @@
 mapIn.contentPurposeList = ["RESPONSE"];
 
 //org.ofbiz.base.util.Debug.logInfo("in permprep, mapIn:" + mapIn, null);
-result = dispatcher.runSync("checkContentPermission", mapIn);
+result = runService('checkContentPermission', mapIn);
 permissionStatus = result.permissionStatus;
 //org.ofbiz.base.util.Debug.logInfo("permissionStatus:" + permissionStatus, null);
 if (!"granted".equals(permissionStatus)) {
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ResponsePrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ResponsePrep.groovy
index 1d7801a..dc767ba 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ResponsePrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ResponsePrep.groovy
@@ -63,7 +63,7 @@
 
 // start at 1 to skip webSiteId
 idList.each { id ->
-    webSitePublishPoint = delegator.findOne("WebSitePublishPoint", [contentId : id], true);
+    webSitePublishPoint = from("WebSitePublishPoint").where("contentId", id).cache(true).queryOne();
     siteAncestorList.add(webSitePublishPoint);
 }
 context.siteAncestorList = siteAncestorList;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/BillSettings.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/BillSettings.groovy
index cffffa6..933c388 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/BillSettings.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/BillSettings.groovy
@@ -40,7 +40,7 @@
 request.removeAttribute("_EVENT_MESSAGE_");
 
 if (partyId && !partyId.equals("_NA_")) {
-    party = delegator.findOne("Party", [partyId : partyId], false);
+    party = from("Party").where("partyId", partyId).queryOne();
     person = party.getRelatedOne("Person", false);
     context.party = party;
     context.person = person;
@@ -57,14 +57,12 @@
 
 if (parameters.useShipAddr && cart.getShippingContactMechId()) {
     shippingContactMech = cart.getShippingContactMechId();
-    postalAddress = delegator.findOne("PostalAddress", [contactMechId : shippingContactMech], false);
+    postalAddress = from("PostalAddress").where("contactMechId", shippingContactMech).queryOne();
     context.useEntityFields = "Y";
     context.postalFields = postalAddress;
 
     if (postalAddress && partyId) {
-        partyContactMechs = delegator.findByAnd("PartyContactMech", [partyId : partyId, contactMechId : postalAddress.contactMechId], ["-fromDate"], false);
-        partyContactMechs = EntityUtil.filterByDate(partyContactMechs);
-        partyContactMech = EntityUtil.getFirst(partyContactMechs);
+        partyContactMech = from("PartyContactMech").where("partyId", partyId, "contactMechId", postalAddress.contactMechId).orderBy("-fromDate").filterByDate().queryFirst();
         context.partyContactMech = partyContactMech;
     }
 } else {
@@ -75,7 +73,7 @@
     if (cart.getPaymentMethodIds() ) {
         checkOutPaymentId = cart.getPaymentMethodIds()[0];
         context.checkOutPaymentId = checkOutPaymentId;
-        paymentMethod = delegator.findOne("PaymentMethod", [paymentMethodId : checkOutPaymentId], false);
+        paymentMethod = from("PaymentMethod").where("paymentMethodId", checkOutPaymentId).queryOne();
         account = null;
 
         if ("CREDIT_CARD".equals(paymentMethod.paymentMethodTypeId)) {
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/CheckoutReview.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/CheckoutReview.groovy
index 44bc0c7..7ee31da 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/CheckoutReview.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/CheckoutReview.groovy
@@ -64,7 +64,7 @@
 paymentMethodTypeId = null;
 if (paymentMethodTypeIds) {
     paymentMethodTypeId = paymentMethodTypeIds[0];
-    paymentMethodType = delegator.findOne("PaymentMethodType", [paymentMethodTypeId : paymentMethodTypeId], false);
+    paymentMethodType = from("PaymentMethodType").where("paymentMethodTypeId", paymentMethodTypeId).queryOne();
     context.paymentMethodType = paymentMethodType;
 }
 
@@ -97,7 +97,7 @@
 context.isGift = cart.getIsGift();
 context.currencyUomId = cart.getCurrency();
 
-shipmentMethodType = delegator.findOne("ShipmentMethodType", [shipmentMethodTypeId : cart.getShipmentMethodTypeId()], false);
+shipmentMethodType = from("ShipmentMethodType").where("shipmentMethodTypeId", cart.getShipmentMethodTypeId()).queryOne();
 if (shipmentMethodType) context.shipMethDescription = shipmentMethodType.description;
 
 orh = new OrderReadHelper(orderAdjustments, orderItems);
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/CustSettings.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/CustSettings.groovy
index dd0ee88..6320674 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/CustSettings.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/CustSettings.groovy
@@ -35,7 +35,7 @@
 
     // NOTE: if there was an error, then don't look up and fill in all of this data, just use the values from the previous request (which will be in the parameters Map automagically)
     if (!request.getAttribute("_ERROR_MESSAGE_") && !request.getAttribute("_ERROR_MESSAGE_LIST_")) {
-        person = delegator.findOne("Person", [partyId : partyId], false);
+        person = from("Person").where("partyId", partyId).queryOne();
         if (person) {
             context.callSubmitForm = true;
             // should never be null for the anonymous checkout, but just in case
@@ -68,8 +68,7 @@
         }
 
         // get the Email Address
-        emailPartyContactDetail = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("PartyContactDetailByPurpose",
-                [partyId : partyId, contactMechPurposeTypeId : "PRIMARY_EMAIL"], null, false)));
+        emailPartyContactDetail = from("PartyContactDetailByPurpose").where("partyId", partyId, "contactMechPurposeTypeId", "PRIMARY_EMAIL").filterByDate().queryFirst();
         if (emailPartyContactDetail) {
             parameters.emailContactMechId = emailPartyContactDetail.contactMechId;
             parameters.emailAddress = emailPartyContactDetail.infoString;
@@ -77,8 +76,7 @@
         }
 
         // get the Phone Numbers
-        homePhonePartyContactDetail = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("PartyContactDetailByPurpose",
-                [partyId : partyId, contactMechPurposeTypeId : "PHONE_HOME"], null, false)));
+        homePhonePartyContactDetail = from("PartyContactDetailByPurpose").where("partyId", partyId, "contactMechPurposeTypeId", "PHONE_HOME").filterByDate().queryFirst();
         if (homePhonePartyContactDetail) {
             parameters.homePhoneContactMechId = homePhonePartyContactDetail.contactMechId;
             parameters.homeCountryCode = homePhonePartyContactDetail.countryCode;
@@ -88,8 +86,7 @@
             parameters.homeSol = homePhonePartyContactDetail.allowSolicitation;
         }
 
-        workPhonePartyContactDetail = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("PartyContactDetailByPurpose",
-                [partyId : partyId, contactMechPurposeTypeId : "PHONE_WORK"], null, false)));
+        workPhonePartyContactDetail = from("PartyContactDetailByPurpose").where("partyId", partyId, "contactMechPurposeTypeId", "PHONE_WORK").filterByDate().queryFirst();
         if (workPhonePartyContactDetail) {
             parameters.workPhoneContactMechId = workPhonePartyContactDetail.contactMechId;
             parameters.workCountryCode = workPhonePartyContactDetail.countryCode;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/OptionSettings.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/OptionSettings.groovy
index ba90391..c62fd49 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/OptionSettings.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/OptionSettings.groovy
@@ -40,7 +40,7 @@
 party = null;
 partyId = session.getAttribute("orderPartyId");
 if (partyId) {
-    party = delegator.findOne("Party", [partyId : partyId], false);
+    party = from("Party").where("partyId", partyId).queryOne();
     context.party = party;
 }
 
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/OrderHistory.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/OrderHistory.groovy
index c490e9b..e7b645f 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/OrderHistory.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/OrderHistory.groovy
@@ -22,11 +22,11 @@
 import org.ofbiz.entity.util.*;
 import org.ofbiz.entity.condition.*;
 
-partyRole = delegator.findOne("PartyRole", [partyId : userLogin.partyId, roleTypeId : "SUPPLIER"], false);
+partyRole = from("PartyRole").where("partyId", userLogin.partyId, "roleTypeId", "SUPPLIER").queryOne();
 if (partyRole) {
     if ("SUPPLIER".equals(partyRole.roleTypeId)) {
         /** drop shipper or supplier **/
-        porderRoleCollection = delegator.findByAnd("OrderRole", [partyId : userLogin.partyId, roleTypeId : "SUPPLIER_AGENT"], null, false);
+        porderRoleCollection = from("OrderRole").where("partyId", userLogin.partyId, "roleTypeId", "SUPPLIER_AGENT").queryList();
         porderHeaderList = EntityUtil.orderBy(EntityUtil.filterByAnd(EntityUtil.getRelated("OrderHeader", null, porderRoleCollection, false),
                 [EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "ORDER_REJECTED"),
                  EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "PURCHASE_ORDER")]),
@@ -34,11 +34,10 @@
         context.porderHeaderList = porderHeaderList;
     }
 }
-orderRoleCollection = delegator.findByAnd("OrderRole", [partyId : userLogin.partyId, roleTypeId : "PLACING_CUSTOMER"], null, false);
+orderRoleCollection = from("OrderRole").where("partyId", userLogin.partyId, "roleTypeId", "PLACING_CUSTOMER").queryList();
 orderHeaderList = EntityUtil.orderBy(EntityUtil.filterByAnd(EntityUtil.getRelated("OrderHeader", null, orderRoleCollection, false),
         [EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "ORDER_REJECTED")]), ["orderDate DESC"]);
 context.orderHeaderList = orderHeaderList;
 
-downloadOrderRoleAndProductContentInfoList = delegator.findByAnd("OrderRoleAndProductContentInfo",
-    [partyId : userLogin.partyId, roleTypeId : "PLACING_CUSTOMER", productContentTypeId : "DIGITAL_DOWNLOAD", statusId : "ITEM_COMPLETED"], null, false);
+downloadOrderRoleAndProductContentInfoList = from("OrderRoleAndProductContentInfo").where("partyId", userLogin.partyId, "roleTypeId", "PLACING_CUSTOMER", "productContentTypeId", "DIGITAL_DOWNLOAD", "statusId", "ITEM_COMPLETED").queryList();
 context.downloadOrderRoleAndProductContentInfoList = downloadOrderRoleAndProductContentInfoList;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/OrderStatus.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/OrderStatus.groovy
index b0c4107..f14fd82 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/OrderStatus.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/OrderStatus.groovy
@@ -38,7 +38,7 @@
     // then userLogin is not found when Order Complete Mail is send to user.
     if (!userLogin) {
         if (orderId) {
-            orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+            orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
             orderStatuses = orderHeader.getRelated("OrderStatus", null, null, false);
             filteredOrderStatusList = [];
             extOfflineModeExists = false;
@@ -57,12 +57,12 @@
             if (UtilValidate.isNotEmpty(filteredOrderStatusList)) {
                 if (filteredOrderStatusList.size() < 2) {
                     statusUserLogin = EntityUtil.getFirst(filteredOrderStatusList).statusUserLogin;
-                    userLogin = delegator.findOne("UserLogin", [userLoginId : statusUserLogin], false);
+                    userLogin = from("UserLogin").where("userLoginId", statusUserLogin).queryOne();
                 } else {
                     filteredOrderStatusList.each { orderStatus ->
                         if ("ORDER_COMPLETED".equals(orderStatus.statusId)) {
                             statusUserLogin = orderStatus.statusUserLogin;
-                            userLogin = delegator.findOne("UserLogin", [userLoginId :statusUserLogin], false);
+                            userLogin = from("UserLogin").where("userLoginId", statusUserLogin).queryOne();
                         }
                     }
                 }
@@ -88,7 +88,7 @@
 
 isDemoStore = true;
 if (orderId) {
-    orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+    orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
     if ("PURCHASE_ORDER".equals(orderHeader?.orderTypeId)) {
         //drop shipper or supplier
         roleTypeId = "SUPPLIER_AGENT";
@@ -100,7 +100,7 @@
     // check OrderRole to make sure the user can view this order.  This check must be done for any order which is not anonymously placed and
     // any anonymous order when the allowAnonymousView security flag (see above) is not set to Y, to prevent peeking
     if (orderHeader && (!"anonymous".equals(orderHeader.createdBy) || ("anonymous".equals(orderHeader.createdBy) && !"Y".equals(allowAnonymousView)))) {
-        orderRole = EntityUtil.getFirst(delegator.findByAnd("OrderRole", [orderId : orderId, partyId : partyId, roleTypeId : roleTypeId], null, false));
+        orderRole = from("OrderRole").where("orderId", orderId, "partyId", partyId, "roleTypeId", roleTypeId).queryFirst();
 
         if (!userLogin || !orderRole) {
             context.remove("orderHeader");
@@ -128,9 +128,8 @@
     orderTaxTotal = OrderReadHelper.getAllOrderItemsAdjustmentsTotal(orderItems, orderAdjustments, false, true, false);
     orderTaxTotal = orderTaxTotal.add(OrderReadHelper.calcOrderAdjustments(orderHeaderAdjustments, orderSubTotal, false, true, false));
 
-    placingCustomerOrderRoles = delegator.findByAnd("OrderRole", [orderId : orderId, roleTypeId : roleTypeId], null, false);
-    placingCustomerOrderRole = EntityUtil.getFirst(placingCustomerOrderRoles);
-    placingCustomerPerson = placingCustomerOrderRole == null ? null : delegator.findOne("Person", [partyId : placingCustomerOrderRole.partyId], false);
+    placingCustomerOrderRole = from("OrderRole").where("orderId", orderId, "roleTypeId", roleTypeId).queryFirst();
+    placingCustomerPerson = placingCustomerOrderRole == null ? null : from("Person").where("partyId", placingCustomerOrderRole.partyId).queryOne();
 
     billingAccount = orderHeader.getRelatedOne("BillingAccount", false);
 
@@ -154,15 +153,12 @@
     if (paymentAddress) context.paymentAddress = paymentAddress;
 
     // get Shipment tracking info
-    osisCond = EntityCondition.makeCondition([orderId : orderId], EntityOperator.AND);
-    osisOrder = ["shipmentId", "shipmentRouteSegmentId", "shipmentPackageSeqId"];
-    osisFields = ["shipmentId", "shipmentRouteSegmentId", "carrierPartyId", "shipmentMethodTypeId"] as Set;
-    osisFields.add("shipmentPackageSeqId");
-    osisFields.add("trackingCode");
-    osisFields.add("boxNumber");
-    osisFindOptions = new EntityFindOptions();
-    osisFindOptions.setDistinct(true);
-    orderShipmentInfoSummaryList = delegator.findList("OrderShipmentInfoSummary", osisCond, osisFields, osisOrder, osisFindOptions, false);
+    orderShipmentInfoSummaryList = select("shipmentId", "shipmentRouteSegmentId", "carrierPartyId", "shipmentMethodTypeId","shipmentPackageSeqId","trackingCode","boxNumber")
+                                    .from("OrderShipmentInfoSummary")
+                                    .where("orderId", orderId)
+                                    .orderBy("shipmentId", "shipmentRouteSegmentId", "shipmentPackageSeqId")
+                                    .distinct(true)
+                                    .queryList();
 
     customerPoNumberSet = new TreeSet();
     orderItems.each { orderItemPo ->
@@ -215,6 +211,6 @@
     context.orderShipmentInfoSummaryList = orderShipmentInfoSummaryList;
     context.customerPoNumberSet = customerPoNumberSet;
 
-    orderItemChangeReasons = delegator.findByAnd("Enumeration", [enumTypeId : "ODR_ITM_CH_REASON"], ["sequenceId"], false);
+    orderItemChangeReasons = from("Enumeration").where("enumTypeId", "ODR_ITM_CH_REASON").queryList();
     context.orderItemChangeReasons = orderItemChangeReasons;
 }
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/PaymentInformation.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/PaymentInformation.groovy
index 21c485c..9f5fbbd 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/PaymentInformation.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/PaymentInformation.groovy
@@ -36,7 +36,7 @@
 context.partyId = partyId;
 
 if (partyId && !partyId.equals("_NA_")) {
-    party = delegator.findOne("Party", [partyId : partyId], false);
+    party = from("Party").where("partyId", partyId).queryOne();
     person = party.getRelatedOne("Person", false);
     context.party = party;
     context.person = person;
@@ -47,14 +47,12 @@
 
 if (parameters.useShipAddr && cart.getShippingContactMechId()) {
     shippingContactMech = cart.getShippingContactMechId();
-    postalAddress = delegator.findOne("PostalAddress", [contactMechId : shippingContactMech], false);
+    postalAddress = from("PostalAddress").where("contactMechId", shippingContactMech).queryOne();
     context.useEntityFields = "Y";
     context.postalAddress = postalAddress;
 
     if (postalAddress && partyId) {
-        partyContactMechs = delegator.findByAnd("PartyContactMech", [partyId : partyId, contactMechId : postalAddress.contactMechId], ["-fromDate"], false);
-        partyContactMechs = EntityUtil.filterByDate(partyContactMechs);
-        partyContactMech = EntityUtil.getFirst(partyContactMechs);
+        partyContactMech = from("PartyContactMech").where("partyId", partyId, "contactMechId", postalAddress.contactMechId).orderBy("-fromDate").filterByDate().queryFirst();
         context.partyContactMech = partyContactMech;
     }
 } else {
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/QuickAnonCustSettings.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/QuickAnonCustSettings.groovy
index e9bc456..3c490bd 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/QuickAnonCustSettings.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/QuickAnonCustSettings.groovy
@@ -42,7 +42,7 @@
 
     // NOTE: if there was an error, then don't look up and fill in all of this data, just use the values from the previous request (which will be in the parameters Map automagically)
     if (!request.getAttribute("_ERROR_MESSAGE_") && !request.getAttribute("_ERROR_MESSAGE_LIST_")) {
-        person = delegator.findOne("Person", [partyId : partyId], false);
+        person = from("Person").where("partyId", partyId).queryOne();
         if (person) {
             context.callSubmitForm = true;
             // should never be null for the anonymous checkout, but just in case
@@ -52,8 +52,7 @@
         }
 
         // get the Email Address
-        emailPartyContactDetail = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("PartyContactDetailByPurpose",
-                [partyId : partyId, contactMechPurposeTypeId : "PRIMARY_EMAIL"], null, false)));
+        emailPartyContactDetail = from("PartyContactDetailByPurpose").where("partyId", partyId, "contactMechPurposeTypeId", "PRIMARY_EMAIL").filterByDate().queryFirst();
         if (emailPartyContactDetail) {
             parameters.emailContactMechId = emailPartyContactDetail.contactMechId;
             parameters.emailAddress = emailPartyContactDetail.infoString;
@@ -61,8 +60,7 @@
         }
 
         // get the Phone Numbers
-        homePhonePartyContactDetail = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("PartyContactDetailByPurpose",
-                [partyId : partyId, contactMechPurposeTypeId : "PHONE_HOME"], null, false)));
+        homePhonePartyContactDetail = from("PartyContactDetailByPurpose").where("partyId", partyId, "contactMechPurposeTypeId", "PHONE_HOME").filterByDate().queryFirst();
         if (homePhonePartyContactDetail) {
             parameters.homePhoneContactMechId = homePhonePartyContactDetail.contactMechId;
             parameters.homeCountryCode = homePhonePartyContactDetail.countryCode;
@@ -72,8 +70,7 @@
             parameters.homeSol = homePhonePartyContactDetail.allowSolicitation;
         }
 
-        workPhonePartyContactDetail = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("PartyContactDetailByPurpose",
-                [partyId : partyId, contactMechPurposeTypeId : "PHONE_WORK"], null, false)));
+        workPhonePartyContactDetail = from("PartyContactDetailByPurpose").where(partyId : partyId, contactMechPurposeTypeId : "PHONE_WORK").filterByDate().queryFirst();
         if (workPhonePartyContactDetail) {
             parameters.workPhoneContactMechId = workPhonePartyContactDetail.contactMechId;
             parameters.workCountryCode = workPhonePartyContactDetail.countryCode;
@@ -93,7 +90,7 @@
 request.removeAttribute("_EVENT_MESSAGE_");
 
 if (cartPartyId && !cartPartyId.equals("_NA_")) {
-    cartParty = delegator.findOne("Party", [partyId : cartPartyId], false);
+    cartParty = from("Party").where("partyId", cartPartyId).queryOne();
     if (cartParty) {
         cartPerson = cartParty.getRelatedOne("Person", false);
         context.party = cartParty;
@@ -103,8 +100,7 @@
 
 if (cart && cart.getShippingContactMechId()) {
     shippingContactMechId = cart.getShippingContactMechId();
-    shippingPartyContactDetail = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("PartyContactDetailByPurpose",
-       [partyId : cartPartyId, contactMechId : shippingContactMechId], null, false)));
+    shippingPartyContactDetail = from("PartyContactDetailByPurpose").where("partyId", cartPartyId, "contactMechId", shippingContactMechId).filterByDate().queryFirst();
     parameters.shippingContactMechId = shippingPartyContactDetail.contactMechId;
     context.callSubmitForm = true;
     parameters.shipToName = shippingPartyContactDetail.toName;
@@ -121,7 +117,7 @@
 
 billingContactMechId = session.getAttribute("billingContactMechId");
 if (billingContactMechId) {
-    billPostalAddress = delegator.findOne("PostalAddress", [contactMechId : billingContactMechId], false);
+    billPostalAddress = from("PostalAddress").where("contactMechId", billingContactMechId).queryOne();
     parameters.billingContactMechId = billPostalAddress.contactMechId;
     parameters.billToName = billPostalAddress.toName;
     parameters.billToAttnName = billPostalAddress.attnName;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/QuickAnonOptionSettings.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/QuickAnonOptionSettings.groovy
index 84de8b0..96917d1 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/QuickAnonOptionSettings.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/QuickAnonOptionSettings.groovy
@@ -40,7 +40,7 @@
 party = null;
 partyId = session.getAttribute("orderPartyId");
 if (partyId) {
-    party = delegator.findOne("Party", [partyId : partyId], false);
+    party = from("Party").where("partyId", partyId).queryOne();
     context.party = party;
 }
 
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/RequestReturn.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/RequestReturn.groovy
index c69803c..aaab1b0 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/RequestReturn.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/RequestReturn.groovy
@@ -27,27 +27,27 @@
 party = userLogin.getRelatedOne("Party", false);
 context.party = party;
 
-returnTypes = delegator.findList("ReturnType", null, null, ["sequenceId"], null, false);
+returnTypes = from("ReturnType").orderBy("sequenceId").queryList();
 context.returnTypes = returnTypes;
 
-returnReasons = delegator.findList("ReturnReason", null, null, ["sequenceId"], null, false);
+returnReasons = from("ReturnReason").orderBy("sequenceId").queryList();
 context.returnReasons = returnReasons;
 
 if (orderId) {
-    returnRes = dispatcher.runSync("getReturnableItems", [orderId : orderId]);
+    returnRes = runService('getReturnableItems', [orderId : orderId]);
     context.returnableItems = returnRes.returnableItems;
-    orderHeader = delegator.findOne("OrderHeader", [orderId : orderId], false);
+    orderHeader = from("OrderHeader").where("orderId", orderId).queryOne();
     context.orderHeader = orderHeader;
 }
 
-returnItemTypeMap = delegator.findByAnd("ReturnItemTypeMap", [returnHeaderTypeId : "CUSTOMER_RETURN"], null, false);
+returnItemTypeMap = from("ReturnItemTypeMap").where("returnHeaderTypeId", "CUSTOMER_RETURN").queryList();
 typeMap = new HashMap();
 returnItemTypeMap.each { value -> typeMap[value.returnItemMapKey] = value.returnItemTypeId }
 context.returnItemTypeMap = typeMap;
 
 //put in the return to party information from the order header
 if (orderId) {
-    order = delegator.findOne("OrderHeader", [orderId : orderId], false);
+    order = from("OrderHeader").where("orderId", orderId).queryOne();
     productStore = order.getRelatedOne("ProductStore", false);
     context.toPartyId = productStore.payToPartyId;
 }
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/ShipSettings.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/ShipSettings.groovy
index c3e8260..a01d050 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/ShipSettings.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/ShipSettings.groovy
@@ -32,7 +32,7 @@
 request.removeAttribute("_EVENT_MESSAGE_");
 
 if (partyId && !partyId.equals("_NA_")) {
-    party = delegator.findOne("Party", [partyId : partyId], false);
+    party = from("Party").where("partyId", partyId).queryOne();
     person = party.getRelatedOne("Person", false);
     context.party = party;
     context.person = person;
@@ -40,8 +40,7 @@
 
 if (cart?.getShippingContactMechId()) {
     shippingContactMechId = cart.getShippingContactMechId();
-    shippingPartyContactDetail = EntityUtil.getFirst(EntityUtil.filterByDate(delegator.findByAnd("PartyContactDetailByPurpose",
-        [partyId : partyId, contactMechId : shippingContactMechId], null, false)));
+    shippingPartyContactDetail = from("PartyContactDetailByPurpose").where("partyId", partyId, "contactMechId", shippingContactMechId).filterByDate().queryFirst();
     parameters.shippingContactMechId = shippingPartyContactDetail.contactMechId;
     context.callSubmitForm = true;
 
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/ShipmentStatus.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/ShipmentStatus.groovy
index 13b1727..55757e9 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/ShipmentStatus.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/order/ShipmentStatus.groovy
@@ -25,16 +25,16 @@
 
 shipmentId = parameters.shipmentId;
 if (shipmentId) {
-    shipment = delegator.findOne("Shipment", [shipmentId : shipmentId], false);
-    shipmentItems = delegator.findByAnd("ShipmentItem", [shipmentId : shipmentId], null, false);
+    shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
+    shipmentItems = from("ShipmentItem").where("shipmentId", shipmentId).queryList();
 
     // get Shipment tracking info
-    osisCond = EntityCondition.makeCondition([shipmentId : shipmentId], EntityOperator.AND);
-    osisOrder = ["shipmentId", "shipmentRouteSegmentId", "shipmentPackageSeqId"];
-    osisFields = ["shipmentId", "shipmentRouteSegmentId", "shipmentPackageSeqId", "carrierPartyId", "trackingCode"] as Set;
-    osisFindOptions = new EntityFindOptions();
-    osisFindOptions.setDistinct(true);
-    orderShipmentInfoSummaryList = delegator.findList("OrderShipmentInfoSummary", osisCond, osisFields, osisOrder, osisFindOptions, false);
+    orderShipmentInfoSummaryList = select("shipmentId", "shipmentRouteSegmentId", "shipmentPackageSeqId", "carrierPartyId", "trackingCode")
+                                    .from("OrderShipmentInfoSummary")
+                                    .where("shipmentId", shipmentId)
+                                    .orderBy("shipmentId", "shipmentRouteSegmentId", "shipmentPackageSeqId")
+                                    .distinct()
+                                    .queryList();
 
     context.shipment = shipment;
     context.shipmentItems = shipmentItems;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/shoppinglist/EditShoppingList.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/shoppinglist/EditShoppingList.groovy
index 29dafcd..fe3168d 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/shoppinglist/EditShoppingList.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/shoppinglist/EditShoppingList.groovy
@@ -53,13 +53,13 @@
 exprList = [EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, userLogin.partyId),
         EntityCondition.makeCondition("listName", EntityOperator.NOT_EQUAL, "auto-save")];
 condition = EntityCondition.makeCondition(exprList, EntityOperator.AND);
-allShoppingLists = delegator.findList("ShoppingList", condition, null, ["listName"], null, false);
+allShoppingLists = from("ShoppingList").where(exprList).orderBy("listName").queryList();
 shoppingLists = EntityUtil.filterByAnd(allShoppingLists, [parentShoppingListId : null]);
 context.allShoppingLists = allShoppingLists;
 context.shoppingLists = shoppingLists;
 
 // get all shoppingListTypes
-shoppingListTypes = delegator.findList("ShoppingListType", null, null, ["description"], null, true);
+shoppingListTypes = from("ShoppingListType").orderBy("description").cache(true).queryList();
 context.shoppingListTypes = shoppingListTypes;
 
 // get the shoppingListId for this reqest
@@ -78,7 +78,7 @@
 
 // if we passed a shoppingListId get the shopping list info
 if (shoppingListId) {
-    shoppingList = delegator.findOne("ShoppingList", [shoppingListId : shoppingListId], false);
+    shoppingList = from("ShoppingList").where("shoppingListId", shoppingListId).queryOne();
     context.shoppingList = shoppingList;
 
     if (shoppingList) {
@@ -93,11 +93,8 @@
 
                 product = shoppingListItem.getRelatedOne("Product", true);
 
-                calcPriceInMap = [product : product, quantity : shoppingListItem.quantity, currencyUomId : currencyUomId, userLogin : userLogin];
-                calcPriceInMap.webSiteId = webSiteId;
-                calcPriceInMap.prodCatalogId = prodCatalogId;
-                calcPriceInMap.productStoreId = productStoreId;
-                calcPriceOutMap = dispatcher.runSync("calculateProductPrice", calcPriceInMap);
+                calcPriceOutMap = runService('calculateProductPrice', [product : product, quantity : shoppingListItem.quantity, currencyUomId : currencyUomId, userLogin : userLogin,
+                    webSiteId: webSiteId, prodCatalogId: prodCatalogId, productStoreId: productStoreId]);
                 price = calcPriceOutMap.price;
                 totalPrice = price * shoppingListItem.quantity;
                 // similar code at ShoppingCartItem.java getRentalAdjustment
@@ -164,15 +161,14 @@
         context.shoppingListType = shoppingListType;
 
         // get the child shopping lists of the current list for the logged in user
-        childShoppingLists = delegator.findByAnd("ShoppingList", [partyId : userLogin.partyId, parentShoppingListId : shoppingListId], ["listName"], true);
+        childShoppingLists = from("ShoppingList").where("partyId", userLogin.partyId, "parentShoppingListId", shoppingListId).orderBy("listName").cache(true).queryList();
         // now get prices for each child shopping list...
         if (childShoppingLists) {
             childShoppingListDatas = new ArrayList(childShoppingLists.size());
             childShoppingLists.each { childShoppingList ->
                 childShoppingListData = [:];
 
-                calcListPriceInMap = [shoppingListId : childShoppingList.shoppingListId, prodCatalogId : prodCatalogId, webSiteId : webSiteId, userLogin : userLogin, currencyUomId : currencyUomId];
-                childShoppingListPriceMap = dispatcher.runSync("calculateShoppingListDeepTotalPrice", calcListPriceInMap);
+                childShoppingListPriceMap = runService('calculateShoppingListDeepTotalPrice', [shoppingListId : childShoppingList.shoppingListId, prodCatalogId : prodCatalogId, webSiteId : webSiteId, userLogin : userLogin, currencyUomId : currencyUomId]);
                 totalPrice = childShoppingListPriceMap.totalPrice;
                 shoppingListChildTotal += totalPrice;
 
@@ -205,7 +201,7 @@
                 context.shippingContactMechList = ContactHelper.getContactMech(party, "SHIPPING_LOCATION", "POSTAL_ADDRESS", false);
                 context.paymentMethodList = EntityUtil.filterByDate(party.getRelated("PaymentMethod", null, ["paymentMethodTypeId"], false));
 
-                shipAddress = delegator.findOne("PostalAddress", ["contactMechId" : shoppingList.contactMechId], false);
+                shipAddress = from("PostalAddress").where("contactMechId", shoppingList.contactMechId).queryOne();
                 Debug.log("SL - address : " + shipAddress);
                 if (shipAddress) {
                     listCart = ShoppingListServices.makeShoppingListCart(dispatcher, shoppingListId, locale);
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/catalog/LayeredNavBar.ftl b/specialpurpose/ecommerce/webapp/ecommerce/catalog/LayeredNavBar.ftl
index 4370e9a..b413e53 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/catalog/LayeredNavBar.ftl
+++ b/specialpurpose/ecommerce/webapp/ecommerce/catalog/LayeredNavBar.ftl
@@ -19,7 +19,11 @@
 
 <#if currentSearchCategory??>
   <div id="layeredNav" class="screenlet">
-    <h3>Layered Navigation</h3>
+    <div class="screenlet-title-bar">
+      <ul>
+        <li class="h3">${uiLabelMap.EcommerceLayeredNavigation}</li>
+      </ul>
+    </div>
     <#escape x as x?xml>
       <#if productCategory.productCategoryId != currentSearchCategory.productCategoryId>
         <#assign currentSearchCategoryName = categoryContentWrapper.get("CATEGORY_NAME")?string />
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/catalog/ProductCategories.ftl b/specialpurpose/ecommerce/webapp/ecommerce/catalog/ProductCategories.ftl
index 063cbaf..5b4a30e 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/catalog/ProductCategories.ftl
+++ b/specialpurpose/ecommerce/webapp/ecommerce/catalog/ProductCategories.ftl
@@ -199,7 +199,11 @@
 
 
 <div id="quickadd" class="screenlet">
-    <h3>${uiLabelMap.ProductCategories}</h3>
+    <div class="screenlet-title-bar">
+        <ul>
+            <li class="h3">${uiLabelMap.ProductCategories}</li>
+        </ul>
+    </div>
     <div class="screenlet-body" id="tree">
     </div>
 </div>
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/catalog/minireorderprods.ftl b/specialpurpose/ecommerce/webapp/ecommerce/catalog/minireorderprods.ftl
index 451a888..1032652 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/catalog/minireorderprods.ftl
+++ b/specialpurpose/ecommerce/webapp/ecommerce/catalog/minireorderprods.ftl
@@ -18,7 +18,11 @@
 -->
 <#if reorderProducts?has_content>
 <div id ="minireorderprods" class="screenlet">
-    <h3>${uiLabelMap.ProductQuickReorder}...</h3>
+    <div class="screenlet-title-bar">
+        <ul>
+            <li class="h3">${uiLabelMap.ProductQuickReorder}...</li>
+        </ul>
+    </div>
     <div class="screenlet-body">
         <#list reorderProducts as miniProduct>
           <div>
diff --git a/specialpurpose/ecommerce/widget/CatalogScreens.xml b/specialpurpose/ecommerce/widget/CatalogScreens.xml
index 316f7cf..8afaec5 100644
--- a/specialpurpose/ecommerce/widget/CatalogScreens.xml
+++ b/specialpurpose/ecommerce/widget/CatalogScreens.xml
@@ -475,6 +475,9 @@
     </screen>
     <screen name="LayeredNavBar">
         <section>
+            <actions>
+                <property-map resource="EcommerceUiLabels" map-name="uiLabelMap" global="true"/>
+            </actions>
             <widgets>
                 <platform-specific><html><html-template location="component://ecommerce/webapp/ecommerce/catalog/LayeredNavBar.ftl"/></html></platform-specific>
             </widgets>
diff --git a/specialpurpose/ecommerce/widget/ContentForms.xml b/specialpurpose/ecommerce/widget/ContentForms.xml
index c7c3db9..fe30d53 100644
--- a/specialpurpose/ecommerce/widget/ContentForms.xml
+++ b/specialpurpose/ecommerce/widget/ContentForms.xml
@@ -37,7 +37,7 @@
             </hyperlink>
         </field>
         <field name="contentId"><display/></field>
-        <field name="dataResourceId"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><display/></field>
         <field name="contentName"><display/></field>
     </form>
 </forms>
diff --git a/specialpurpose/ecommerce/widget/ForumForms.xml b/specialpurpose/ecommerce/widget/ForumForms.xml
index dcae637..94cd59a 100644
--- a/specialpurpose/ecommerce/widget/ForumForms.xml
+++ b/specialpurpose/ecommerce/widget/ForumForms.xml
@@ -43,7 +43,7 @@
         <field name="imageData" >
             <file />
         </field>
-        <field name="dataResourceId" >
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" >
             <drop-down allow-empty="false" no-current-selected-key="TEMPLATE_TEXT_ONLY">
                 <option key="TEMPLATE_TEXT_ONLY" description="${uiLabelMap.EcommerceTextOnly}"/>
                 <option key="TEMPLATE_IMAGE_CENTERED" description="${uiLabelMap.EcommerceImageCenteredAbove}"/>
@@ -150,7 +150,7 @@
        <field name="summaryData" >
                 <ignored/>
         </field>
-        <field name="dataResourceId" >
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" >
             <display />
         </field>
         <field name="ftlContentId" position="1">
@@ -179,7 +179,7 @@
         <field name="caContentAssocTypeId" title="${uiLabelMap.FormFieldTitle_contentAssocTypeId}" ><text-find/></field>
         <field name="caFromDate" title="${uiLabelMap.CommonFromDate}" ><date-find/></field>
         <field name="contentId"><text-find/></field>
-        <field name="dataResourceId"><text-find/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><text-find/></field>
         <field name="contentName"><text-find/></field>
         <field name="submitButton" title="${uiLabelMap.CommonFind}" widget-style="smallSubmit"><submit button-type="button"/></field>
 <!--
@@ -216,7 +216,7 @@
         <field name="caFromDate" title="From Date" ><display/></field>
 -->
         <field name="contentId"><display/></field>
-        <field name="dataResourceId"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><display/></field>
         <field name="contentName"><display/></field>
     </form>
 
@@ -225,7 +225,7 @@
         <field name="imageData" >
             <file />
         </field>
-        <field name="dataResourceId" >
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" >
             <drop-down allow-empty="false" no-current-selected-key="TEMPLATE_TEXT_ONLY">
                 <option key="TEMPLATE_TEXT_ONLY" description="${uiLabelMap.EcommerceTextOnly}"/>
                 <option key="TEMPLATE_IMAGE_CENTERED" description="${uiLabelMap.EcommerceImageCenteredAbove}"/>
@@ -337,7 +337,7 @@
                 <entity-options description="${description}" entity-name="ContentType" key-field-name="contentTypeId"/>
             </drop-down>
         </field>
-        <field name="dataResourceId">
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}">
             <drop-down allow-empty="false" no-current-selected-key="TEMPLATE_TEXT_ONLY">
                 <option key="TEMPLATE_TEXT_ONLY" description="${uiLabelMap.EcommerceTextOnly}"/>
                 <option key="TEMPLATE_IMAGE_CENTERED" description="${uiLabelMap.EcommerceImageCenteredAbove}"/>
@@ -386,7 +386,7 @@
     <form name="DataResourceMaster" target="createDataResource" title="" type="single" default-map-name="currentValue"
         default-title-style="tableheadtext" default-widget-style="inputBox">
         <auto-fields-entity entity-name="DataResource" default-field-type="edit"/>
-        <field name="dataResourceId"></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"></field>
         <field name="dataResourceTypeId">
             <drop-down allow-empty="true">
                 <entity-options description="${description}" entity-name="DataResourceType" key-field-name="dataResourceTypeId"/>
@@ -429,7 +429,7 @@
     </form>
     <form name="EditDataResourceText" target="updateDataResourceText" title="" type="single" extends="DataResourceMaster"
         default-title-style="tableheadtext" default-widget-style="inputBox">
-        <field name="dataResourceId"><display/></field>
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><display/></field>
         <field name="dataResourceTypeId"><hidden value="ELECTRONIC_TEXT"/></field>
         <field name="dataResourceTypeIdDisplay" title="${uiLabelMap.CommonType}" field-name="dataResourceTypeId" >
             <display description="ELECTRONIC_TEXT" also-hidden="false"/>
@@ -439,7 +439,7 @@
     </form>
     <form name="ImageUpload" target="uploadImage" title="" type="upload"
         default-title-style="tableheadtext" default-widget-style="inputBox">
-        <field name="dataResourceId" >
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" >
             <display description="${currentValue.dataResourceId}"/>
         </field>
         <field name="objectInfo" title="${uiLabelMap.EcommerceImageFileName}">
@@ -457,7 +457,7 @@
         <field name="imageData" >
             <file />
         </field>
-        <field name="dataResourceId" >
+        <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}" >
             <drop-down allow-empty="false" no-current-selected-key="TEMPLATE_TEXT_ONLY">
                 <option key="TEMPLATE_TEXT_ONLY" description="${uiLabelMap.EcommerceTextOnly}"/>
                 <option key="TEMPLATE_IMAGE_CENTERED" description="${uiLabelMap.EcommerceImageCenteredAbove}"/>
diff --git a/specialpurpose/ecommerce/widget/ForumScreens.xml b/specialpurpose/ecommerce/widget/ForumScreens.xml
index 262e5fa..c3517ed 100644
--- a/specialpurpose/ecommerce/widget/ForumScreens.xml
+++ b/specialpurpose/ecommerce/widget/ForumScreens.xml
@@ -85,7 +85,7 @@
                                 <label style="head1" text="${uiLabelMap.EcommerceMessageListForForum} ${forum.description}"/>
                                 <section>
                                     <condition>
-                                        <if-has-permission permission="CONTENTMGR" action="CREATE"/>
+                                        <if-has-permission permission="CONTENTMGR" action="_CREATE"/>
                                     </condition>
                                     <widgets>
                                         <!-- old link converted during URLs securing, seems busted... no time to look at detail...-->
@@ -137,7 +137,7 @@
                         </container>
                         <section>
                             <condition>
-                                <if-has-permission permission="CONTENTMGR" action="CREATE"/>
+                                <if-has-permission permission="CONTENTMGR" action="_CREATE"/>
                             </condition>
                             <widgets>
                                 <label style="blogheader">${uiLabelMap.EcommerceBlogAddResponse}</label>
diff --git a/specialpurpose/ecommerce/widget/ForumTrees.xml b/specialpurpose/ecommerce/widget/ForumTrees.xml
index 8f0813f..5418af2 100644
--- a/specialpurpose/ecommerce/widget/ForumTrees.xml
+++ b/specialpurpose/ecommerce/widget/ForumTrees.xml
@@ -21,7 +21,7 @@
 <trees xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/widget-tree.xsd">
 
-    <tree name="ResponseTree" root-node-name="node-root"
+    <tree name="ResponseTree" entity-name="Content" root-node-name="node-root"
         default-render-style="simple" default-wrap-style="responseTreeWrapper">
         <node name="node-root" >
             <entity-one entity-name="Content"  use-cache="false" value-field="rsp">
diff --git a/specialpurpose/ecommerce/widget/blog/BlogTrees.xml b/specialpurpose/ecommerce/widget/blog/BlogTrees.xml
index e5e81b8..5ccdb81 100644
--- a/specialpurpose/ecommerce/widget/blog/BlogTrees.xml
+++ b/specialpurpose/ecommerce/widget/blog/BlogTrees.xml
@@ -19,7 +19,7 @@
   -->
 
 <trees xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/widget-tree.xsd">
-    <tree name="ResponseTree" root-node-name="node-root" default-render-style="simple" default-wrap-style="responseTreeWrapper">
+    <tree name="ResponseTree" entity-name="Content" root-node-name="node-root" default-render-style="simple" default-wrap-style="responseTreeWrapper">
         <node name="node-root" entry-name="rsp">
             <entity-one entity-name="Content" use-cache="false" value-field="rsp">
                 <field-map field-name="contentId" from-field="rootEntityId"/>
diff --git a/specialpurpose/example/webapp/example/WEB-INF/actions/includes/FindExampleFeatures.groovy b/specialpurpose/example/webapp/example/WEB-INF/actions/includes/FindExampleFeatures.groovy
index b324e27..0ac8394 100644
--- a/specialpurpose/example/webapp/example/WEB-INF/actions/includes/FindExampleFeatures.groovy
+++ b/specialpurpose/example/webapp/example/WEB-INF/actions/includes/FindExampleFeatures.groovy
@@ -36,8 +36,7 @@
 
 autocompleteOptions = [];
 if (andExprs) {
-    entityConditionList = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-    autocompleteOptions = delegator.findList("ExampleFeature", entityConditionList, ['exampleFeatureId', 'description'] as Set, ['-exampleFeatureId'], null, false);
+    autocompleteOptions = select("exampleFeatureId", "description").from("ExampleFeature").where(andExprs).orderBy("-exampleFeatureId").queryList();
     //context.autocompleteOptions = autocompleteOptions;
     request.setAttribute("autocompleteOptions", autocompleteOptions);
 }
diff --git a/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/FilterProducts.groovy b/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/FilterProducts.groovy
index e8441b6..149128b 100644
--- a/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/FilterProducts.groovy
+++ b/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/FilterProducts.groovy
@@ -27,7 +27,7 @@
 
 defaultLocaleString = "";
 if (parameters.productStoreId) {
-    productStore = delegator.findByAnd("ProductStore", ["productStoreId":parameters.productStoreId], null, false);
+    productStore = from("ProductStore").where("productStoreId", parameters.productStoreId).queryList();
     defaultLocaleString = productStore[0].defaultLocaleString.toString()
 }
 active = parameters.ACTIVE_PRODUCT;
@@ -37,12 +37,11 @@
 if (UtilValidate.isNotEmpty(productIds) && ("Y".equals(active) || "Y".equals(notSynced))) {
     for (int i = 0; i < productIds.size(); i++) {
         productId = productIds[i];
-        productCategoryMembers = delegator.findByAnd("ProductCategoryMember", [productId : productId], null, false);
-        productCategoryMember = EntityUtil.getFirst(productCategoryMembers);
+        productCategoryMember = from("ProductCategoryMember").where("productId", productId).queryFirst();
         if (UtilValidate.isNotEmpty(productCategoryMember)) {
             if ("Y".equals(active) && "Y".equals(notSynced)) {
                 thruDate = productCategoryMember.get("thruDate");
-                goodIdentification = delegator.findOne("GoodIdentification", [productId : productId, goodIdentificationTypeId : "GOOGLE_ID_" + defaultLocaleString], false);
+                goodIdentification = from("GoodIdentification").where("productId", productId, "goodIdentificationTypeId", "GOOGLE_ID_" + defaultLocaleString).queryOne();
                 if (UtilValidate.isEmpty(thruDate) && UtilValidate.isEmpty(goodIdentification)) {
                     productList.add(productId);
                 }
@@ -53,7 +52,7 @@
                 }
                 parameters.GOOGLE_SYNCED = "N"
             } else if ("Y".equals(notSynced)) {
-                goodIdentification = delegator.findOne("GoodIdentification", [productId : productId, goodIdentificationTypeId : "GOOGLE_ID_" + defaultLocaleString], false);
+                goodIdentification = from("GoodIdentification").where("productId", productId, "goodIdentificationTypeId", "GOOGLE_ID_" + defaultLocaleString).queryOne();
                 if (UtilValidate.isEmpty(goodIdentification)) {
                     productList.add(productId);
                 }
@@ -71,8 +70,8 @@
 def notDiscontProdList = []
 if(parameters.DISCONTINUED_PRODUCT == 'Y'){
     productIds.each { value ->
-        def stockIsZero = dispatcher.runSync("isStoreInventoryAvailable", ["productId": value, "productStoreId": parameters.productStoreId, "quantity": BigDecimal.valueOf(1.00)]);
-        def thisProduct = delegator.findOne("Product", [productId : value], false);
+        def stockIsZero = runService('isStoreInventoryAvailable', ["productId": value, "productStoreId": parameters.productStoreId, "quantity": BigDecimal.valueOf(1.00)]);
+        def thisProduct = from("Product").where("productId", value).queryOne();
         if (stockIsZero.get("available") == 'Y'){
             notDiscontProdList.add(value);
         }else {
diff --git a/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/GoogleBaseAdvancedSearch.groovy b/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/GoogleBaseAdvancedSearch.groovy
index 5125715..a9ee417 100644
--- a/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/GoogleBaseAdvancedSearch.groovy
+++ b/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/GoogleBaseAdvancedSearch.groovy
@@ -31,7 +31,7 @@
 } else {
     productStoreId = ProductStoreWorker.getProductStoreId(request);
 }
-googleBaseConfigList = delegator.findList("GoogleBaseConfig", null, null, null, null, false);
+googleBaseConfigList = from("GoogleBaseConfig").queryList();
 if (!productStoreId) {
     googleBaseProductStore = EntityUtil.getFirst(googleBaseConfigList);
     productStoreId = googleBaseProductStore.productStoreId;
@@ -40,7 +40,7 @@
     productStoreCatalogs = CatalogWorker.getStoreCatalogs(delegator, productStoreId);
     if (productStoreCatalogs) {
         productStoreCatalogs.each { productStoreCatalog ->
-            prodCatalog = delegator.findOne("ProdCatalog", [prodCatalogId : productStoreCatalog.prodCatalogId], true);
+            prodCatalog = from("ProdCatalog").where("prodCatalogId", productStoreCatalog.prodCatalogId).cache(true).queryOne();
             prodCatalogList.add(prodCatalog);
         }
     }
diff --git a/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/autoUpdateConfig.groovy b/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/autoUpdateConfig.groovy
index d161afc..b60c431 100644
--- a/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/autoUpdateConfig.groovy
+++ b/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/autoUpdateConfig.groovy
@@ -17,30 +17,30 @@
  * under the License.
  */
 import javolution.util.FastList
-import org.ofbiz.base.util.UtilProperties
+import org.ofbiz.entity.util.EntityUtilProperties
 
 configList = []
-str = UtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStoreId")
+str = EntityUtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStoreId", delegator)
 productStoreIds = str.split(",")
-str = UtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.option.outOfStock")
+str = EntityUtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.option.outOfStock", delegator)
 outOfStock = str.split(",")
-str = UtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.option.backInStock")
+str = EntityUtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.option.backInStock", delegator)
 backInStock = str.split(",")
-str = UtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.webSiteUrl")
+str = EntityUtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.webSiteUrl", delegator)
 webSiteUrl = str.split(",")
-str = UtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.actionType")
+str = EntityUtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.actionType", delegator)
 actionType = str.split(",")
-str = UtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.statusId")
+str = EntityUtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.statusId", delegator)
 statusId = str.split(",")
-str = UtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.testMode")
+str = EntityUtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.testMode", delegator)
 testMode = str.split(",")
-str = UtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.webSiteMountPoint")
+str = EntityUtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.webSiteMountPoint", delegator)
 webSiteMountPoint = str.split(",")
-str = UtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.countryCode")
+str = EntityUtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.countryCode", delegator)
 countryCode = str.split(",")
-str = UtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.trackingCodeId")
+str = EntityUtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.trackingCodeId", delegator)
 trackingCodeId = str.split(",")
-str = UtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.allowRecommended")
+str = EntityUtilProperties.getPropertyValue("autoUpdateToGoogleBase.properties", "autoUpdateGoogleBase.productStore.allowRecommended", delegator)
 allowRecommended = str.split(",")
 
 productStoreIds.eachWithIndex{ productStoreId, i ->
diff --git a/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/googlebaseDivideList.groovy b/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/googlebaseDivideList.groovy
index 3276f50..1afb341 100644
--- a/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/googlebaseDivideList.groovy
+++ b/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/googlebaseDivideList.groovy
@@ -20,7 +20,7 @@
 // productList.unique() like distinct sql command, return string type.
 def productUniqueStr = productList.unique();
 def productUniqueStrList = productUniqueStr.toList();
-def googleBaseList = delegator.findByAnd("GoodIdentification",["goodIdentificationTypeId":"GOOGLE_ID_" + productStore.defaultLocaleString], null, false);
+def googleBaseList = from("GoodIdentification").where("goodIdentificationTypeId", "GOOGLE_ID_" + productStore.defaultLocaleString).queryList();
 // find product is existed in google base.
 def notNeededList = productUniqueStrList - googleBaseList.productId;
 def resultList = productUniqueStrList - notNeededList;
diff --git a/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/productsExportToGoogle.groovy b/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/productsExportToGoogle.groovy
index 823e1cd..7a9dff1 100644
--- a/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/productsExportToGoogle.groovy
+++ b/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/productsExportToGoogle.groovy
@@ -28,9 +28,9 @@
 webSite = null;
 if (parameters.productStoreId) {
     productStoreId = parameters.productStoreId;
-    webSiteList = delegator.findList("WebSite", EntityCondition.makeCondition("productStoreId", EntityOperator.EQUALS, productStoreId), null, null, null, false);
+    webSiteList = from("WebSite").where("productStoreId", productStoreId).queryList();
     if (parameters.webSiteId) {
-        webSite = delegator.findOne("WebSite", ["webSiteId" : parameters.webSiteId], true);
+        webSite = from("WebSite").where("webSiteId", parameters.webSiteId).cache(true).queryOne();
         context.webSiteId = parameters.webSiteId;
     } else if (webSiteList) {
         webSite = EntityUtil.getFirst(webSiteList);
@@ -43,7 +43,7 @@
 }
 
 if (parameters.productStoreId) {
-    productStore = delegator.findByAnd("ProductStore", ["productStoreId":parameters.productStoreId], null, false);
+    productStore = from("ProductStore").where("productStoreId", parameters.productStoreId).queryList();
     str = productStore[0].defaultLocaleString.toString().toUpperCase();
     localeString = str.substring(str.length()-2, str.length());
     if(localeString.equals("US")){
diff --git a/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/productsToGooglebase.groovy b/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/productsToGooglebase.groovy
index 6487c9e..e81a5bc 100644
--- a/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/productsToGooglebase.groovy
+++ b/specialpurpose/googlebase/webapp/googlebase/WEB-INF/actions/productsToGooglebase.groovy
@@ -33,12 +33,12 @@
 if (parameters.productStoreId) {
     productStoreId = parameters.productStoreId;
 }
-googleBaseConfigList = delegator.findByAnd("GoogleBaseConfig",["productStoreId":productStoreId], null, false);
+googleBaseConfigList = from("GoogleBaseConfig").where("productStoreId", productStoreId).queryList();
 if (productStoreId) {
     productStoreCatalogs = CatalogWorker.getStoreCatalogs(delegator, productStoreId);
     if (productStoreCatalogs) {
         productStoreCatalogs.each { productStoreCatalog ->
-            prodCatalog = delegator.findOne("ProdCatalog", [prodCatalogId : productStoreCatalog.prodCatalogId], true);
+            prodCatalog = from("ProdCatalog").where("prodCatalogId", productStoreCatalog.prodCatalogId).cache(true).queryOne();
             prodCatalogList.add(prodCatalog);
         }
     }
@@ -46,10 +46,10 @@
 currentCatalogId = null;
 prodCatalogList.each { prodCatalogList -> 
     currentCatalogId = prodCatalogList.prodCatalogId
-    prodCatalogCategoryList = delegator.findByAnd("ProdCatalogCategory",["prodCatalogId":currentCatalogId, "prodCatalogCategoryTypeId":"PCCT_BROWSE_ROOT"], null, false);
+    prodCatalogCategoryList = from("ProdCatalogCategory").where("prodCatalogId", currentCatalogId, "prodCatalogCategoryTypeId", "PCCT_BROWSE_ROOT").queryList();
     topCategory = prodCatalogCategoryList.productCategoryId[0];
     if (topCategory){
-        relatedCategories = dispatcher.runSync("getRelatedCategories", [parentProductCategoryId: topCategory, userLogin: userLogin]);
+        relatedCategories = runService('getRelatedCategories', [parentProductCategoryId: topCategory]);
         categoryList = relatedCategories.categories
     } else {
         categoryIdsTemp.clear()
diff --git a/specialpurpose/hhfacility/webapp/hhfacility/WEB-INF/actions/Facilities.groovy b/specialpurpose/hhfacility/webapp/hhfacility/WEB-INF/actions/Facilities.groovy
index 1e9197d..dcf3611 100644
--- a/specialpurpose/hhfacility/webapp/hhfacility/WEB-INF/actions/Facilities.groovy
+++ b/specialpurpose/hhfacility/webapp/hhfacility/WEB-INF/actions/Facilities.groovy
@@ -17,4 +17,4 @@
  * under the License.
  */
 
-context.facilities = delegator.findList("Facility", null, null, null, null, false);
+context.facilities = from("Facility").queryList();
diff --git a/specialpurpose/hhfacility/webapp/hhfacility/WEB-INF/actions/ProductStockTake.groovy b/specialpurpose/hhfacility/webapp/hhfacility/WEB-INF/actions/ProductStockTake.groovy
index 61b3388..929fa52 100644
--- a/specialpurpose/hhfacility/webapp/hhfacility/WEB-INF/actions/ProductStockTake.groovy
+++ b/specialpurpose/hhfacility/webapp/hhfacility/WEB-INF/actions/ProductStockTake.groovy
@@ -27,11 +27,11 @@
 }
 
 if (productId) {
-    product = delegator.findOne("Product", [productId : productId], true);
+    product = from("Product").where("productId", productId).cache(true).queryOne();
     context.product = product;
 
     facilityId = request.getParameter("facilityId");
-    resultOutput = dispatcher.runSync("getInventoryAvailableByFacility", [productId : productId, facilityId : facilityId]);
+    resultOutput = runService('getInventoryAvailableByFacility', [productId : productId, facilityId : facilityId]);
     quantitySummary = FastMap.newInstance();
     quantitySummary.facilityId = facilityId;
     quantitySummary.atp_qoh = ((Double)resultOutput.availableToPromiseTotal).intValue() + " / " +
@@ -40,8 +40,7 @@
 
     // For now this just generates a visual list of locations set against the product for this facility.
     // todo: Will need to be able to edit and change these values at some point in the future.
-    productFacilityLocList = delegator.findList("ProductFacilityLocation",
-            EntityCondition.makeCondition([productId : productId, facilityId : facilityId]), null, null, null, false);
+    productFacilityLocList = from("ProductFacilityLocation").where("productId", productId, "facilityId", facilityId).queryList();
     facStr = null;
     productFacilityLocList.each { facilityLoc ->
         if (!facStr) {
@@ -55,8 +54,7 @@
 
     // Now we build a list of locations for inventory items against the facility.
     // todo: change this to a select from inv_items where productId and facilityId matches distinct (locationSeqId).
-    invItemList = delegator.findList("InventoryItem",
-            EntityCondition.makeCondition([productId : productId, facilityId : facilityId]), null, null, null, false);
+    invItemList = from("InventoryItem").where("productId", productId, "facilityId", facilityId).queryList();
 
     locations = FastMap.newInstance();
 
@@ -80,7 +78,7 @@
     locationsIter = locations.keySet().iterator();
     while (locationsIter.hasNext()) {
         location = locationsIter.next();
-        resultOutput = dispatcher.runSync("getInventoryAvailableByLocation", [productId : productId, facilityId : facilityId, locationSeqId : location]);
+        resultOutput = runService('getInventoryAvailableByLocation', [productId : productId, facilityId : facilityId, locationSeqId : location]);
         quantitySummary = FastMap.newInstance();
         quantitySummary.productId = productId;
         quantitySummary.facilityId = facilityId;
diff --git a/specialpurpose/ldap/src/org/ofbiz/ldap/LdapLoginWorker.java b/specialpurpose/ldap/src/org/ofbiz/ldap/LdapLoginWorker.java
index 197d276..186f9a4 100644
--- a/specialpurpose/ldap/src/org/ofbiz/ldap/LdapLoginWorker.java
+++ b/specialpurpose/ldap/src/org/ofbiz/ldap/LdapLoginWorker.java
@@ -94,7 +94,7 @@
                 }
             }
 
-            if (!hasBasePermission(userLogin, request) || isFlaggedLoggedOut(userLogin) || hasLdapLoggedOut) {
+            if (!hasBasePermission(userLogin, request) || isFlaggedLoggedOut(userLogin, userLogin.getDelegator()) || hasLdapLoggedOut) {
                 Debug.logInfo("User does not have permission or is flagged as logged out", module);
                 doBasicLogout(userLogin, request, response);
                 userLogin = null;
diff --git a/specialpurpose/lucene/webapp/content/WEB-INF/actions/IndexProducts.groovy b/specialpurpose/lucene/webapp/content/WEB-INF/actions/IndexProducts.groovy
index 694423a..44ea2b8 100644
--- a/specialpurpose/lucene/webapp/content/WEB-INF/actions/IndexProducts.groovy
+++ b/specialpurpose/lucene/webapp/content/WEB-INF/actions/IndexProducts.groovy
@@ -29,7 +29,7 @@
     beganTransaction = TransactionUtil.begin()
     EntityListIterator products
     try {
-        products = delegator.find('Product', null, null, new TreeSet(['productId']), null, null)
+        products = select("productId").from("Product").queryIterator();
         while (product = products.next()) {
             pi.queue(new ProductDocument(product.productId))
             productsCounter++
diff --git a/specialpurpose/lucene/webapp/content/WEB-INF/actions/Search.groovy b/specialpurpose/lucene/webapp/content/WEB-INF/actions/Search.groovy
index 9ce77bc..00ad3d2 100644
--- a/specialpurpose/lucene/webapp/content/WEB-INF/actions/Search.groovy
+++ b/specialpurpose/lucene/webapp/content/WEB-INF/actions/Search.groovy
@@ -102,7 +102,7 @@
     for (int start = 0; start < collector.getTotalHits(); start++) {
         Document doc = searcher.doc(hits[start].doc)
         contentId = doc.get("contentId");
-        content = delegator.findOne("Content", [contentId : contentId], true);
+        content = from("Content").where("contentId", contentId).cache(true).queryOne();
         if (!hitSet.contains(contentId)) {
             contentList.add(content);
             hitSet.add(contentId);
diff --git a/specialpurpose/lucene/webapp/content/WEB-INF/actions/SearchProducts.groovy b/specialpurpose/lucene/webapp/content/WEB-INF/actions/SearchProducts.groovy
index d20ad5e..c223e95 100644
--- a/specialpurpose/lucene/webapp/content/WEB-INF/actions/SearchProducts.groovy
+++ b/specialpurpose/lucene/webapp/content/WEB-INF/actions/SearchProducts.groovy
@@ -64,7 +64,7 @@
     hits.each { hit ->
         Document doc = searcher.doc(hit.doc)
         productId = doc.productId
-        product = delegator.findOne("Product", [productId : productId], true)
+        product = from("Product").where("productId", productId).cache(true).queryOne();
         if (product) {
             productList.add(product)
         }
diff --git a/specialpurpose/oagis/src/org/ofbiz/oagis/OagisInventoryServices.java b/specialpurpose/oagis/src/org/ofbiz/oagis/OagisInventoryServices.java
index bcbffc2..23a60c9 100644
--- a/specialpurpose/oagis/src/org/ofbiz/oagis/OagisInventoryServices.java
+++ b/specialpurpose/oagis/src/org/ofbiz/oagis/OagisInventoryServices.java
@@ -59,7 +59,7 @@
     public static final String resource = "OagisUiLabels";
     public static final Double doubleZero = new Double(0.0);
     public static final Double doubleOne = new Double(1.0);
-    public static final String syncInventoryFacilityId = UtilProperties.getPropertyValue("oagis.properties", "Oagis.Warehouse.SyncInventoryFacilityId");
+    
 
     public static Map<String, Object> oagisReceiveSyncInventory(DispatchContext ctx, Map<String, Object> context) {
         Document doc = (Document) context.get("document");
@@ -69,7 +69,7 @@
         Locale locale = (Locale) context.get("locale");
         List<Map<String, String>> errorMapList = FastList.newInstance();
         List<Map<String, Object>> inventoryMapList = FastList.newInstance();
-
+        final String syncInventoryFacilityId = EntityUtilProperties.getPropertyValue("oagis.properties", "Oagis.Warehouse.SyncInventoryFacilityId", delegator);
         GenericValue userLogin = null;
         try {
             userLogin = EntityQuery.use(delegator).from("UserLogin").where("userLoginId", "system").queryOne();
diff --git a/specialpurpose/oagis/src/org/ofbiz/oagis/OagisServices.java b/specialpurpose/oagis/src/org/ofbiz/oagis/OagisServices.java
index 0c2c483..eb308d3 100644
--- a/specialpurpose/oagis/src/org/ofbiz/oagis/OagisServices.java
+++ b/specialpurpose/oagis/src/org/ofbiz/oagis/OagisServices.java
@@ -82,10 +82,6 @@
 
     public static final String resource = "OagisUiLabels";
 
-    public static final String certAlias = UtilProperties.getPropertyValue("oagis.properties", "auth.client.certificate.alias");
-    public static final String basicAuthUsername = UtilProperties.getPropertyValue("oagis.properties", "auth.basic.username");
-    public static final String basicAuthPassword = UtilProperties.getPropertyValue("oagis.properties", "auth.basic.password");
-
     public static final boolean debugSaveXmlOut = "true".equals(UtilProperties.getPropertyValue("oagis.properties", "Oagis.Debug.Save.Xml.Out"));
     public static final boolean debugSaveXmlIn = "true".equals(UtilProperties.getPropertyValue("oagis.properties", "Oagis.Debug.Save.Xml.In"));
 
@@ -108,7 +104,7 @@
         Locale locale = (Locale) context.get("locale");
         String errorReferenceId = (String) context.get("referenceId");
         List<Map<String, String>> errorMapList = UtilGenerics.checkList(context.get("errorMapList"));
-
+        
         String sendToUrl = (String) context.get("sendToUrl");
         if (UtilValidate.isEmpty(sendToUrl)) {
             sendToUrl = EntityUtilProperties.getPropertyValue("oagis.properties", "url.send.confirmBod", delegator);
@@ -219,7 +215,7 @@
             Debug.logError(e, errMsg, module);
         }
 
-        Map<String, Object> sendMessageReturn = OagisServices.sendMessageText(outText, out, sendToUrl, saveToDirectory, saveToFilename, locale);
+        Map<String, Object> sendMessageReturn = OagisServices.sendMessageText(outText, out, sendToUrl, saveToDirectory, saveToFilename, locale, delegator);
         if (sendMessageReturn != null) {
             return sendMessageReturn;
         }
@@ -679,8 +675,11 @@
         return result;
     }
 
-    public static Map<String, Object> sendMessageText(String outText, OutputStream out, String sendToUrl, String saveToDirectory, String saveToFilename, Locale locale) {
-        if (out != null) {
+    public static Map<String, Object> sendMessageText(String outText, OutputStream out, String sendToUrl, String saveToDirectory, String saveToFilename, Locale locale, Delegator delegator) {
+        final String certAlias = EntityUtilProperties.getPropertyValue("oagis.properties", "auth.client.certificate.alias", delegator);
+        final String basicAuthUsername = EntityUtilProperties.getPropertyValue("oagis.properties", "auth.basic.username", delegator);
+        final String basicAuthPassword = EntityUtilProperties.getPropertyValue("oagis.properties", "auth.basic.password", delegator);
+    	if (out != null) {
             Writer outWriter = new OutputStreamWriter(out);
             try {
                 outWriter.write(outText);
diff --git a/specialpurpose/oagis/src/org/ofbiz/oagis/OagisShipmentServices.java b/specialpurpose/oagis/src/org/ofbiz/oagis/OagisShipmentServices.java
index 8df3a19..7c00c37 100644
--- a/specialpurpose/oagis/src/org/ofbiz/oagis/OagisShipmentServices.java
+++ b/specialpurpose/oagis/src/org/ofbiz/oagis/OagisShipmentServices.java
@@ -80,10 +80,6 @@
 
     public static final String resource = "OagisUiLabels";
 
-    public static final String certAlias = UtilProperties.getPropertyValue("oagis.properties", "auth.client.certificate.alias");
-    public static final String basicAuthUsername = UtilProperties.getPropertyValue("oagis.properties", "auth.basic.username");
-    public static final String basicAuthPassword = UtilProperties.getPropertyValue("oagis.properties", "auth.basic.password");
-
     public static final String oagisMainNamespacePrefix = "n";
     public static final String oagisSegmentsNamespacePrefix = "os";
     public static final String oagisFieldsNamespacePrefix = "of";
@@ -906,7 +902,7 @@
                 Debug.logError(e, errMsg, module);
             }
 
-            Map<String, Object> sendMessageReturn = OagisServices.sendMessageText(outText, out, sendToUrl, saveToDirectory, saveToFilename, locale);
+            Map<String, Object> sendMessageReturn = OagisServices.sendMessageText(outText, out, sendToUrl, saveToDirectory, saveToFilename, locale, delegator);
             if (sendMessageReturn != null && ServiceUtil.isError(sendMessageReturn)) {
                 try {
                     Map<String, Object> uomiCtx = FastMap.newInstance();
@@ -1149,7 +1145,7 @@
                 Debug.logError(e, errMsg, module);
             }
 
-            Map<String, Object> sendMessageReturn = OagisServices.sendMessageText(outText, out, sendToUrl, saveToDirectory, saveToFilename, locale);
+            Map<String, Object> sendMessageReturn = OagisServices.sendMessageText(outText, out, sendToUrl, saveToDirectory, saveToFilename, locale, delegator);
             if (sendMessageReturn != null && ServiceUtil.isError(sendMessageReturn)) {
                 try {
                     Map<String, Object> uomiCtx = FastMap.newInstance();
diff --git a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/EditWeekTimesheet.groovy b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/EditWeekTimesheet.groovy
index beb6942..7bd4c0e 100644
--- a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/EditWeekTimesheet.groovy
+++ b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/EditWeekTimesheet.groovy
@@ -39,7 +39,7 @@
 timesheet = null;
 timesheetId = parameters.timesheetId;
 if (timesheetId) {
-    timesheet = delegator.findOne("Timesheet", ["timesheetId" : timesheetId], false);
+    timesheet = from("Timesheet").where("timesheetId", timesheetId).queryOne();
     partyId = timesheet.partyId; // use the party from this timesheet
 } else {
     // make sure because of timezone changes, not a duplicate timesheet is created
@@ -49,13 +49,13 @@
         EntityCondition.makeCondition("thruDate", EntityComparisonOperator.GREATER_THAN, midweek),
         EntityCondition.makeCondition("partyId", EntityComparisonOperator.EQUALS, partyId)
         ], EntityOperator.AND);
-    entryIterator = delegator.find("Timesheet", entryExprs, null, null, null, null);
+    entryIterator = from("Timesheet").where(entryExprs).queryIterator();
     timesheet = entryIterator.next();
     entryIterator.close();
     if (timesheet == null) {
-        result = dispatcher.runSync("createProjectTimesheet", ["userLogin" : parameters.userLogin, "partyId" : partyId]);
+        result = runService('createProjectTimesheet', ["userLogin" : parameters.userLogin, "partyId" : partyId]);
         if (result && result.timesheetId) {
-            timesheet = delegator.findOne("Timesheet", ["timesheetId" : result.timesheetId], false);
+            timesheet = from("Timesheet").where("timesheetId", result.timesheetId).queryOne();
         }
     }
 }
@@ -64,9 +64,9 @@
 context.weekNumber = UtilDateTime.weekNumber(timesheet.fromDate);
 
 // get the user names
-context.partyNameView = delegator.findOne("PartyNameView",["partyId" : partyId], false);
+context.partyNameView = from("PartyNameView").where("partyId", partyId).queryOne();
 // get the default rate for this person
-rateTypes = EntityUtil.filterByDate(delegator.findByAnd("PartyRate", ["partyId" : partyId, "defaultRate" : "Y"], null, false));
+rateTypes = from("PartyRate").where("partyId", partyId, "defaultRate", "Y").filterByDate().queryList();
 if (rateTypes) {
     context.defaultRateTypeId = rateTypes[0].rateTypeId;
 }
@@ -114,7 +114,7 @@
             // get project/phase information
             entry.workEffortId = entryWorkEffort.workEffortId;
             entry.workEffortName = entryWorkEffort.workEffortName;
-            result = dispatcher.runSync("getProjectIdAndNameFromTask", ["userLogin" : parameters.userLogin,"taskId" : entryWorkEffort.workEffortId]);
+            result = runService('getProjectIdAndNameFromTask', ["userLogin" : parameters.userLogin,"taskId" : entryWorkEffort.workEffortId]);
                 entry.phaseId = result.phaseId;
                 entry.phaseName = result.phaseName;
                 entry.projectId = result.projectId;
@@ -189,7 +189,7 @@
 }
 context.timeEntries = entries;
 // get all timesheets of this user, including the planned hours
-timesheetsDb = delegator.findByAnd("Timesheet", ["partyId" : partyId], ["fromDate DESC"], false);
+timesheetsDb = from("Timesheet").where("partyId", partyId).orderBy("fromDate DESC").queryList();
 timesheets = new LinkedList();
 timesheetsDb.each { timesheetDb ->
     timesheet = [:];
diff --git a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/GanttChart.groovy b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/GanttChart.groovy
index 17eedbe..640fd50 100644
--- a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/GanttChart.groovy
+++ b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/GanttChart.groovy
@@ -32,7 +32,7 @@
 userLogin = parameters.userLogin;
 
 //project info
-result = dispatcher.runSync("getProject", [projectId : projectId, userLogin : userLogin]);
+result = runService('getProject', [projectId : projectId, userLogin : userLogin]);
 project = result.projectInfo;
 if (project && project.startDate)
     context.chartStart = project.startDate;
@@ -46,7 +46,7 @@
 if (project == null) return;
 
 ganttList = new LinkedList();
-result = dispatcher.runSync("getProjectPhaseList", [userLogin : userLogin , projectId : projectId]);
+result = runService('getProjectPhaseList', [userLogin : userLogin , projectId : projectId]);
 phases = result.phaseList;
 if (phases) {
     phases.each { phase ->
@@ -71,10 +71,10 @@
                 EntityCondition.makeCondition("currentStatusId", EntityOperator.NOT_EQUAL, "PTS_CANCELLED"),
                 EntityCondition.makeCondition("workEffortParentId", EntityOperator.EQUALS, phase.phaseId)
                 ], EntityOperator.AND);
-        tasks = delegator.findList("WorkEffort", cond, null, ["sequenceNum","workEffortName"], null, false);
+        tasks = from("WorkEffort").where(cond).orderBy("sequenceNum","workEffortName").queryList();
         if (tasks) {
             tasks.each { task ->
-                resultTaskInfo = dispatcher.runSync("getProjectTask", [userLogin : userLogin , taskId : task.workEffortId]);
+                resultTaskInfo = runService('getProjectTask', [userLogin : userLogin , taskId : task.workEffortId]);
                 taskInfo = resultTaskInfo.taskInfo;
                 taskInfo.taskNr = task.workEffortId;
                 taskInfo.phaseNr = phase.phaseId;
@@ -117,7 +117,7 @@
                 }
 
                 // dependency can only show one in the ganttchart, so onl show the latest one..
-                preTasks = delegator.findByAnd("WorkEffortAssoc", ["workEffortIdTo" : task.workEffortId], ["workEffortIdFrom"], false);
+                preTasks = from("WorkEffortAssoc").where("workEffortIdTo", task.workEffortId).orderBy("workEffortIdFrom").queryList();
                 latestTaskIds = new LinkedList();
                 preTasks.each { preTask ->
                     wf = preTask.getRelatedOne("FromWorkEffort", false);
diff --git a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ListCurrentProjects.groovy b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ListCurrentProjects.groovy
index d726139..f1dafb8 100644
--- a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ListCurrentProjects.groovy
+++ b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ListCurrentProjects.groovy
@@ -23,13 +23,13 @@
         EntityCondition.makeCondition ("workEffortTypeId", EntityOperator.EQUALS, "PROJECT"),
         EntityCondition.makeCondition ("currentStatusId", EntityOperator.NOT_EQUAL, "PRJ_CLOSED")
         ], EntityJoinOperator.AND);
-allProjects = delegator.findList("WorkEffort", cond, (HashSet) ["workEffortId"], ["workEffortName"], null, false);
+allProjects = select("workEffortId").from("WorkEffort").where(cond).orderBy("workEffortName").queryList();
 
 projects = [];
 allProjects.each { project ->
-    result = dispatcher.runSync("getProject", ["userLogin" : parameters.userLogin, "projectId" : project.workEffortId]);
+    result = runService('getProject', ["userLogin" : parameters.userLogin, "projectId" : project.workEffortId]);
     if (result.projectInfo) {
-        resultAssign = delegator.findByAnd("WorkEffortPartyAssignment", ["partyId" : parameters.userLogin.partyId, "workEffortId" : project.workEffortId], null, false)
+        resultAssign = from("WorkEffortPartyAssignment").where("partyId", parameters.userLogin.partyId, "workEffortId", project.workEffortId).queryList();
         if (security.hasEntityPermission("PROJECTMGR", "_ADMIN", session)
         || ((security.hasEntityPermission("PROJECTMGR", "_ROLE_ADMIN", session) || security.hasEntityPermission("PROJECTMGR", "_ROLE_VIEW", session)) && resultAssign)) {
             projects.add(result.projectInfo);
diff --git a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ListResourceBillingHours.groovy b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ListResourceBillingHours.groovy
index 7fe11f3..fd5b296 100644
--- a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ListResourceBillingHours.groovy
+++ b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ListResourceBillingHours.groovy
@@ -27,16 +27,11 @@
 import javolution.util.FastList;
 
 
-cond =
-    EntityCondition.makeCondition(
-            [EntityCondition.makeCondition ("workEffortTypeId", EntityOperator.EQUALS, "PROJECT"),
-             EntityCondition.makeCondition ("partyId", EntityOperator.EQUALS, parameters.partyId)
-            ],EntityOperator.AND);
-allProjects = delegator.findList("WorkEffortAndPartyAssign", cond, (HashSet) ["workEffortId"], ["workEffortName"], null, true);
+allProjects = select("workEffortId").from("WorkEffortAndPartyAssign").where("workEffortTypeId", "PROJECT", "partyId", parameters.partyId).orderBy("workEffortName").cache(true).queryList();
 
 projects = [];
 allProjects.each { project ->
-    result = dispatcher.runSync("getProject", ["userLogin" : parameters.userLogin, "projectId" : project.workEffortId, partyId : parameters.partyId]);
+    result = runService('getProject', ["userLogin" : parameters.userLogin, "projectId" : project.workEffortId, partyId : parameters.partyId]);
     projects.add(result.projectInfo);
 }
 if (projects) {
diff --git a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ProjectBilling.groovy b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ProjectBilling.groovy
index 082b9b6..b91ec86 100644
--- a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ProjectBilling.groovy
+++ b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ProjectBilling.groovy
@@ -32,7 +32,13 @@
         ], EntityOperator.AND);
 orderBy = ["-fromDate"];
 // check if latest invoice generated is still in process so allow re-generation to correct errors
-entryIterator = delegator.find("ProjectPhaseTaskAndTimeEntryTimeSheet", entryExprs, null, null, orderBy, null);
+entryIterator = from("ProjectPhaseTaskAndTimeEntryTimeSheet")
+                    .where(EntityCondition.makeCondition([
+                                EntityCondition.makeCondition("projectId", EntityOperator.EQUALS, projectId),
+                                EntityCondition.makeCondition("invoiceId", EntityOperator.NOT_EQUAL, null),
+                            ], EntityOperator.AND))
+                    .orderBy("-fromDate")
+                    .queryIterator();
 while (entryItem = entryIterator.next()) {
     invoice = entryItem.getRelatedOne("Invoice", false);
     if (invoice.getString("statusId").equals("INVOICE_IN_PROCESS")) {
diff --git a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ProjectIsBillable.groovy b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ProjectIsBillable.groovy
index e683101..116ba19 100644
--- a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ProjectIsBillable.groovy
+++ b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/ProjectIsBillable.groovy
@@ -19,8 +19,7 @@
 
 import org.ofbiz.entity.util.EntityUtil;
  
-projectMembers = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : context.projectId], null, false);
-projectMembers = EntityUtil.filterByDate(projectMembers);
+projectMembers = from("WorkEffortPartyAssignment").where("workEffortId", context.projectId).filterByDate().queryList();
 
 toPartyId = null;
 fromPartyId = null;
diff --git a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/getLastRequestAssignment.groovy b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/getLastRequestAssignment.groovy
index 415d5a3..52b1ea3 100644
--- a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/getLastRequestAssignment.groovy
+++ b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/getLastRequestAssignment.groovy
@@ -22,7 +22,7 @@
 
 // get last request from this user and use that project/task assignment as default on the screen
 
-custRequestList = delegator.findByAnd("CustRequest", ["fromPartyId" : fromPartyId], ["-createdDate"], false);
+custRequestList = from("CustRequest").where("fromPartyId", fromPartyId).orderBy("-createdDate").queryList();
 if (custRequestList) {
     custReqTaskList = custRequestList.get(0).getRelated("CustRequestWorkEffort", null, null, false);
     if (custReqTaskList) {
diff --git a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/getProjectId.groovy b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/getProjectId.groovy
index 46a4a4d..180a864 100644
--- a/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/getProjectId.groovy
+++ b/specialpurpose/projectmgr/webapp/projectmgr/WEB-INF/actions/getProjectId.groovy
@@ -25,7 +25,7 @@
 
 if (parameters.workEffortId) {
     workEffortId = parameters.workEffortId;
-    projects = delegator.findByAnd("ProjectAndPhaseAndTask", UtilMisc.toMap("workEffortId", workEffortId), null, false);
+    projects = from("ProjectAndPhaseAndTask").where("workEffortId", workEffortId).queryList();
     if (UtilValidate.isNotEmpty(projects)) {
         context.put("projectId", projects.get(0).getString("projectId"));
         context.put("projectName", projects.get(0).getString("projectName"));
diff --git a/specialpurpose/projectmgr/widget/CustRequestScreens.xml b/specialpurpose/projectmgr/widget/CustRequestScreens.xml
index ffc3a7e..c5cc550 100644
--- a/specialpurpose/projectmgr/widget/CustRequestScreens.xml
+++ b/specialpurpose/projectmgr/widget/CustRequestScreens.xml
@@ -24,7 +24,7 @@
     <screen name="ProjectRequestList">
         <section>
             <condition>
-                <if-has-permission permission="PROJECTMGR" action="ADMIN"/>
+                <if-has-permission permission="PROJECTMGR" action="_ADMIN"/>
             </condition>
             <actions>
                 <entity-and list="custRequests" entity-name="CustRequest">
diff --git a/specialpurpose/projectmgr/widget/forms/ProjectForms.xml b/specialpurpose/projectmgr/widget/forms/ProjectForms.xml
index f2ba2bd..f1462a4 100644
--- a/specialpurpose/projectmgr/widget/forms/ProjectForms.xml
+++ b/specialpurpose/projectmgr/widget/forms/ProjectForms.xml
@@ -912,7 +912,7 @@
         </field>
         <!-- note sure if these two are necessray, but they are kind of confusing in this context:
             <field name="ownerContentId"><lookup target-form-name="LookupContent"/></field>
-            <field name="dataResourceId"><lookup target-form-name="LookupDataResource"/></field>
+            <field name="dataResourceId" title="${uiLabelMap.ContentDataResourceId}"><lookup target-form-name="LookupDataResource"/></field>
         -->
         <field name="contentTypeId" use-when="workEffortContent!=null">
             <drop-down allow-empty="false" no-current-selected-key="DOCUMENT">
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddProductBacklogItem.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddProductBacklogItem.groovy
index 49e5a02..4d8837c 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddProductBacklogItem.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddProductBacklogItem.groovy
@@ -28,8 +28,6 @@
 def module = "AddProductBacklogItem.groovy";
 
 // find cust request and items
-def performFindInMap = [:];
-performFindInMap.entityName = "CustRequestAndCustRequestItem";
 def inputFields = [:];
 
 if(parameters.statusId == null){
@@ -39,9 +37,7 @@
 }
 inputFields.putAll(parameters);
 inputFields.custRequestTypeId = "RF_PROD_BACKLOG";
-performFindInMap.inputFields = inputFields;
-performFindInMap.orderBy = "custSequenceNum";
-def performFindResults = dispatcher.runSync("performFind", performFindInMap);
+def performFindResults = runService('performFind', ["entityName": "CustRequestAndCustRequestItem", "inputFields": inputFields, "orderBy": "custSequenceNum"]);
 def custRequestAndItems = performFindResults.listIt.getCompleteList();
 performFindResults.listIt.close();
 
@@ -54,11 +50,11 @@
     tempCustRequestAndItem.custSequenceNum = countSequence;
     tempCustRequestAndItem.realSequenceNum = custRequestAndItem.custSequenceNum;
     // if custRequest has task then get Actual Hours
-    custWorkEffortList = delegator.findByAnd("CustRequestWorkEffort",["custRequestId" : custRequestAndItem.custRequestId], null, false);
+    custWorkEffortList = from("CustRequestWorkEffort").where("custRequestId", custRequestAndItem.custRequestId).queryList();
     if (custWorkEffortList) {
         actualHours = 0.00;
         custWorkEffortList.each() { custWorkEffortMap ->
-            result = dispatcher.runSync("getScrumActualHour", ["taskId" : custWorkEffortMap.workEffortId,"partyId" : null, "userLogin" : userLogin]);
+            result = runService('getScrumActualHour', ["taskId" : custWorkEffortMap.workEffortId,"partyId" : null, "userLogin" : userLogin]);
             actualHours += result.actualHours;
         }
         if(actualHours) {
@@ -101,9 +97,8 @@
 
 mainConditionList.add(orConditions);
 mainConditionList.add(conditions);
-mainConditions = EntityCondition.makeCondition(mainConditionList, EntityOperator.AND);
 
-unplannedList = delegator.findList("CustRequestAndCustRequestItem", mainConditions, ["custRequestId", "custSequenceNum", "statusId", "description", "custEstimatedMilliSeconds", "custRequestName", "parentCustRequestId"] as Set, ["custSequenceNum"], null, false);
+unplannedList = select("custRequestId", "custSequenceNum", "statusId", "description", "custEstimatedMilliSeconds", "custRequestName", "parentCustRequestId").from("CustRequestAndCustRequestItem").where(mainConditionList).orderBy("custSequenceNum").queryList();
 
 def countSequenceUnplanned = 1;
 def unplanBacklogItems = [];
@@ -113,11 +108,11 @@
     tempUnplanned.custSequenceNum = countSequenceUnplanned;
     tempUnplanned.realSequenceNum = unplannedItem.custSequenceNum;
     // if custRequest has task then get Actual Hours
-    unplanCustWorkEffortList = delegator.findByAnd("CustRequestWorkEffort",["custRequestId" : unplannedItem.custRequestId], null, false);
+    unplanCustWorkEffortList = from("CustRequestWorkEffort").where("custRequestId", unplannedItem.custRequestId).queryList();
     if (unplanCustWorkEffortList) {
         actualHours = 0.00;
         unplanCustWorkEffortList.each() { custWorkEffortMap ->
-            result = dispatcher.runSync("getScrumActualHour", ["taskId" : custWorkEffortMap.workEffortId,"partyId" : null, "userLogin" : userLogin]);
+            result = runService('getScrumActualHour', ["taskId" : custWorkEffortMap.workEffortId,"partyId" : null, "userLogin" : userLogin]);
             actualHours += result.actualHours;
         }
         if(actualHours) {
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddResourceTaskParty.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddResourceTaskParty.groovy
index 0aa12b4..b4fd8e4 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddResourceTaskParty.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddResourceTaskParty.groovy
@@ -23,21 +23,21 @@
 partyId = parameters.partyId
 // get existing task that no assign
 projectSprintBacklogAndTaskList = [];
-projectAndTaskList = delegator.findByAnd("ProjectSprintBacklogAndTask", ["sprintTypeId" : "SCRUM_SPRINT","taskCurrentStatusId" : "STS_CREATED"], ["taskId DESC"], false);
+projectAndTaskList = from("ProjectSprintBacklogAndTask").where("sprintTypeId", "SCRUM_SPRINT","taskCurrentStatusId", "STS_CREATED").orderBy("taskId DESC").queryList();
 projectAndTaskList.each { projectAndTaskMap ->
 userLoginId = userLogin.partyId;
     projectId = projectAndTaskMap.projectId;
-    partyAssignmentProjectList = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : projectId, "partyId" : partyId], null, false);
+    partyAssignmentProjectList = from("WorkEffortPartyAssignment").where("workEffortId", projectId, "partyId", partyId).queryList();
     partyAssignmentProjectMap = partyAssignmentProjectList[0];
         // if this userLoginId is a member of project
         if (partyAssignmentProjectMap) {
             sprintId = projectAndTaskMap.sprintId;
-            partyAssignmentSprintList = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : sprintId, "partyId" : partyId], null, false);
+            partyAssignmentSprintList = from("WorkEffortPartyAssignment").where("workEffortId", sprintId, "partyId", partyId).queryList();
             partyAssignmentSprintMap = partyAssignmentSprintList[0];
             // if this userLoginId is a member of sprint
             if (partyAssignmentSprintMap) {
                 workEffortId = projectAndTaskMap.taskId;
-                partyAssignmentTaskList = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : workEffortId], null, false);
+                partyAssignmentTaskList = from("WorkEffortPartyAssignment").where("workEffortId", workEffortId).queryList();
                 partyAssignmentTaskMap = partyAssignmentTaskList[0];
                 // if the task do not assigned
                 if (!partyAssignmentTaskMap) {
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/BacklogNotifications.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/BacklogNotifications.groovy
index 08e89cf..f64922d 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/BacklogNotifications.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/BacklogNotifications.groovy
@@ -22,8 +22,8 @@
 
 def module = "BacklogNotifications.groovy";
 
-custRequest = delegator.findOne("CustRequest", ["custRequestId" : custRequestId], false);
-person = delegator.findOne("PartyNameView", ["partyId" : partyIdTo], false);
+custRequest = from("CustRequest").where("custRequestId", custRequestId).queryOne();
+person = from("PartyNameView").where("partyId", partyIdTo).queryOne();
 informationMap = [:];
 informationMap.internalName = null;
 informationMap.productId = null;
@@ -31,24 +31,19 @@
 informationMap.workEffortId = null;
 
 //check in sprint
-andExprs = [EntityCondition.makeCondition("workEffortTypeId", EntityOperator.EQUALS, "SCRUM_SPRINT"),
-            EntityCondition.makeCondition("custRequestId", EntityOperator.EQUALS, custRequestId)];
-backlogCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-backlogList = delegator.findList("ProductBacklog", backlogCond, ["productId", "workEffortId", "custRequestId"] as Set ,null ,null, false);
+backlogList = select("productId", "workEffortId", "custRequestId").from("ProductBacklog").where("workEffortTypeId", "SCRUM_SPRINT", "custRequestId", custRequestId).queryList();
 if (backlogList) {
-    product = delegator.findOne("Product", ["productId" : backlogList[0].productId], false);
-    sprint = delegator.findOne("WorkEffort", ["workEffortId" : backlogList[0].workEffortId], false);
+    product = from("Product").where("productId", backlogList[0].productId).queryOne();
+    sprint = from("WorkEffort").where("workEffortId", backlogList[0].workEffortId).queryOne();
     informationMap.internalName = product.internalName;
     informationMap.productId = product.productId;
     informationMap.workEffortName = sprint.workEffortName;
     informationMap.workEffortId = sprint.workEffortId;
 } else {
-    andExprs = [EntityCondition.makeCondition("custRequestId", EntityOperator.EQUALS, custRequestId)];
-    backlogCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-    backlogList = delegator.findList("ProductBacklog", backlogCond, ["productId", "workEffortId", "custRequestId"] as Set ,null ,null, false);
+    backlogList = select("productId", "workEffortId", "custRequestId").from("ProductBacklog").where("custRequestId", custRequestId).queryList();
     if (backlogList) {
         if (backlogList[0].productId) {
-            product = delegator.findOne("Product", ["productId" : backlogList[0].productId], false);
+            product = from("Product").where("productId", backlogList[0].productId).queryOne();
             informationMap.internalName = product.internalName;
             informationMap.productId = product.productId;
         }
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditDailyHourReport.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditDailyHourReport.groovy
index 9c451cb..33c0661 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditDailyHourReport.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditDailyHourReport.groovy
@@ -40,7 +40,7 @@
 timesheet = null;
 timesheetId = parameters.timesheetId;
 if (timesheetId) {
-    timesheet = delegator.findOne("Timesheet", ["timesheetId" : timesheetId], false);
+    timesheet = from("Timesheet").where("timesheetId", timesheetId).queryOne();
     partyId = timesheet.partyId; // use the party from this timesheet
 } else {
     // make sure because of timezone changes, not a duplicate timesheet is created
@@ -50,13 +50,13 @@
         EntityCondition.makeCondition("thruDate", EntityComparisonOperator.GREATER_THAN, midweek),
         EntityCondition.makeCondition("partyId", EntityComparisonOperator.EQUALS, partyId)
         ], EntityOperator.AND);
-    entryIterator = delegator.find("Timesheet", entryExprs, null, null, null, null);
+    entryIterator = from("Timesheet").where(entryExprs).queryIterator();
     timesheet = entryIterator.next();
     entryIterator.close();
     if (timesheet == null) {
-        result = dispatcher.runSync("createProjectTimesheet", ["userLogin" : parameters.userLogin, "partyId" : partyId]);
+        result = runService('createProjectTimesheet', ["userLogin" : parameters.userLogin, "partyId" : partyId]);
         if (result && result.timesheetId) {
-            timesheet = delegator.findOne("Timesheet", ["timesheetId" : result.timesheetId], false);
+            timesheet = from("Timesheet").where("timesheetId", result.timesheetId).queryOne();
         }
     }
 }
@@ -65,9 +65,9 @@
 context.weekNumber = UtilDateTime.weekNumber(timesheet.fromDate);
 
 // get the user names
-context.partyNameView = delegator.findOne("PartyNameView",["partyId" : partyId], false);
+context.partyNameView = from("PartyNameView").where("partyId", partyId).queryOne();
 // get the default rate for this person
-rateTypes = EntityUtil.filterByDate(delegator.findByAnd("PartyRate", ["partyId" : partyId, "defaultRate" : "Y"], null, false));
+rateTypes = from("PartyRate").where("partyId", partyId, "defaultRate", "Y").filterByDate().queryList();
 if (rateTypes) {
     context.defaultRateTypeId = rateTypes[0].rateTypeId;
 }
@@ -108,7 +108,7 @@
             //entry.plannedHours = pHours;
             planHours = 0.0;
             planHours = lastTimeEntry.planHours;
-            lastTimeEntryOfTasks = delegator.findByAnd("TimeEntry", ["workEffortId" : lastTimeEntry.workEffortId, "partyId" : partyId], ["-fromDate"], false);
+            lastTimeEntryOfTasks = from("TimeEntry").where("workEffortId", lastTimeEntry.workEffortId, "partyId", partyId).orderBy("-fromDate").queryList();
             if (lastTimeEntryOfTasks.size() != 0) lastTimeEntry = lastTimeEntryOfTasks[0];
             if (planHours < 1) {
                 planHours = estimatedHour;
@@ -141,7 +141,7 @@
             // get project/phase information
             entry.workEffortId = entryWorkEffort.workEffortId;
             entry.workEffortName = entryWorkEffort.workEffortName;
-            result = dispatcher.runSync("getProjectInfoFromTask", ["userLogin" : parameters.userLogin,"taskId" : entryWorkEffort.workEffortId]);
+            result = runService('getProjectInfoFromTask', ["userLogin" : parameters.userLogin,"taskId" : entryWorkEffort.workEffortId]);
                 entry.phaseId = result.phaseId;
                 entry.phaseName = result.phaseName;
                 entry.projectId = result.projectId;
@@ -211,12 +211,8 @@
 void retrieveEmplLeaveData() {
         if (lastEmplLeaveEntry) {
             //service get Hours
-            inputMap = [:];
-            inputMap.userLogin = parameters.userLogin;
-            inputMap.partyId = lastEmplLeaveEntry.partyId;
-            inputMap.leaveTypeId = lastEmplLeaveEntry.leaveTypeId;
-            inputMap.fromDate = lastEmplLeaveEntry.fromDate;
-            result = dispatcher.runSync("getPartyLeaveHoursForDate", inputMap);
+            result = runService('getPartyLeaveHoursForDate', 
+                ["userLogin": parameters.userLogin, "partyId": lastEmplLeaveEntry.partyId, "leaveTypeId": lastEmplLeaveEntry.leaveTypeId, "fromDate": lastEmplLeaveEntry.fromDate]);
             if (result.hours) {
                 leaveEntry.plannedHours = result.hours;
                 leaveEntry.planHours =  result.hours;
@@ -242,12 +238,11 @@
    }
 
 // define condition
-findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
 leaveExprs = [];
 leaveExprs.add(EntityCondition.makeCondition("fromDate", EntityOperator.GREATER_THAN_EQUAL_TO, timesheet.fromDate));
 leaveExprs.add(EntityCondition.makeCondition("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, timesheet.thruDate));
 leaveExprs.add(EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, partyId));
-emplLeave = delegator.find("EmplLeave", EntityCondition.makeCondition(leaveExprs, EntityOperator.AND), null, null, null, findOpts);
+emplLeave = from("EmplLeave").where(leaveExprs).cursorScrollInsensitive().distinct().queryIterator();
 
 while ((emplLeaveMap = emplLeave.next())) {
     if (emplLeaveEntry!=void) {
@@ -261,21 +256,13 @@
             !lastEmplLeaveEntry.partyId.equals(emplLeaveEntry.partyId))) {
             retrieveEmplLeaveData();
         }
-    input = [:];
-    input.userLogin = parameters.userLogin;
-    input.partyId = emplLeaveEntry.partyId;
-    input.leaveTypeId = emplLeaveEntry.leaveTypeId;
-    input.fromDate = emplLeaveEntry.fromDate;
-    resultHours = dispatcher.runSync("getPartyLeaveHoursForDate", input);
+    resultHours = runService('getPartyLeaveHoursForDate', 
+        ["userLogin": parameters.userLogin, "partyId": emplLeaveEntry.partyId, "leaveTypeId": emplLeaveEntry.leaveTypeId, "fromDate": emplLeaveEntry.fromDate]);
     
     if (resultHours.hours) {
         leaveDayNumber = "d" + (emplLeaveEntry.fromDate.getTime() - timesheet.fromDate.getTime()) / (24*60*60*1000);
-        inputMap = [:];
-        inputMap.userLogin = parameters.userLogin;
-        inputMap.partyId = emplLeaveEntry.partyId;
-        inputMap.leaveTypeId = emplLeaveEntry.leaveTypeId;
-        inputMap.fromDate = emplLeaveEntry.fromDate;
-        resultHours = dispatcher.runSync("getPartyLeaveHoursForDate", inputMap);
+        resultHours = runService('getPartyLeaveHoursForDate', 
+            ["userLogin": parameters.userLogin, "partyId": emplLeaveEntry.partyId, "leaveTypeId": emplLeaveEntry.leaveTypeId, "fromDate": emplLeaveEntry.fromDate]);
         leaveHours = resultHours.hours.doubleValue();
         leaveEntry.put(String.valueOf(leaveDayNumber), leaveHours);
         if (leaveDayNumber.equals("d0")) day0Total += leaveHours;
@@ -289,12 +276,8 @@
     }
     if (resultHours.hours) {
         leavePlanDay = "pd" + (emplLeaveEntry.fromDate.getTime() - timesheet.fromDate.getTime()) / (24*60*60*1000);
-        inputMap = [:];
-        inputMap.userLogin = parameters.userLogin;
-        inputMap.partyId = emplLeaveEntry.partyId;
-        inputMap.leaveTypeId = emplLeaveEntry.leaveTypeId;
-        inputMap.fromDate = emplLeaveEntry.fromDate;
-        resultPlanHours = dispatcher.runSync("getPartyLeaveHoursForDate", inputMap);
+        resultPlanHours = runService('getPartyLeaveHoursForDate', 
+            ["userLogin": parameters.userLogin, "partyId": emplLeaveEntry.partyId, "leaveTypeId": emplLeaveEntry.leaveTypeId, "fromDate": emplLeaveEntry.fromDate]);
         leavePlanHours = resultPlanHours.hours.doubleValue();
         leaveEntry.put(String.valueOf(leavePlanDay), leavePlanHours);
         if (leavePlanDay.equals("pd0")) pDay0Total += leavePlanHours;
@@ -350,7 +333,7 @@
 }
 context.timeEntries = entries;
 // get all timesheets of this user, including the planned hours
-timesheetsDb = delegator.findByAnd("Timesheet", ["partyId" : partyId], ["fromDate DESC"], false);
+timesheetsDb = from("Timesheet").where("partyId", partyId).orderBy("fromDate DESC").queryList();
 timesheets = new LinkedList();
 timesheetsDb.each { timesheetDb ->
     //get hours from EmplLeave;
@@ -359,17 +342,13 @@
     leaveExprsList.add(EntityCondition.makeCondition("fromDate", EntityOperator.GREATER_THAN_EQUAL_TO, timesheetDb.fromDate));
     leaveExprsList.add(EntityCondition.makeCondition("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, timesheetDb.thruDate));
     leaveExprsList.add(EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, partyId));
-    emplLeaveList = delegator.find("EmplLeave", EntityCondition.makeCondition(leaveExprsList, EntityOperator.AND), null, null, null, findOpts);
+    emplLeaveList = from("EmplLeave").where(leaveExprsList).cursorScrollInsensitive().distinct().queryIterator();
     leaveHours = 0.00;
     
     while ((emplLeaveMap = emplLeaveList.next())) {
         emplLeaveEntry = emplLeaveMap;
-        inputData = [:];
-        inputData.userLogin = parameters.userLogin;
-        inputData.partyId = emplLeaveEntry.partyId;
-        inputData.leaveTypeId = emplLeaveEntry.leaveTypeId;
-        inputData.fromDate = emplLeaveEntry.fromDate;
-        resultHour = dispatcher.runSync("getPartyLeaveHoursForDate", inputData);
+        resultHour = runService('getPartyLeaveHoursForDate', 
+            ["userLogin": parameters.userLogin, "partyId": emplLeaveEntry.partyId, "leaveTypeId": emplLeaveEntry.leaveTypeId, "fromDate": emplLeaveEntry.fromDate]);
         if (resultHour) {
             leaveActualHours = resultHour.hours.doubleValue();
             leaveHours += leaveActualHours;
@@ -396,19 +375,19 @@
 taskList=[];
 projectSprintBacklogAndTaskList = [];
 backlogIndexList = [];
-projectAndTaskList = delegator.findByAnd("ProjectSprintBacklogAndTask", ["sprintTypeId" : "SCRUM_SPRINT","taskCurrentStatusId" : "STS_CREATED"], ["projectName ASC","taskActualStartDate DESC"], false);
+projectAndTaskList = from("ProjectSprintBacklogAndTask").where("sprintTypeId" : "SCRUM_SPRINT","taskCurrentStatusId" : "STS_CREATED").orderBy("projectName ASC","taskActualStartDate DESC").queryList();
 projectAndTaskList.each { projectAndTaskMap ->
 userLoginId = userLogin.partyId;
     sprintId = projectAndTaskMap.sprintId;
-    workEffortList = delegator.findByAnd("WorkEffortAndProduct", ["workEffortId" : projectAndTaskMap.projectId], null, false);
+    workEffortList = from("WorkEffortAndProduct").where("workEffortId", projectAndTaskMap.projectId).queryList();
     backlogIndexList.add(workEffortList[0].productId);
 	
-    partyAssignmentSprintList = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : sprintId, "partyId" : userLoginId], null, false);
+    partyAssignmentSprintList = from("WorkEffortPartyAssignment").where("workEffortId", sprintId, "partyId", userLoginId).queryList();
     partyAssignmentSprintMap = partyAssignmentSprintList[0];
     // if this userLoginId is a member of sprint
     if (partyAssignmentSprintMap) {
         workEffortId = projectAndTaskMap.taskId;
-        partyAssignmentTaskList = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : workEffortId], null, false);
+        partyAssignmentTaskList = from("WorkEffortPartyAssignment").where("workEffortId", workEffortId).queryList();
         partyAssignmentTaskMap = partyAssignmentTaskList[0];
         // if the task do not assigned
         if (partyAssignmentTaskMap) {
@@ -427,24 +406,24 @@
 unplanList=[];
 if (backlogIndexList) {
     backlogIndex = new HashSet(backlogIndexList);
-    custRequestList = delegator.findByAnd("CustRequest", ["custRequestTypeId" : "RF_UNPLAN_BACKLOG","statusId" : "CRQ_REVIEWED"],["custRequestDate DESC"], false);
+    custRequestList = from("CustRequest").where("custRequestTypeId", "RF_UNPLAN_BACKLOG","statusId", "CRQ_REVIEWED").orderBy("custRequestDate DESC").queryList();
     if (custRequestList) {
         custRequestList.each { custRequestMap ->
             custRequestItemList = custRequestMap.getRelated("CustRequestItem", null, null, false);
 			custRequestItem =  
 			productOut = custRequestItemList[0].productId;
-			product = delegator.findOne("Product", ["productId" : productOut], false);
+			product = from("Product").where("productId", productOut).queryOne();
             backlogIndex.each { backlogProduct ->
                 productId = backlogProduct
                 if (productId.equals(productOut)) {
-                    custRequestWorkEffortList = delegator.findByAnd("CustRequestWorkEffort", ["custRequestId" : custRequestItemList[0].custRequestId], null, false);
+                    custRequestWorkEffortList = from("CustRequestWorkEffort").where("custRequestId", custRequestItemList[0].custRequestId).queryList();
                     custRequestWorkEffortList.each { custRequestWorkEffortMap ->
-                        partyAssignmentTaskList = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : custRequestWorkEffortMap.workEffortId], null, false);
+                        partyAssignmentTaskList = from("WorkEffortPartyAssignment").where("workEffortId", custRequestWorkEffortMap.workEffortId).queryList();
                         partyAssignmentTaskMap = partyAssignmentTaskList[0];
                         // if the task do not assigned
                         if (!partyAssignmentTaskMap) {
                             result = [:];
-                            workEffortMap = delegator.findOne("WorkEffort", ["workEffortId" : custRequestWorkEffortMap.workEffortId], false);
+                            workEffortMap = from("WorkEffort").where("workEffortId", custRequestWorkEffortMap.workEffortId).queryOne();
                             result.description = custRequestMap.description;
                             result.productName = product.internalName;
                             result.taskId = workEffortMap.workEffortId;
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditWeekTimesheet.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditWeekTimesheet.groovy
index 881db4f..034dce3 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditWeekTimesheet.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditWeekTimesheet.groovy
@@ -39,7 +39,7 @@
 timesheet = null;
 timesheetId = parameters.timesheetId;
 if (timesheetId) {
-    timesheet = delegator.findOne("Timesheet", ["timesheetId" : timesheetId], false);
+    timesheet = from("Timesheet").where("timesheetId", timesheetId).queryOne();
     partyId = timesheet.partyId; // use the party from this timesheet
 } else {
     // make sure because of timezone changes, not a duplicate timesheet is created
@@ -49,13 +49,13 @@
         EntityCondition.makeCondition("thruDate", EntityComparisonOperator.GREATER_THAN, midweek),
         EntityCondition.makeCondition("partyId", EntityComparisonOperator.EQUALS, partyId)
         ], EntityOperator.AND);
-    entryIterator = delegator.find("Timesheet", entryExprs, null, null, null, null);
+    entryIterator = from("Timesheet").where(entryExprs).queryIterator();
     timesheet = entryIterator.next();
     entryIterator.close();
     if (timesheet == null) {
-        result = dispatcher.runSync("createProjectTimesheet", ["userLogin" : parameters.userLogin, "partyId" : partyId]);
+        result = runService('createProjectTimesheet', ["userLogin" : parameters.userLogin, "partyId" : partyId]);
         if (result && result.timesheetId) {
-            timesheet = delegator.findOne("Timesheet", ["timesheetId" : result.timesheetId], false);
+            timesheet = from("Timesheet").where("timesheetId", result.timesheetId).queryOne();
         }
     }
 }
@@ -64,9 +64,9 @@
 context.weekNumber = UtilDateTime.weekNumber(timesheet.fromDate);
 
 // get the user names
-context.partyNameView = delegator.findOne("PartyNameView",["partyId" : partyId], false);
+context.partyNameView = from("PartyNameView").where("partyId", partyId).queryOne();
 // get the default rate for this person
-rateTypes = EntityUtil.filterByDate(delegator.findByAnd("PartyRate", ["partyId" : partyId, "defaultRate" : "Y"], null, false));
+rateTypes = from("PartyRate").where("partyId", partyId, "defaultRate", "Y").filterByDate().queryList();
 if (rateTypes) {
     context.defaultRateTypeId = rateTypes[0].rateTypeId;
 }
@@ -114,7 +114,7 @@
             // get project/phase information
             entry.workEffortId = entryWorkEffort.workEffortId;
             entry.workEffortName = entryWorkEffort.workEffortName;
-            result = dispatcher.runSync("getProjectIdAndNameFromTask", ["userLogin" : parameters.userLogin,"taskId" : entryWorkEffort.workEffortId]);
+            result = runService('getProjectIdAndNameFromTask', ["userLogin" : parameters.userLogin,"taskId" : entryWorkEffort.workEffortId]);
                 entry.sprintId = result.phaseId;
                 entry.sprintName = result.phaseName;
                 entry.projectId = result.projectId;
@@ -189,7 +189,7 @@
 }
 context.timeEntries = entries;
 // get all timesheets of this user, including the planned hours
-timesheetsDb = delegator.findByAnd("Timesheet", ["partyId" : partyId], ["fromDate DESC"], false);
+timesheetsDb = from("Timesheet").where("partyId", partyId).orderBy("fromDate DESC").queryList();
 timesheets = new LinkedList();
 timesheetsDb.each { timesheetDb ->
     timesheet = [:];
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindBacklogItem.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindBacklogItem.groovy
index cec5d97..e33a702 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindBacklogItem.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindBacklogItem.groovy
@@ -32,7 +32,7 @@
 productId =parameters.productId;
 custRequestList=[];
 backlogList=[];
-custRequestList = delegator.findByAnd("CustRequestItem", ["productId" : productId], null, false);
+custRequestList = from("CustRequestItem").where("productId", productId).queryList();
 custRequestList.each { custRequestListMap ->
     custRequestId=custRequestListMap.custRequestId;
     exprBldr = FastList.newInstance();
@@ -43,15 +43,15 @@
     andExprs.add(EntityCondition.makeCondition(exprBldr, EntityOperator.OR));
     custRequestTypeCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
     orderBy = ["custRequestTypeId"];
-    productBacklogList = delegator.findList("CustRequest", custRequestTypeCond, null,orderBy ,null, false);
+    productBacklogList = from("CustRequest").where(andExprs).orderBy("custRequestTypeId").queryList();
     productBacklogList.each { productBacklogMap ->
         productBackId = productBacklogMap.custRequestId;
-        taskBacklogList = delegator.findByAnd("CustRequestWorkEffort", ["custRequestId" : productBackId], null, false);
+        taskBacklogList = from("CustRequestWorkEffort").where("custRequestId", productBackId).queryList();
         int countImplTask=0, countImplTaskComplete=0, countInstallTask=0, countInstallTaskComplete=0, countErrTask=0, countErrTaskComplete=0, countTestTask=0;
         taskBacklogList.each { taskBacklogMap ->
             taskId = taskBacklogMap.workEffortId;
             
-            task = delegator.findOne("WorkEffort", ["workEffortId" : taskId], false);
+            task = from("WorkEffort").where("workEffortId", taskId).queryOne();
             if (task.workEffortTypeId == "SCRUM_TASK_IMPL") {
                 countImplTask+=1;
                 if ( task.currentStatusId == "STS_COMPLETED" || task.currentStatusId == "STS_CANCELLED") {
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindProductBacklogItem.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindProductBacklogItem.groovy
index e09f46b..80eda2f 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindProductBacklogItem.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindProductBacklogItem.groovy
@@ -94,9 +94,12 @@
     }
     
     mainConditionBacklogList.add(conditionsBacklog);
-    mainConditionsBacklog = EntityCondition.makeCondition(mainConditionBacklogList, EntityOperator.AND);
     
-    backlogList = delegator.findList("CustRequestAndCustRequestItem", mainConditionsBacklog, ["custRequestId","custRequestTypeId", "custSequenceNum", "statusId", "description", "custEstimatedMilliSeconds", "custRequestName", "parentCustRequestId","productId","billed","custRequestDate","fromPartyId"] as Set, ["-custRequestTypeId",orderBy], null, false);
+    backlogList = select("custRequestId","custRequestTypeId", "custSequenceNum", "statusId", "description", "custEstimatedMilliSeconds", "custRequestName", "parentCustRequestId","productId","billed","custRequestDate","fromPartyId")
+                    .from("CustRequestAndCustRequestItem")
+                    .where(mainConditionBacklogList)
+                    .orderBy("-custRequestTypeId", orderBy)
+                    .queryList();
     def countSequenceBacklog = 1;
     def backlogItems = [];
     backlogList.each() { backlogItem ->
@@ -105,11 +108,11 @@
         tempBacklog.custSequenceNum = countSequenceBacklog;
         tempBacklog.realSequenceNum = backlogItem.custSequenceNum;
         // if custRequest has task then get Actual Hours
-        backlogCustWorkEffortList = delegator.findByAnd("CustRequestWorkEffort",["custRequestId" : backlogItem.custRequestId], null, false);
+        backlogCustWorkEffortList = from("CustRequestWorkEffort").where("custRequestId", backlogItem.custRequestId).queryList();
         if (backlogCustWorkEffortList) {
             actualHours = 0.00;
             backlogCustWorkEffortList.each() { custWorkEffortMap ->
-                result = dispatcher.runSync("getScrumActualHour", ["taskId" : custWorkEffortMap.workEffortId,"partyId" : null, "userLogin" : userLogin]);
+                result = runService('getScrumActualHour', ["taskId" : custWorkEffortMap.workEffortId,"partyId" : null, "userLogin" : userLogin]);
                 actualHours += result.actualHours;
             }
             if(actualHours) {
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindTaskList.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindTaskList.groovy
index 8de602a..53746ba 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindTaskList.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindTaskList.groovy
@@ -69,11 +69,10 @@
         if (statusId){
             exprBldr.add(EntityCondition.makeCondition("currentStatusId", EntityOperator.EQUALS, statusId));
         }
-        unplannedCond = EntityCondition.makeCondition(exprBldr, EntityOperator.AND);
-        unplannedTaskList = delegator.findList("UnPlannedBacklogsAndTasks", unplannedCond, null,["-createdDate"] ,null, false);
+        unplannedTaskList = from("UnPlannedBacklogsAndTasks").where(exprBldr).orderBy("-createdDate").queryList();
     }
     else{
-        unplannedTaskList = delegator.findList("UnPlannedBacklogsAndTasks", null, null,["-createdDate"] ,null, false);
+        unplannedTaskList = from("UnPlannedBacklogsAndTasks").orderBy("-createdDate").queryList();
     }
     
     exprBldr2 =  FastList.newInstance();
@@ -102,8 +101,7 @@
         exprBldr2.add(EntityCondition.makeCondition("projectName", EntityOperator.LIKE, "%"+projectName+"%"));
     }
     exprBldr2.add(EntityCondition.makeCondition("sprintTypeId", EntityOperator.EQUALS, "SCRUM_SPRINT"));
-    plannedCond = EntityCondition.makeCondition(exprBldr2, EntityOperator.AND);
-    plannedTaskList = delegator.findList("ProjectSprintBacklogAndTask", plannedCond, null,["-taskCreatedDate"] ,null, false);
+    plannedTaskList = from("ProjectSprintBacklogAndTask").where(exprBldr2).orderBy("-taskCreatedDate").queryList();
     
     unplannedTaskList.each{ unplannedTaskMap ->
         unplannedMap = [:];
@@ -170,7 +168,7 @@
         resultList = [];
         assignedList.each { assignedMap ->
             workEffortId = assignedMap.taskId;
-            assignToList = delegator.findByAnd("WorkEffortPartyAssignment",["workEffortId" : workEffortId, "partyId" : partyId], null, false);
+            assignToList = from("WorkEffortPartyAssignment").where("workEffortId", workEffortId, "partyId", partyId).queryList();
             if (assignToList) {
                 assignedMap.partyId = assignToList[0].partyId;
                 resultList.add(assignedMap);
@@ -181,7 +179,7 @@
         resultList = [];
         assignedList.each { assignedMap ->
             workEffortId = assignedMap.taskId;
-            assignToList = delegator.findByAnd("WorkEffortPartyAssignment",["workEffortId" : workEffortId], null, false);
+            assignToList = from("WorkEffortPartyAssignment").where("workEffortId", workEffortId).queryList();
             if (assignToList) {
                 assignedMap.partyId = assignToList[0].partyId;
                 resultList.add(assignedMap);
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListCurrentProducts.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListCurrentProducts.groovy
index d75d5f7..30b6a18 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListCurrentProducts.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListCurrentProducts.groovy
@@ -59,22 +59,22 @@
     paramCond.add(EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, "PRODUCT_OWNER_COMP"));
     paramCond.add(EntityCondition.makeCondition("thruDate", EntityOperator.EQUALS, null));
     
-    cond = EntityCondition.makeCondition(paramCond, EntityOperator.AND);
+    allProducts = from("ProductAndRole").where(paramCond).orderBy("groupName", "internalName").queryList();
     
-    allProducts = delegator.findList("ProductAndRole", cond, null, ["groupName", "internalName"], null, false);
+    partyAndSecurityGroupList = select("partyId", "groupId")
+                                    .from("ScrumMemberUserLoginAndSecurityGroup").where(EntityCondition.makeCondition([
+                                        EntityCondition.makeCondition ("partyId", EntityOperator.EQUALS, userLogin.partyId),
+                                        EntityCondition.makeCondition ("partyStatusId", EntityOperator.NOT_EQUAL, "PARTY_DISABLED"),
+                                        EntityCondition.makeCondition ("thruDate", EntityOperator.EQUALS, null)
+                                    ], EntityJoinOperator.AND))
+                                    .orderBy("partyId")
+                                    .queryList();
     
-    securityGroupCond = EntityCondition.makeCondition([
-        EntityCondition.makeCondition ("partyId", EntityOperator.EQUALS, userLogin.partyId),
-        EntityCondition.makeCondition ("partyStatusId", EntityOperator.NOT_EQUAL, "PARTY_DISABLED"),
-        EntityCondition.makeCondition ("thruDate", EntityOperator.EQUALS, null)
-        ], EntityJoinOperator.AND);
-    fields = new HashSet(["partyId", "groupId"]);
-    partyAndSecurityGroupList = delegator.findList("ScrumMemberUserLoginAndSecurityGroup", securityGroupCond, fields, ["partyId"], null, false);
     context.partyAndSecurityGroupList = partyAndSecurityGroupList;
     boolean addAllProducts = false;
     allProducts.each { product ->
         product = product.getAllFields();
-        productMap = delegator.findOne("Product", ["productId" : product.productId], false);    
+        productMap = from("Product").where("productId", product.productId).queryOne();
         product.put("longDescription",productMap.longDescription)
         if(security.hasEntityPermission("SCRUM", "_ADMIN", session)){
             addAllProducts = true;
@@ -83,7 +83,7 @@
             if (partyAndSecurityGroupList) {
                 groupId = partyAndSecurityGroupList[0].groupId;
                 if ("SCRUM_PRODUCT_OWNER".equals(groupId)) {
-                    productAndRoleList = delegator.findByAnd("ProductRole", ["productId" : product.productId, "partyId" : userLogin.partyId, "thruDate" : null], null, false);
+                    productAndRoleList = from("ProductRole").where("productId", product.productId, "partyId", userLogin.partyId, "thruDate", null).queryList();
                     if (productAndRoleList) {
                         productAndRoleList.each { productAndRoleMap ->
                             productIdInner = productAndRoleMap.productId;
@@ -100,8 +100,8 @@
                         EntityCondition.makeCondition ("partyStatusId", EntityOperator.NOT_EQUAL, "PARTY_DISABLED"),
                         EntityCondition.makeCondition ("thruDate", EntityOperator.EQUALS, null)
                         ], EntityJoinOperator.AND);
-                    scrumRolesPersonAndCompanyList = delegator.findList("ScrumRolesPersonAndCompany", scrumRolesCond, null, null, null, false);
-                    productRoleList = delegator.findByAnd("ProductRole", ["partyId" : scrumRolesPersonAndCompanyList[0].partyIdFrom, "roleTypeId" : "PRODUCT_OWNER_COMP", "thruDate" : null], null, false);
+                    scrumRolesPersonAndCompanyList = from("ScrumRolesPersonAndCompany").where(scrumRolesCond).queryList();
+                    productRoleList = from("ProductRole").where("partyId", scrumRolesPersonAndCompanyList[0].partyIdFrom, "roleTypeId", "PRODUCT_OWNER_COMP", "thruDate", null).queryList();
                     if (productRoleList) {
                         productRoleList.each { productRoleMap ->
                             stakeholderProduct = productRoleMap.productId;
@@ -112,8 +112,7 @@
                    }
                    //check in product.
                     if (ismember == false) {
-                        productAndRoleList = delegator.findByAnd("ProductAndRole", ["productId" : product.productId, "partyId" : userLogin.partyId
-                            , "roleTypeId" : "STAKEHOLDER", "supportDiscontinuationDate" : null, "thruDate" : null], null, false);
+                        productAndRoleList = from("ProductAndRole").where("productId" : product.productId, "partyId" : userLogin.partyId, "roleTypeId" : "STAKEHOLDER", "supportDiscontinuationDate" : null, "thruDate" : null).queryList()
                         if (productAndRoleList) {
                             ismember = true;
                         }
@@ -121,18 +120,17 @@
                 } else if ("SCRUM_MASTER".equals(groupId)) {
                     //check in product.
                     productRoleList = [];
-                    productRoleList = delegator.findByAnd("ProductAndRole", ["productId" : product.productId, "partyId" : userLogin.partyId
-                        , "roleTypeId" : "SCRUM_MASTER", "supportDiscontinuationDate" : null, "thruDate" : null], null, false);
+                    productRoleList = from("ProductAndRole").where("productId" : product.productId, "partyId" : userLogin.partyId, "roleTypeId" : "SCRUM_MASTER", "supportDiscontinuationDate" : null, "thruDate" : null).queryList();
                     if (productRoleList) {
                         ismember = true;
                     }
                     //check in project.
                     if (ismember == false) {
                         projects = [];
-                        projects = delegator.findByAnd("WorkEffortAndProduct", ["productId" : product.productId, "workEffortTypeId" : "SCRUM_PROJECT", "currentStatusId" : "SPJ_ACTIVE"], null, false);
+                        projects = from("WorkEffortAndProduct").where("productId", product.productId, "workEffortTypeId", "SCRUM_PROJECT", "currentStatusId", "SPJ_ACTIVE").queryList();
                         if (projects) {
                             projects.each { project ->
-                                projectPartyAssignment = delegator.findByAnd("WorkEffortPartyAssignment", ["partyId" : userLogin.partyId, "workEffortId" : project.workEffortId], null, false);
+                                projectPartyAssignment = from("WorkEffortPartyAssignment").where("partyId", userLogin.partyId, "workEffortId", project.workEffortId).queryList();
                                 if (projectPartyAssignment) {
                                     ismember = true;
                                 }
@@ -143,10 +141,10 @@
                     if (ismember == false) {
                         projects.each { project ->
                             allSprintList = [];
-                            allSprintList = delegator.findByAnd("WorkEffort", ["workEffortParentId" : project.workEffortId, "currentStatusId" : "SPRINT_ACTIVE"], null, false);
+                            allSprintList = from("WorkEffort").where("workEffortParentId", project.workEffortId, "currentStatusId", "SPRINT_ACTIVE").queryList();
                             allSprintList.each { SprintListMap ->
                                 sprintId = SprintListMap.workEffortId;
-                                workEffortPartyAssignment = delegator.findByAnd("WorkEffortPartyAssignment", ["partyId" : userLogin.partyId, "workEffortId" : sprintId], null, false)
+                                workEffortPartyAssignment = from("WorkEffortPartyAssignment").where("partyId", userLogin.partyId, "workEffortId", sprintId).queryList();
                                 if (workEffortPartyAssignment) {
                                     ismember = true;
                                 }
@@ -155,14 +153,14 @@
                     }
                 } else {
                     projects = [];
-                    projects = delegator.findByAnd("WorkEffortAndProduct", ["productId" : product.productId, "workEffortTypeId" : "SCRUM_PROJECT", "currentStatusId" : "SPJ_ACTIVE"], null, false);
+                    projects = from("WorkEffortAndProduct").where("productId", product.productId, "workEffortTypeId", "SCRUM_PROJECT", "currentStatusId", "SPJ_ACTIVE").queryList();
                     if (projects) {
                         projects.each { project ->
                             allSprintList = [];
-                            allSprintList = delegator.findByAnd("WorkEffort", ["workEffortParentId" : project.workEffortId, "currentStatusId" : "SPRINT_ACTIVE"], null, false);
+                            allSprintList = from("WorkEffort").where("workEffortParentId", project.workEffortId, "currentStatusId", "SPRINT_ACTIVE").queryList();
                             allSprintList.each { SprintListMap ->
                                 sprintId = SprintListMap.workEffortId;
-                                workEffortPartyAssignment = delegator.findByAnd("WorkEffortPartyAssignment", ["partyId" : userLogin.partyId, "workEffortId" : sprintId], null, false)
+                                workEffortPartyAssignment = from("WorkEffortPartyAssignment").where("partyId", userLogin.partyId, "workEffortId", sprintId).queryList();
                                 if (workEffortPartyAssignment) {
                                     ismember = true;
                                 }
@@ -176,11 +174,11 @@
                                     EntityCondition.makeCondition("currentStatusId", EntityOperator.EQUALS, "STS_CREATED"),
                                     EntityCondition.makeCondition(exprBldr, EntityOperator.OR)];
                         unplannedBacklogCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-                        unplannedBacklogList = delegator.findList("UnPlannedBacklogsAndTasks", unplannedBacklogCond, null,null ,null, false);
+                        unplannedBacklogList = from("UnPlannedBacklogsAndTasks").where(unplannedBacklogCond).queryList();
                         if (unplannedBacklogList) {
                             unplannedBacklogList.each { unplannedMap ->
                                 workEffortId = unplannedMap.workEffortId;
-                                workEffortPartyAssignment = delegator.findByAnd("WorkEffortPartyAssignment", ["partyId" : userLogin.partyId, "workEffortId" : workEffortId], null, false)
+                                workEffortPartyAssignment = from("WorkEffortPartyAssignment").where("partyId", userLogin.partyId, "workEffortId", workEffortId).queryList();
                                 if (workEffortPartyAssignment) {
                                     ismember = true;
                                 }
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListCurrentSprints.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListCurrentSprints.groovy
index 1acf17c..c36cf29 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListCurrentSprints.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListCurrentSprints.groovy
@@ -31,15 +31,15 @@
     ], EntityJoinOperator.AND);
 fields = new HashSet(["partyId", "groupId"]);
 
-allSprints = delegator.findList("ProjectSprint", cond, null, ["projectName", "-sprintActualStartDate"], null, false);
-partyAndSecurityGroupList = delegator.findList("ScrumMemberUserLoginAndSecurityGroup", securityGroupCond, fields, ["partyId"], null, false);
+allSprints = from("ProjectSprint").where(cond).orderBy("projectName", "-sprintActualStartDate").queryList();
+partyAndSecurityGroupList = select("partyId", "groupId").from("ScrumMemberUserLoginAndSecurityGroup").where(securityGroupCond).orderBy("partyId").queryList();
 oldProjectId = null;
 newProjectId = null;
 countSprint = 0;
 sprints = [];
 allSprints.each { sprint ->
     newProjectId = sprint.projectId;
-    productAndRole = delegator.findByAnd("ProductAndRole", ["roleTypeId" : "PRODUCT_OWNER_COMP", "productId" : sprint.productId], null, false);
+    productAndRole = from("ProductAndRole").where("roleTypeId", "PRODUCT_OWNER_COMP", "productId", sprint.productId).queryList();
     companyId = "";
     companyName = "";
     if (productAndRole.size() > 0) {
@@ -49,7 +49,7 @@
     sprint = sprint.getAllFields();
     sprint.put("companyId", companyId)
     sprint.put("companyName", companyName)
-    product = delegator.findOne("Product",["productId" : sprint.productId], false);
+    product = from("Product").where("productId", sprint.productId).queryOne();
     productName = "";
     if (product != null) productName = product.internalName;
     sprint.put("productName", productName);
@@ -61,7 +61,7 @@
        if (partyAndSecurityGroupList) {
            groupId = partyAndSecurityGroupList[0].groupId;
            if ("SCRUM_PRODUCT_OWNER".equals(groupId)) {
-               productAndRoleList = delegator.findByAnd("ProductRole", ["productId" : sprint.productId, "partyId" : partyAndSecurityGroupList.getAt(0).partyId, "thruDate" : null], null, false);
+               productAndRoleList = from("ProductRole").where("productId", sprint.productId, "partyId", partyAndSecurityGroupList.getAt(0).partyId, "thruDate", null).queryList();
                if (productAndRoleList) {
                    ismember = true;
                    }
@@ -73,8 +73,8 @@
                    EntityCondition.makeCondition ("partyStatusId", EntityOperator.NOT_EQUAL, "PARTY_DISABLED"),
                    EntityCondition.makeCondition ("thruDate", EntityOperator.EQUALS, null)
                    ], EntityJoinOperator.AND);
-               scrumRolesPersonAndCompanyList = delegator.findList("ScrumRolesPersonAndCompany", scrumRolesCond, null, null, null, false);
-               productRoleList = delegator.findByAnd("ProductRole", ["partyId" : scrumRolesPersonAndCompanyList[0].partyIdFrom, "roleTypeId" : "PRODUCT_OWNER_COMP", "thruDate" : null], null, false);
+               scrumRolesPersonAndCompanyList = from("ScrumRolesPersonAndCompany").where(scrumRolesCond).queryList();
+               productRoleList = from("ProductRole").where("partyId", scrumRolesPersonAndCompanyList[0].partyIdFrom, "roleTypeId", "PRODUCT_OWNER_COMP", "thruDate", null).queryList();
                if (productRoleList) {
                    productRoleList.each { productRoleMap ->
                        stakeholderProduct = productRoleMap.productId;
@@ -85,8 +85,10 @@
                }
                //check in product.
                if (ismember == false) {
-                   productAndRoleList = delegator.findByAnd("ProductAndRole", ["productId" : sprint.productId, "partyId" : userLogin.partyId
-                       , "roleTypeId" : "STAKEHOLDER", "supportDiscontinuationDate" : null, "thruDate" : null], null, false);
+                   productAndRoleList = from("ProductAndRole")
+                                           .where("productId", sprint.productId, "partyId", userLogin.partyId, "roleTypeId", "STAKEHOLDER", 
+                                               "supportDiscontinuationDate", null, "thruDate", null)
+                                           .queryList();
                    if (productAndRoleList) {
                        ismember = true;
                    }
@@ -94,14 +96,17 @@
            } else if("SCRUM_MASTER".equals(groupId)) {
                //check in product
                productRoleList = [];
-               productRoleList = delegator.findByAnd("ProductAndRole", ["productId" : sprint.productId, "partyId" : userLogin.partyId
-                   , "roleTypeId" : "SCRUM_MASTER", "supportDiscontinuationDate" : null, "thruDate" : null], null, false);
+               productRoleList = from("ProductAndRole")
+                   .where("productId" : sprint.productId, "partyId" : userLogin.partyId, 
+                       "roleTypeId" : "SCRUM_MASTER", "supportDiscontinuationDate" : null, "thruDate" : null)
+                   .queryList();
+               
                if (productRoleList) {
                    ismember = true;
                }
                //check in project.
                if (ismember == false) {
-                   projectPartyAssignment = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : sprint.projectId, "partyId" : userLogin.partyId], null, false);
+                   projectPartyAssignment = from("WorkEffortPartyAssignment").where("workEffortId", sprint.projectId, "partyId", userLogin.partyId).queryList();
                    if (projectPartyAssignment) {
                        ismember = true;
                    }
@@ -109,10 +114,10 @@
                //check in sprint.
                if (ismember == false) {
                    allSprintList = [];
-                   allSprintList = delegator.findByAnd("WorkEffort", ["workEffortParentId" : sprint.projectId], null, false);
+                   allSprintList = from("WorkEffort").where("workEffortParentId", sprint.projectId).queryList();
                    allSprintList.each { SprintListMap ->
                        sprintId = SprintListMap.workEffortId;
-                       workEffortPartyAssignment = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : sprintId, "partyId" : userLogin.partyId], null, false);
+                       workEffortPartyAssignment = from("WorkEffortPartyAssignment").where("workEffortId", sprintId, "partyId", userLogin.partyId).queryList();
                        if (workEffortPartyAssignment) {
                            ismember = true;
                        }
@@ -120,10 +125,10 @@
                }
            } else {
                allSprintList = [];
-               allSprintList = delegator.findByAnd("WorkEffort", ["workEffortParentId" : sprint.projectId], null, false);
+               allSprintList = from("WorkEffort").where("workEffortParentId", sprint.projectId).queryList();
                allSprintList.each { SprintListMap ->
                    sprintId = SprintListMap.workEffortId;
-                   workEffortPartyAssignment = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : sprintId, "partyId" : userLogin.partyId], null, false);
+                   workEffortPartyAssignment = from("WorkEffortPartyAssignment").where("workEffortId", sprintId, "partyId", userLogin.partyId).queryList();
                    if (workEffortPartyAssignment) {
                        ismember = true;
                    }
@@ -143,7 +148,7 @@
            if (partyAndSecurityGroupList) {
                groupId = partyAndSecurityGroupList[0].groupId;
                if ("SCRUM_PRODUCT_OWNER".equals(groupId)) {
-                   productAndRoleList = delegator.findByAnd("ProductRole", ["productId" : sprint.productId, "partyId" : partyAndSecurityGroupList.getAt(0).partyId, "thruDate" : null], null, false);
+                   productAndRoleList = from("ProductRole").where("productId", sprint.productId, "partyId", partyAndSecurityGroupList.getAt(0).partyId, "thruDate", null).queryList();
                    if (productAndRoleList) {
                        ismember = true;
                    }
@@ -155,8 +160,8 @@
                            EntityCondition.makeCondition ("partyStatusId", EntityOperator.NOT_EQUAL, "PARTY_DISABLED"),
                            EntityCondition.makeCondition ("thruDate", EntityOperator.EQUALS, null)
                            ], EntityJoinOperator.AND);
-                       scrumRolesPersonAndCompanyList = delegator.findList("ScrumRolesPersonAndCompany", scrumRolesCond, null, null, null, false);
-                       productRoleList = delegator.findByAnd("ProductRole", ["partyId" : scrumRolesPersonAndCompanyList[0].partyIdFrom, "roleTypeId" : "PRODUCT_OWNER_COMP", "thruDate" : null], null, false);
+                       scrumRolesPersonAndCompanyList = from("ScrumRolesPersonAndCompany").where(scrumRolesCond).queryList();
+                       productRoleList = from("ProductRole").where("partyId", scrumRolesPersonAndCompanyList[0].partyIdFrom, "roleTypeId", "PRODUCT_OWNER_COMP", "thruDate", null).queryList();
                        if (productRoleList) {
                            productRoleList.each { productRoleMap ->
                                stakeholderProduct = productRoleMap.productId;
@@ -167,8 +172,7 @@
                       }
                        //check in product.
                        if (ismember == false) {
-                           productAndRoleList = delegator.findByAnd("ProductAndRole", ["productId" : sprint.productId, "partyId" : userLogin.partyId
-                               , "roleTypeId" : "STAKEHOLDER", "supportDiscontinuationDate" : null, "thruDate" : null], null, false);
+                           productAndRoleList = from("ProductAndRole").where("productId" : sprint.productId, "partyId" : userLogin.partyId, "roleTypeId" : "STAKEHOLDER", "supportDiscontinuationDate" : null, "thruDate" : null).queryList();
                            if (productAndRoleList) {
                                ismember = true;
                            }
@@ -176,14 +180,13 @@
                } else if("SCRUM_MASTER".equals(groupId)) {
                        //check in product
                        productRoleList = [];
-                       productRoleList = delegator.findByAnd("ProductAndRole", ["productId" : sprint.productId, "partyId" : userLogin.partyId
-                           , "roleTypeId" : "SCRUM_MASTER", "supportDiscontinuationDate" : null, "thruDate" : null], null, false);
+                       productRoleList = from("ProductAndRole").where("productId" : sprint.productId, "partyId" : userLogin.partyId, "roleTypeId" : "SCRUM_MASTER", "supportDiscontinuationDate" : null, "thruDate" : null).queryList();
                        if (productRoleList) {
                            ismember = true;
                        }
                        //check in project.
                        if (ismember == false) {
-                           projectPartyAssignment = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : sprint.projectId, "partyId" : userLogin.partyId], null, false);
+                           projectPartyAssignment = from("WorkEffortPartyAssignment").where("workEffortId", sprint.projectId, "partyId", userLogin.partyId).queryList();
                            if (projectPartyAssignment) {
                                ismember = true;
                            }
@@ -191,10 +194,10 @@
                        //check in sprint.
                        if (ismember == false) {
                            allSprintList = [];
-                           allSprintList = delegator.findByAnd("WorkEffort", ["workEffortParentId" : sprint.projectId], null, false);
+                           allSprintList = from("WorkEffort").where("workEffortParentId", sprint.projectId).queryList();
                            allSprintList.each { SprintListMap ->
                                sprintId = SprintListMap.workEffortId;
-                               workEffortPartyAssignment = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : sprintId, "partyId" : userLogin.partyId], null, false);
+                               workEffortPartyAssignment = from("WorkEffortPartyAssignment").where("workEffortId", sprintId, "partyId", userLogin.partyId).queryList();
                                if (workEffortPartyAssignment) {
                                    ismember = true;
                                }
@@ -202,10 +205,10 @@
                        }
                } else {
                    allSprintList = [];
-                   allSprintList = delegator.findByAnd("WorkEffort", ["workEffortParentId" : sprint.projectId], null, false);
+                   allSprintList = from("WorkEffort").where("workEffortParentId", sprint.projectId).queryList();
                    allSprintList.each { SprintListMap ->
                        sprintId = SprintListMap.workEffortId;
-                       workEffortPartyAssignment = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : sprintId, "partyId" : userLogin.partyId], null, false);
+                       workEffortPartyAssignment = from("WorkEffortPartyAssignment").where("workEffortId", sprintId, "partyId", userLogin.partyId).queryList();
                        if (workEffortPartyAssignment) {
                            ismember = true;
                        }
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListRevision.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListRevision.groovy
index f7d1aea..3c1870c 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListRevision.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListRevision.groovy
@@ -40,7 +40,7 @@
     }
     andList.add(EntityCondition.makeCondition(orList, EntityOperator.OR));
     custRequestCond = EntityCondition.makeCondition(andList, EntityOperator.AND);
-    custRequestList = delegator.findList("CustRequestAndCustRequestItem", custRequestCond, null,null ,null, false);
+    custRequestList = from("CustRequestAndCustRequestItem").where(custRequestCond).queryList();
     
     custRequestIds = EntityUtil.getFieldListFromEntityList(custRequestList, "custRequestId", true);
     taskOrList =  [];
@@ -52,7 +52,7 @@
     taskAndList.add(EntityCondition.makeCondition("custRequestId", EntityOperator.IN, custRequestIds));
     taskAndList.add(EntityCondition.makeCondition(taskOrList, EntityOperator.OR));
     custAndWorkEffortCond = EntityCondition.makeCondition(taskAndList, EntityOperator.AND);
-    custAndWorkEffortList = delegator.findList("CustRequestAndWorkEffort", custAndWorkEffortCond, null,null ,null, false);
+    custAndWorkEffortList = from("CustRequestAndWorkEffort").where(custAndWorkEffortCond).queryList();
     
     //for workEffortId
     workEffortIds = EntityUtil.getFieldListFromEntityList(custAndWorkEffortList, "workEffortId", true);
@@ -64,7 +64,7 @@
     }
     revisionAndList.add(EntityCondition.makeCondition("workEffortContentTypeId", EntityOperator.EQUALS, "TASK_SUB_INFO"));
     revisionCond = EntityCondition.makeCondition(revisionAndList, EntityOperator.AND);
-    revisionList = delegator.findList("WorkEffortAndContentDataResource", revisionCond, null,["-fromDate"] ,null, false);
+    revisionList = from("WorkEffortAndContentDataResource").where(revisionCond).orderBy("-fromDate").queryList();
     
     if (revisionList) {
         revisionList.each { revisionMap ->
@@ -75,10 +75,10 @@
             inputMap.contentName = revisionMap.contentName;
             inputMap.description = revisionMap.description;
             inputMap.drObjectInfo = revisionMap.drObjectInfo;
-            custAndWorkEfffList = delegator.findByAnd("CustRequestAndWorkEffort", ["workEffortId" : revisionMap.workEffortId], null, false);
+            custAndWorkEfffList = from("CustRequestAndWorkEffort").where("workEffortId", revisionMap.workEffortId).queryList();
             if (custAndWorkEfffList) {
                 custAndWorkEfffMap = custAndWorkEfffList[0];
-                custAndCustItemList = delegator.findByAnd("CustRequestAndCustRequestItem", ["custRequestId" : custAndWorkEfffMap.custRequestId], null, false);
+                custAndCustItemList = from("CustRequestAndCustRequestItem").where("custRequestId", custAndWorkEfffMap.custRequestId).queryList();
                 if (custAndCustItemList) {
                     custAndCustItemMap = custAndCustItemList[0];
                     inputMap.productId = custAndCustItemMap.productId;
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListScrumPreferenceSecurityGroup.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListScrumPreferenceSecurityGroup.groovy
index 8b28740..45b60fd 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListScrumPreferenceSecurityGroup.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListScrumPreferenceSecurityGroup.groovy
@@ -47,7 +47,7 @@
 
 combinedConds = EntityCondition.makeCondition(combinedCondList, EntityOperator.AND);
 
-scrumUserLoginSecurityGroupList = delegator.findList("ScrumMemberUserLoginAndSecurityGroup", combinedConds, null, null, null, false);
+scrumUserLoginSecurityGroupList = from("ScrumMemberUserLoginAndSecurityGroup").where(combinedConds).queryList();
 userPreferenceList = [];
 userPreferenceOutList = [];
 if (scrumUserLoginSecurityGroupList) {
@@ -57,13 +57,13 @@
             ownerCond.add(EntityCondition.makeCondition("enumTypeId", EntityOperator.EQUALS, "SCRUM_PREFERENCE"));
             ownerCond.add(EntityCondition.makeCondition("enumId", EntityOperator.NOT_EQUAL, "MASTER_NOTIFY"));
             ownerConds = EntityCondition.makeCondition(ownerCond, EntityOperator.AND);
-            userPreferenceList = delegator.findList("Enumeration" , ownerConds, null, null, null, false);
+            userPreferenceList = from("Enumeration").where(ownerConds).queryList();
         } else if (scrumUserLoginSecurityGroupMap.groupId == "SCRUM_MASTER") {
             masterCond = FastList.newInstance();
             masterCond.add(EntityCondition.makeCondition("enumTypeId", EntityOperator.EQUALS, "SCRUM_PREFERENCE"));
             masterCond.add(EntityCondition.makeCondition("enumId", EntityOperator.EQUALS, "MASTER_NOTIFY"));
             masterConds = EntityCondition.makeCondition(masterCond, EntityOperator.AND);
-            userPreferenceList = delegator.findList("Enumeration" , masterConds, null, null, null, false);
+            userPreferenceList = from("Enumeration").where(masterConds).queryList();
         } /*else if (scrumUserLoginSecurityGroupMap.groupId == "SCRUM_TEAM") {
             teamCond = FastList.newInstance();
             teamCond.add(EntityCondition.makeCondition("enumTypeId", EntityOperator.EQUALS, "SCRUM_PREFERENCE"));
@@ -80,7 +80,7 @@
     context.userPreferenceList = userPreferenceOutList;
 } else {
     if (security.hasEntityPermission("SCRUM", "_ADMIN", session)) {
-        userPreferenceList = delegator.findByAnd("Enumeration", [enumTypeId : "SCRUM_PREFERENCE"], ["sequenceId"], false);
+        userPreferenceList = from("Enumeration").where("enumTypeId", "SCRUM_PREFERENCE").queryList();
         context.userPreferenceList = userPreferenceList;
     }
 }
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListScrumResource.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListScrumResource.groovy
index 68e01fd..18836f2 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListScrumResource.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListScrumResource.groovy
@@ -41,7 +41,7 @@
 if (parameters.sortField) {
 	performFindInMap.orderBy = "lastName";
 }
-performFindResults = dispatcher.runSync("performFind", performFindInMap);
+performFindResults = runService('performFind', performFindInMap);
 resultList = performFindResults.listIt.getCompleteList();
 performFindResults.listIt.close();
 
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListScrumRolesPersonAndCompany.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListScrumRolesPersonAndCompany.groovy
index dc1d480..8090107 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListScrumRolesPersonAndCompany.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListScrumRolesPersonAndCompany.groovy
@@ -25,7 +25,7 @@
 personAndCompanyList = [];
 
 if (productId) {
-    productRoleList = delegator.findByAnd("ProductRole", ["productId" : productId, "roleTypeId" : "PRODUCT_OWNER_COMP"], null, false);
+    productRoleList = from("ProductRole").where("productId" : productId, "roleTypeId" : "PRODUCT_OWNER_COMP").queryList();
     if (productRoleList) {
         personAndComCond = EntityCondition.makeCondition([
             EntityCondition.makeCondition ("roleTypeId", EntityOperator.EQUALS, "PRODUCT_OWNER"),
@@ -33,7 +33,7 @@
             EntityCondition.makeCondition ("partyStatusId", EntityOperator.NOT_EQUAL, "PARTY_DISABLED"),
             EntityCondition.makeCondition ("thruDate", EntityOperator.EQUALS, null)
             ], EntityJoinOperator.AND);
-        personAndCompanyList = delegator.findList("ScrumRolesPersonAndCompany", personAndComCond, null, ["groupName"], null, false);
+        personAndCompanyList = from("ScrumRolesPersonAndCompany").where(personAndComCond).orderBy("groupName").queryList();
     }
 }
 if (personAndCompanyList) {
@@ -50,7 +50,7 @@
     EntityCondition.makeCondition ("partyStatusId", EntityOperator.NOT_EQUAL, "PARTY_DISABLED"),
     EntityCondition.makeCondition ("thruDate", EntityOperator.EQUALS, null)
     ], EntityJoinOperator.AND);
-personAndCompanyList = delegator.findList("ScrumRolesPersonAndCompany", personAndComConds, null, ["groupName"], null, false);
+personAndCompanyList = from("ScrumRolesPersonAndCompany").where(personAndComConds).orderBy("groupName").queryList();
 if (personAndCompanyList) {
     personAndCompanyList.each { personAndCompanyMap ->
         partyId = personAndCompanyMap.partyId;
@@ -58,7 +58,7 @@
             EntityCondition.makeCondition ("partyId", EntityOperator.EQUALS, partyId),
             EntityCondition.makeCondition ("partyStatusId", EntityOperator.NOT_EQUAL, "PARTY_DISABLED")
             ], EntityJoinOperator.AND);
-        securityGroupList = delegator.findList("ScrumMemberUserLoginAndSecurityGroup", securityGroupCond, null, null, null, false);
+        securityGroupList = from("ScrumMemberUserLoginAndSecurityGroup").where(securityGroupCond).queryList();
         if (securityGroupList) {
             scrumRolesPersonAndCompanyList.add(personAndCompanyMap);
             }
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListTimeSheets.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListTimeSheets.groovy
index c82b191..32c64bf 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListTimeSheets.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListTimeSheets.groovy
@@ -25,17 +25,13 @@
 
 // get all timesheets of all user, including the planned hours
 timesheets = [];
-performFindInMap = [:];
 inputFields = [:];
-performFindInMap.entityName = "Timesheet";
 
 if (!parameters.noConditionFind) {
     parameters.noConditionFind = "N"
 }
 inputFields.putAll(parameters);
-performFindInMap.inputFields = inputFields;
-performFindInMap.orderBy = "fromDate DESC";
-performFindResults = dispatcher.runSync("performFind", performFindInMap);
+performFindResults = runService('performFind', ["entityName": "Timesheet", "inputFields": inputFields, "orderBy": "fromDate DESC"]);
 if (performFindResults.listSize > 0) {
     timesheetsDb = performFindResults.listIt.getCompleteList();
     performFindResults.listIt.close();
@@ -47,17 +43,13 @@
         leaveExprsList.add(EntityCondition.makeCondition("fromDate", EntityOperator.GREATER_THAN_EQUAL_TO, timesheetDb.fromDate));
         leaveExprsList.add(EntityCondition.makeCondition("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, timesheetDb.thruDate));
         leaveExprsList.add(EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, timesheetDb.partyId));
-        emplLeaveList = delegator.find("EmplLeave", EntityCondition.makeCondition(leaveExprsList, EntityOperator.AND), null, null, null, findOpts);
+        emplLeaveList = from("EmplLeave").where(leaveExprsList).cursorScrollInsensitive().distinct().queryIterator();
         leaveHours = 0.00;
         
         while ((emplLeaveMap = emplLeaveList.next())) {
             emplLeaveEntry = emplLeaveMap;
-            inputData = [:];
-            inputData.userLogin = parameters.userLogin;
-            inputData.partyId = emplLeaveEntry.partyId;
-            inputData.leaveTypeId = emplLeaveEntry.leaveTypeId;
-            inputData.fromDate = emplLeaveEntry.fromDate;
-            resultHour = dispatcher.runSync("getPartyLeaveHoursForDate", inputData);
+            resultHour = runService('getPartyLeaveHoursForDate', 
+                ["userLogin": parameters.userLogin, "partyId": emplLeaveEntry.partyId, "leaveTypeId": emplLeaveEntry.leaveTypeId, "fromDate": emplLeaveEntry.fromDate]);
             if (resultHour) {
                 leaveActualHours = resultHour.hours.doubleValue();
                 leaveHours += leaveActualHours;
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListUnplanBacklog.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListUnplanBacklog.groovy
index 5491c90..39ac177 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListUnplanBacklog.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ListUnplanBacklog.groovy
@@ -43,7 +43,7 @@
     andExprs.add(EntityCondition.makeCondition(orStsExprs, EntityOperator.OR));
     andExprs.add(EntityCondition.makeCondition(orCurentExprs, EntityOperator.OR));
 unplannedBacklogCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-unplannedBacklogList = delegator.findList("UnPlannedBacklogsAndTasks", unplannedBacklogCond, null,["-custRequestId","workEffortTypeId","custSequenceNum"],null, false);
+unplannedBacklogList = from("UnPlannedBacklogsAndTasks").where(unplannedBacklogCond).orderBy("-custRequestId","workEffortTypeId","custSequenceNum").queryList();
 
 context.listIt = unplannedBacklogList;
 context.paraBacklogStatusId = paraBacklogStatusId;
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ProductBilling.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ProductBilling.groovy
index def6daf..665178c 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ProductBilling.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ProductBilling.groovy
@@ -31,9 +31,8 @@
         EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId),
         EntityCondition.makeCondition("invoiceId", EntityOperator.NOT_EQUAL, null),
         ], EntityOperator.AND);
-orderBy = ["-fromDate"];
 // check if latest invoice generated is still in process so allow re-generation to correct errors
-entryIterator = delegator.find("ProjectSprintBacklogTaskAndTimeEntryTimeSheet", entryExprs, null, null, orderBy, null);
+entryIterator = from("ProjectSprintBacklogTaskAndTimeEntryTimeSheet").where(entryExprs).orderBy("-fromDate").queryIterator();
 while (entryItem = entryIterator.next()) {
     invoice = entryItem.getRelatedOne("Invoice", false);
     if (invoice.getString("statusId").equals("INVOICE_IN_PROCESS")) {
@@ -73,13 +72,13 @@
     taskConds.add(EntityCondition.makeCondition("custRequestTypeId", EntityOperator.NOT_EQUAL, "RF_SCRUM_MEETINGS"));
 }
 // get sprint task list
-def sprintTasks = delegator.findList("ProjectSprintBacklogTaskAndTimeEntryTimeSheet", EntityCondition.makeCondition(taskConds), null, null, null, false);
+def sprintTasks = from("ProjectSprintBacklogTaskAndTimeEntryTimeSheet").where(taskConds).queryList();
 
 // get cancelled backlog task list
-def cancelledBacklogTasks = delegator.findList("CancelledBacklogsTaskAndTimeEntryTimeSheet", EntityCondition.makeCondition(taskConds), null, null, null, false);
+def cancelledBacklogTasks = from("CancelledBacklogsTaskAndTimeEntryTimeSheet").where(taskConds).queryList();
 
 // get unplanned task list
-def unplannedTasks = delegator.findList("UnPlannedBacklogsTaskAndTimeEntryTimeSheet", EntityCondition.makeCondition(taskConds), null, null, null, false);
+def unplannedTasks = from("UnPlannedBacklogsTaskAndTimeEntryTimeSheet").where(taskConds).queryList();
 
 def hoursNotYetBilledTasks = [];
 hoursNotYetBilledTasks.addAll(sprintTasks);
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ProductEmail.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ProductEmail.groovy
index 3717401..add2cf2 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ProductEmail.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/ProductEmail.groovy
@@ -32,33 +32,33 @@
 try{
     if (UtilValidate.isNotEmpty(loginPartyId)) {
         if (UtilValidate.isNotEmpty(productId)) {
-        context.product = delegator.findOne("Product",["productId" : productId], false);
+        context.product = from("Product").where("productId", productId).queryOne();
         }
-        communicationEvent = delegator.findOne("CommunicationEvent",["communicationEventId" : communicationEventId], false);
+        communicationEvent = from("CommunicationEvent").where("communicationEventId", communicationEventId).queryOne();
         communicationEvent.communicationEventTypeId = "EMAIL_COMMUNICATION";
         communicationEvent.contactMechTypeId = "EMAIL_ADDRESS";
         communicationEvent.datetimeStarted = now;
-        checkOwner = delegator.findByAnd("ProductRole",["productId" : productId,"partyId" : loginPartyId,"roleTypeId" : "PRODUCT_OWNER"], null, false);
+        checkOwner = from("ProductRole").where("productId", productId,"partyId", loginPartyId,"roleTypeId", "PRODUCT_OWNER").queryList();
         if (checkOwner) {
             /* for product owner to our company */
             
             // for owner
-            productRole = delegator.findByAnd("ProductRole",["productId" : productId,"roleTypeId" : "PRODUCT_OWNER"], null, false);
+            productRole = from("ProductRole").where("productId", productId,"roleTypeId", "PRODUCT_OWNER").queryList();
             context.productOwnerId = productRole[0].partyId
-            parentCom = delegator.findOne("CommunicationEvent",["communicationEventId" : communicationEventId], false);
+            parentCom = from("CommunicationEvent").where("communicationEventId", communicationEventId).queryOne();
             if (parentCom) {
                 context.partyIdFrom = productRole[0].partyId;
             } else {
                 context.partyIdFrom = parentCom.partyIdTo;
             }
-            resultsIdFrom = dispatcher.runSync("getPartyEmail", ["partyId" : productRole[0].partyId, "userLogin" : userLogin]);
+            resultsIdFrom = runService('getPartyEmail', ["partyId" : productRole[0].partyId, "userLogin" : userLogin]);
             if (resultsIdFrom.contactMechId != null) {
                 context.contactMechIdFrom = resultsIdFrom.contactMechId;
                 communicationEvent.contactMechIdFrom = resultsIdFrom.contactMechId;
             }
             // for team
             defaultPartyIdTo = organizationPartyId;
-            resultsIdTo = dispatcher.runSync("getPartyEmail", ["partyId" : defaultPartyIdTo,"contactMechPurposeTypeId" :"SUPPORT_EMAIL", "userLogin" : userLogin]);
+            resultsIdTo = runService('getPartyEmail', ["partyId" : defaultPartyIdTo,"contactMechPurposeTypeId" :"SUPPORT_EMAIL", "userLogin" : userLogin]);
             if (resultsIdTo.contactMechId != null) {
                 context.contactMechIdTo = resultsIdTo.contactMechId;
                 communicationEvent.contactMechIdTo = resultsIdTo.contactMechId;
@@ -72,21 +72,21 @@
             // for team
             defaultPartyIdFrom = organizationPartyId;
             context.partyIdFrom = defaultPartyIdFrom;
-            resultsIdFrom = dispatcher.runSync("getPartyEmail", ["partyId" : defaultPartyIdFrom,"contactMechPurposeTypeId" :"SUPPORT_EMAIL", "userLogin" : userLogin]);
+            resultsIdFrom = runService('getPartyEmail', ["partyId" : defaultPartyIdFrom,"contactMechPurposeTypeId" :"SUPPORT_EMAIL", "userLogin" : userLogin]);
             if (resultsIdFrom.contactMechId != null) {
                 context.contactMechIdFrom = resultsIdFrom.contactMechId;
                 communicationEvent.contactMechIdFrom = resultsIdFrom.contactMechId;
             }
             // for owner
-            productRole = delegator.findByAnd("ProductRole",["productId" : productId,"roleTypeId" : "PRODUCT_OWNER"], null, false);
+            productRole = from("ProductRole").where("productId", productId,"roleTypeId", "PRODUCT_OWNER").queryList();
             context.productOwnerId = productRole[0].partyId;
-            parentCom = delegator.findOne("CommunicationEvent",["communicationEventId" : communicationEventId], false);
+            parentCom = from("CommunicationEvent").where("communicationEventId", communicationEventId).queryOne();
             if(parentCom){
                 context.partyIdTo = productRole[0].partyId;
             } else {
                  context.partyIdTo = parentCom.partyIdFrom;
             }
-           resultsIdTo = dispatcher.runSync("getPartyEmail", ["partyId" : productRole[0].partyId, "userLogin" : userLogin]);
+           resultsIdTo = runService('getPartyEmail', ["partyId" : productRole[0].partyId, "userLogin" : userLogin]);
            if (resultsIdTo.contactMechId != null) {
               context.contactMechIdTo = resultsIdTo.contactMechId;
               communicationEvent.contactMechIdTo = resultsIdTo.contactMechId;
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/QuickAddBacklog.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/QuickAddBacklog.groovy
index 17e34a5..03699c1 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/QuickAddBacklog.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/QuickAddBacklog.groovy
@@ -22,17 +22,17 @@
 try{
     // for sprint dropdown
     workEffortList = [];
-    sprintList = delegator.findByAnd("WorkEffort",["workEffortTypeId" : "SCRUM_SPRINT","currentStatusId" : "SPRINT_ACTIVE"], null, false);
+    sprintList = from("WorkEffort").where("workEffortTypeId", "SCRUM_SPRINT","currentStatusId", "SPRINT_ACTIVE").queryList();
     if (sprintList) {
         sprintList.each{ sprintMap ->
             workEffortMap = [:];
             workEffortParentId = sprintMap.workEffortParentId;
             if (workEffortParentId) {
-               projectList = delegator.findByAnd("WorkEffortAndProduct",["workEffortId" : workEffortParentId], null, false);
+               projectList = from("WorkEffortAndProduct").where("workEffortId", workEffortParentId).queryList();
                projectMap = projectList[0];
                // make sure that project dose not closed
                if (projectMap.currentStatusId != "SPJ_CLOSED") {
-                   productMap = delegator.findOne("Product",["productId" : projectMap.productId], false);
+                   productMap = from("Product").where("productId", projectMap.productId).queryOne();
                    workEffortMap.productId = productMap.productId;
                    workEffortMap.internalName = returnNameAsString(productMap.internalName,30);
                    workEffortMap.projectId = projectMap.workEffortId;
@@ -59,16 +59,16 @@
     }
     categoryList = [];
     if (productId) {
-        sprintList = delegator.findByAnd("CustRequestAndCustRequestItem",["custRequestTypeId" : "RF_PARENT_BACKLOG","productId" : productId], null, false);
+        sprintList = from("CustRequestAndCustRequestItem").where("custRequestTypeId", "RF_PARENT_BACKLOG","productId", productId).queryList();
     } else {
-        sprintList = delegator.findByAnd("CustRequestAndCustRequestItem",["custRequestTypeId" : "RF_PARENT_BACKLOG"], null, false);
+        sprintList = from("CustRequestAndCustRequestItem").where("custRequestTypeId", "RF_PARENT_BACKLOG").queryList();
     }
     if (sprintList) {
         sprintList.each{ categoryMap ->
             inputMap = [:];
             productIdIn = categoryMap.productId;
             if (productIdIn) {
-               productMap = delegator.findOne("Product",["productId" : productIdIn], false);
+               productMap = from("Product").where("productId", productIdIn).queryOne();
                inputMap.productId = productMap.productId;
                inputMap.internalName = productMap.internalName;
                inputMap.custRequestId = categoryMap.custRequestId;
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/SprintBacklogListItems.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/SprintBacklogListItems.groovy
index 9f7bc9c..bd47c62 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/SprintBacklogListItems.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/SprintBacklogListItems.groovy
@@ -67,7 +67,7 @@
     andExprs.add(EntityCondition.makeCondition("sprintTypeId", EntityOperator.EQUALS, "SCRUM_SPRINT"));
     
 projectSprintCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
-projectSprintList = delegator.findList("ProjectSprintBacklogAndTask", projectSprintCond, null,["custSequenceNum","custRequestId","taskTypeId"],null, false);
+projectSprintList = from("ProjectSprintBacklogAndTask").where(andExprs).orderBy("custSequenceNum","custRequestId","taskTypeId").queryList();
 
 context.listIt = projectSprintList;
 context.paraBacklogStatusId = paraBacklogStatusId;
@@ -79,7 +79,7 @@
     reviewedBacklog = 0;
     totalbacklog = 0;
     allTask = [];
-    sprintList = delegator.findByAnd("CustRequestWorkEffort", ["workEffortId" : parameters.sprintId], null, false);
+    sprintList = from("CustRequestWorkEffort").where("workEffortId", parameters.sprintId).queryList();
     sprintList.each { sprintMap ->
         custMap = sprintMap.getRelatedOne("CustRequest", false);
         //if ("RF_PROD_BACKLOG".equals(custMap.custRequestTypeId)) {
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/TaskList.groovy b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/TaskList.groovy
index e497334..b7fc226 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/TaskList.groovy
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/TaskList.groovy
@@ -38,14 +38,14 @@
 
 //${projectId} - ${projectName} - ${sprintName} - ${groovy:description.substring(0,Math.min(description.length(),30))}[${custRequestId}] - ${groovy:taskName.substring(0,Math.min(taskName.length(),20))}[${taskId}]"/>
 
-taskUnplanList = delegator.findByAnd("ProjectSprintBacklogTaskAndParty", ["partyId" : partyId,"taskCurrentStatusId": "STS_CREATED","custRequestTypeId":"RF_UNPLAN_BACKLOG"],["taskTypeId"], false);
+taskUnplanList = from("ProjectSprintBacklogTaskAndParty").where("partyId", partyId,"taskCurrentStatusId", "STS_CREATED","custRequestTypeId","RF_UNPLAN_BACKLOG").orderBy("taskTypeId").queryList();
 taskUnplanList.each { taskUnplanMap ->
 	unplanMap=[:];
 	custRequestId = taskUnplanMap.custRequestId;
-	productlist = delegator.findByAnd("CustRequestItem", ["custRequestId" : custRequestId],["productId"], false);
+	productlist = from("CustRequestItem").where("custRequestId", custRequestId).orderBy("productId").queryList();
 	productlist.each { productMap ->
 		productId = productMap.productId;
-		product = delegator.findOne("Product",["productId":productId], false);
+		product = from("Product").where("productId", productId).queryOne();
 			productName = product.internalName;
 			unplanMap.taskId = taskUnplanMap.taskId;
 			unplanMap.taskName = taskUnplanMap.taskName;
@@ -72,11 +72,11 @@
 andExprs.add(EntityCondition.makeCondition(exprBldr, EntityOperator.OR));
 custRequestTypeCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
 
-taskPlanList = delegator.findList("ProjectSprintBacklogTaskAndParty", custRequestTypeCond, null,["taskTypeId","projectId","sprintId"] ,null, false);
+taskPlanList = from("ProjectSprintBacklogTaskAndParty").where(custRequestTypeCond).orderBy("taskTypeId","projectId","sprintId").queryList();
 taskPlanList.each { taskPlanMap ->
     planMap=[:];
     if ("RF_SCRUM_MEETINGS".equals(taskPlanMap.custRequestTypeId)) {
-        workEffPartyAssignedList = delegator.findByAnd("WorkEffortPartyAssignment",["partyId" : partyId, "workEffortId" : taskPlanMap.taskId], null, false);
+        workEffPartyAssignedList = from("WorkEffortPartyAssignment").where("partyId", partyId, "workEffortId", taskPlanMap.taskId).queryList();
         workEffPartyAssignedMap = workEffPartyAssignedList[0];
         if (!"SCAS_COMPLETED".equals(workEffPartyAssignedMap.statusId)) {
             taskPartyList.add(taskPlanMap);
@@ -88,8 +88,8 @@
             taskListDropdown.add(taskPlanMap);
         } else {
             custRequestId = taskPlanMap.custRequestId;
-            productlist = delegator.findByAnd("CustRequestItem", ["custRequestId" : custRequestId],["productId"], false);
-            product = delegator.findOne("Product",["productId":productlist[0].productId], false);
+            productlist = from("CustRequestItem").where("custRequestId", custRequestId).orderBy("productId").queryList();
+            product = from("Product").where("productId", productlist[0].productId).queryOne();
             productName = product.internalName;
             planMap.taskId = taskPlanMap.taskId;
             planMap.taskTypeId = taskPlanMap.taskTypeId;
diff --git a/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/Login.groovy b/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/Login.groovy
index 49239a9..06bb648 100644
--- a/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/Login.groovy
+++ b/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/Login.groovy
@@ -42,8 +42,8 @@
     facilityId = productStore.getString("inventoryFacilityId");
 
     if (facilityId) {
-        context.posTerminals = delegator.findList("PosTerminal", EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, facilityId), null, ["posTerminalId"], null, false);
+        context.posTerminals = from("PosTerminal").where("facilityId", facilityId).orderBy("posTerminalId").queryList();
     } else {
-        context.posTerminals = delegator.findList("PosTerminal", null, null, ["posTerminalId"], null, false);
+        context.posTerminals = from("PosTerminal").orderBy("posTerminalId").queryList();
     }
 }
diff --git a/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/cart/ShowCart.groovy b/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/cart/ShowCart.groovy
index 54630db..3e152e7 100644
--- a/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/cart/ShowCart.groovy
+++ b/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/cart/ShowCart.groovy
@@ -35,7 +35,7 @@
     
     context.person = null;
     if (UtilValidate.isNotEmpty(shoppingCart)) {
-        placingCustomerParty = delegator.findOne("PartyAndPerson", [partyId : shoppingCart.getPlacingCustomerPartyId()], false);
+        placingCustomerParty = from("PartyAndPerson").where("partyId", shoppingCart.getPlacingCustomerPartyId()).queryOne();
         if (UtilValidate.isNotEmpty(placingCustomerParty)) {
             context.person = placingCustomerParty.lastName + " " + placingCustomerParty.firstName;
         }
@@ -79,7 +79,7 @@
     context.shoppingCartSize = 0;
 }
 
-context.paymentCash   = delegator.findOne("PaymentMethodType", ["paymentMethodTypeId" : "CASH"], true);
-context.paymentCheck  = delegator.findOne("PaymentMethodType", ["paymentMethodTypeId" : "PERSONAL_CHECK"], true);
-context.paymentGift   = delegator.findOne("PaymentMethodType", ["paymentMethodTypeId" : "GIFT_CARD"], true);
-context.paymentCredit = delegator.findOne("PaymentMethodType", ["paymentMethodTypeId" : "CREDIT_CARD"], true);
\ No newline at end of file
+context.paymentCash   = from("PaymentMethodType").where("paymentMethodTypeId" : "CASH").cache(true).queryOne();
+context.paymentCheck  = from("PaymentMethodType").where("paymentMethodTypeId" : "PERSONAL_CHECK").cache(true).queryOne();
+context.paymentGift   = from("PaymentMethodType").where("paymentMethodTypeId" : "GIFT_CARD").cache(true).queryOne();
+context.paymentCredit = from("PaymentMethodType").where("paymentMethodTypeId" : "CREDIT_CARD").cache(true).queryOne();
\ No newline at end of file
diff --git a/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/catalog/Category.groovy b/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/catalog/Category.groovy
index dd71e2e..c22f2dc 100644
--- a/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/catalog/Category.groovy
+++ b/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/catalog/Category.groovy
@@ -36,7 +36,7 @@
     productCategoryId = request.getAttribute("topCategoryId");
 }
 
-category = delegator.findOne("ProductCategory", [productCategoryId : productCategoryId], true);
+category = from("ProductCategory").where("productCategoryId", productCategoryId).cache(true).queryOne();
 if (category) {
     if (category.detailScreen) {
         detailScreen = category.detailScreen;
diff --git a/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/customer/EditAddress.groovy b/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/customer/EditAddress.groovy
index e482693..03390db 100644
--- a/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/customer/EditAddress.groovy
+++ b/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/customer/EditAddress.groovy
@@ -17,14 +17,14 @@
  * under the License.
  */
 
-person = delegator.findOne("Person", [partyId : parameters.partyId], false);
+person = from("Person").where("partyId", parameters.partyId).queryOne();
 if (person) {
     request.setAttribute("lastName", person.lastName);
     request.setAttribute("firstName", person.firstName);
     request.setAttribute("partyId", parameters.partyId);
 }
 
-contactMech = delegator.findOne("ContactMech", [contactMechId : parameters.contactMechId], false);
+contactMech = from("ContactMech").where("contactMechId", parameters.contactMechId).queryOne();
 if (contactMech) {
     postalAddress = contactMech.getRelatedOne("PostalAddress", false);
     if (postalAddress) {
@@ -37,11 +37,11 @@
         request.setAttribute("postalCode", postalAddress.postalCode);
         request.setAttribute("stateProvinceGeoId", postalAddress.stateProvinceGeoId);
         request.setAttribute("countryGeoId", postalAddress.countryGeoId);
-        stateProvinceGeo = delegator.findOne("Geo", [geoId : postalAddress.stateProvinceGeoId], false);
+        stateProvinceGeo = from("Geo").where("geoId", postalAddress.stateProvinceGeoId).queryOne();
         if (stateProvinceGeo) {
             request.setAttribute("stateProvinceGeo", stateProvinceGeo.get("geoName", locale));
         }
-        countryProvinceGeo = delegator.findOne("Geo", [geoId : postalAddress.countryGeoId], false);
+        countryProvinceGeo = from("Geo").where("geoId", postalAddress.countryGeoId).queryOne();
         if (countryProvinceGeo) {
             request.setAttribute("countryProvinceGeo", countryProvinceGeo.get("geoName", locale));
         }
diff --git a/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/manager/PaidOutAndIn.groovy b/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/manager/PaidOutAndIn.groovy
index 3b5077d..aff0230 100644
--- a/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/manager/PaidOutAndIn.groovy
+++ b/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/manager/PaidOutAndIn.groovy
@@ -19,5 +19,5 @@
 
 import org.ofbiz.entity.condition.*;
 
-context.paidReasonIn  = delegator.findList("Enumeration", EntityCondition.makeCondition("enumTypeId", EntityOperator.EQUALS, "POS_PAID_REASON_IN") , null, ["sequenceId"], null, false);
-context.paidReasonOut = delegator.findList("Enumeration", EntityCondition.makeCondition("enumTypeId", EntityOperator.EQUALS, "POS_PAID_REASON_OUT"), null, ["sequenceId"], null, false);
+context.paidReasonIn  = from("Enumeration").where("enumTypeId", "POS_PAID_REASON_IN").orderBy("sequenceId").queryList();
+context.paidReasonOut = from("Enumeration").where("enumTypeId", "POS_PAID_REASON_OUT").orderBy("sequenceId").queryList();
diff --git a/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/search/CustomerAddress.groovy b/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/search/CustomerAddress.groovy
index 8f8929c..05f4a50 100644
--- a/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/search/CustomerAddress.groovy
+++ b/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/search/CustomerAddress.groovy
@@ -24,22 +24,22 @@
     shoppingCart = webPosSession.getCart();
     shipToCustomerPartyId = shoppingCart.getShipToCustomerPartyId();
     if (UtilValidate.isNotEmpty(shipToCustomerPartyId)) {
-        context.personShipTo = delegator.findOne("Person", [partyId : shipToCustomerPartyId], false);
+        context.personShipTo = from("Person").where("partyId", shipToCustomerPartyId).queryOne();
     }
     shippingContactMechId = shoppingCart.getContactMech("SHIPPING_LOCATION");
     if (UtilValidate.isNotEmpty(shippingContactMechId)) {
-        contactMech = delegator.findOne("ContactMech", [contactMechId : shippingContactMechId], false);
+        contactMech = from("ContactMech").where("contactMechId", shippingContactMechId).queryOne();
         if (UtilValidate.isNotEmpty(contactMech) && "POSTAL_ADDRESS".equals(contactMech.contactMechTypeId)) {
             context.shippingPostalAddress = contactMech.getRelatedOne("PostalAddress", false);
         }
     }
     billToCustomerPartyId = shoppingCart.getBillToCustomerPartyId();
     if (UtilValidate.isNotEmpty(billToCustomerPartyId)) {
-        context.personBillTo = delegator.findOne("Person", [partyId : billToCustomerPartyId], false);
+        context.personBillTo = from("Person").where("partyId", billToCustomerPartyId).queryOne();
     }
     billingContactMechId = shoppingCart.getContactMech("BILLING_LOCATION");
     if (UtilValidate.isNotEmpty(billingContactMechId)) {
-        contactMech = delegator.findOne("ContactMech", [contactMechId : billingContactMechId], false);
+        contactMech = from("ContactMech").where("contactMechId", billingContactMechId).queryOne();
         if (UtilValidate.isNotEmpty(contactMech) && "POSTAL_ADDRESS".equals(contactMech.contactMechTypeId)) {
             context.billingPostalAddress = contactMech.getRelatedOne("PostalAddress", false);
         }
diff --git a/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/search/SearchSalesReps.groovy b/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/search/SearchSalesReps.groovy
index baab82e..9e06304 100644
--- a/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/search/SearchSalesReps.groovy
+++ b/specialpurpose/webpos/webapp/webpos/WEB-INF/actions/search/SearchSalesReps.groovy
@@ -20,11 +20,7 @@
 import org.ofbiz.entity.condition.EntityCondition;
 import org.ofbiz.entity.condition.EntityOperator;
 
-List partyRoleCond = [];
-List orderBy = ["lastName", "firstName"];
-
-partyRoleCond.add(EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, "SALES_REP"));
-context.salesReps = delegator.findList("PartyRoleNameDetail", EntityCondition.makeCondition(partyRoleCond, EntityOperator.AND), null, orderBy, null, false);
+context.salesReps = from("PartyRoleNameDetail").where("roleTypeId", "SALES_REP").orderBy("lastName", "firstName").queryList();
 
 shoppingCart = session.getAttribute("shoppingCart");
 if (shoppingCart) {