Synched branch with trunk.


git-svn-id: https://svn.apache.org/repos/asf/ofbiz/branches/json-integration-refactoring@1635897 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/.classpath b/.classpath
index ed910ba..a98037f 100644
--- a/.classpath
+++ b/.classpath
@@ -29,6 +29,9 @@
     <classpathentry kind="lib" path="framework/base/lib/ical4j-1.0-rc2.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/icu4j-52_1.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/ivy-2.2.0.jar"/>
+    <classpathentry kind="lib" path="framework/base/lib/jackson-annotations-2.4.0.jar"/>
+    <classpathentry kind="lib" path="framework/base/lib/jackson-core-2.4.2.jar"/>
+    <classpathentry kind="lib" path="framework/base/lib/jackson-databind-2.4.2.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/javolution-5.4.3.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/jdbm-1.0-SNAPSHOT.jar"/>
     <classpathentry kind="lib" path="framework/base/lib/jdom-1.1.jar"/>
@@ -130,7 +133,6 @@
     <classpathentry kind="lib" path="framework/testtools/lib/org.springframework.core-3.1.0.M2.jar"/>
     <classpathentry kind="lib" path="framework/webapp/lib/ezmorph-0.9.1.jar"/>
     <classpathentry kind="lib" path="framework/webapp/lib/iText-2.1.7.jar"/>
-    <classpathentry kind="lib" path="framework/webapp/lib/json-lib-2.2.3-jdk15.jar"/>
     <classpathentry kind="lib" path="framework/webapp/lib/rome-0.9.jar"/>
     <classpathentry kind="lib" path="specialpurpose/googlecheckout/lib/checkout-sdk-0.8.8.jar"/>
     <classpathentry kind="lib" path="specialpurpose/ldap/lib/cas-server-core-3.3.jar"/>
@@ -157,7 +159,6 @@
     <classpathentry kind="src" path="applications/humanres/src"/>
     <classpathentry kind="src" path="applications/workeffort/src"/>
     <classpathentry kind="src" path="specialpurpose/appserver/src"/>
-    <classpathentry kind="src" path="framework/base/build/gen-src/javacc"/>
     <classpathentry excluding="org/ofbiz/base/config/CoberturaInstrumenter.java" kind="src" path="framework/base/src"/>
     <classpathentry kind="src" path="framework/bi/src"/>
     <classpathentry kind="src" path="specialpurpose/birt/src"/>
@@ -172,7 +173,6 @@
     <classpathentry kind="src" path="framework/security/src"/>
     <classpathentry kind="src" path="framework/service/src"/>
     <classpathentry kind="src" path="framework/sql/src"/>
-    <classpathentry kind="src" path="framework/sql/build/gen-src/javacc"/>
     <classpathentry kind="src" path="framework/start/src"/>
     <classpathentry kind="src" path="framework/testtools/src"/>
     <classpathentry excluding="org/ofbiz/webapp/view/JasperReportsPdfViewHandler.java|org/ofbiz/webapp/view/JasperReportsXmlViewHandler.java|org/ofbiz/webapp/view/JasperReportsJXlsViewHandler.java|org/ofbiz/webapp/view/JasperReportsPoiXlsViewHandler.java" kind="src" path="framework/webapp/src"/>
diff --git a/LICENSE b/LICENSE
index 3f55782..58ad29f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -23,6 +23,9 @@
 framework/base/lib/httpclient-cache-4.2.1.jar
 framework/base/lib/httpcore-4.2.1.jar
 framework/base/lib/ivy-2.2.0.jar
+framework/base/lib/jackson-annotations-2.4.0.jar
+framework/base/lib/jackson-core-2.4.2.jar
+framework/base/lib/jackson-databind-2.4.2.jar
 framework/base/lib/jakarta-regexp-1.5.jar
 framework/base/lib/jpim-0.1.jar
 framework/base/lib/juel-impl-2.2.7.jar
@@ -92,7 +95,6 @@
 framework/service/lib/XmlSchema-1.4.3.jar
 framework/webapp/lib/fop-1.1.jar
 framework/webapp/lib/xmlgraphics-commons-1.5.jar
-framework/webapp/lib/json-lib-2.2.3-jdk15.jar
 framework/webapp/lib/ezmorph-0.9.1.jar
 framework/webapp/lib/rome-0.9.jar
 framework/webapp/lib/serializer-2.7.0.jar
@@ -439,7 +441,6 @@
 framework/base/lib/hamcrest-all-1.2.jar
 framework/base/lib/httpunit-1.7.jar
 framework/base/lib/ical4j-1.0-rc2.jar
-lib/build/javacc/javacc.jar (5.0)
 framework/base/lib/javolution-5.4.3.jar
 framework/base/lib/xpp3-1.1.4c.jar
 framework/base/lib/xstream-1.4.6.jar
diff --git a/NOTICE b/NOTICE
index 565c28a..95d0ebb 100644
--- a/NOTICE
+++ b/NOTICE
@@ -253,12 +253,6 @@
 Java PIM Library (jpim)
 Copyright (c) 2001-2003 jpim development team.
 =========================================================================
-==  JavaCC Notice                                                      ==
-=========================================================================
-
-This product includes software developed by the javacc team
-(http://javacc.dev.java.net/).  The included version is 4.1.
-=========================================================================
 ==  XPP3   Notice                                                      ==
 =========================================================================
 
diff --git a/applications/humanres/src/org/ofbiz/humanres/HumanResEvents.java b/applications/humanres/src/org/ofbiz/humanres/HumanResEvents.java
index 0740f57..ae06790 100644
--- a/applications/humanres/src/org/ofbiz/humanres/HumanResEvents.java
+++ b/applications/humanres/src/org/ofbiz/humanres/HumanResEvents.java
@@ -18,18 +18,14 @@
  *******************************************************************************/
 package org.ofbiz.humanres;
 
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import javolution.util.FastList;
 import javolution.util.FastMap;
-import net.sf.json.JSONObject;
 
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilValidate;
@@ -46,7 +42,7 @@
     
     // Please note : the structure of map in this function is according to the JSON data map of the jsTree
     @SuppressWarnings("unchecked")
-    public static void getChildHRCategoryTree(HttpServletRequest request, HttpServletResponse response){
+    public static String getChildHRCategoryTree(HttpServletRequest request, HttpServletResponse response){
         Delegator delegator = (Delegator) request.getAttribute("delegator");
         String partyId = request.getParameter("partyId");
         String onclickFunction = request.getParameter("onclickFunction");
@@ -54,7 +50,7 @@
         String hrefString = request.getParameter("hrefString");
         String hrefString2 = request.getParameter("hrefString2");
         
-        List categoryList = FastList.newInstance();
+        List categoryList = new ArrayList();
         List<GenericValue> childOfComs;
         //check employee position
         try {
@@ -107,11 +103,11 @@
                         
                         categoryList.add(josonMap);
                     }
-                    toJsonObjectList(categoryList,response);
                 }
             }
         } catch (Exception e) {
             e.printStackTrace();
+            return "error";
         }
         
         try {
@@ -235,41 +231,12 @@
                         categoryList.add(emplMap);
                     }
                 }
-                
-                toJsonObjectList(categoryList,response);
             }
         } catch (Exception e) {
             e.printStackTrace();
+            return "error";
         }
-    }
-    
-    @SuppressWarnings("unchecked")
-    public static void toJsonObjectList(List attrList, HttpServletResponse response){
-        String jsonStr = "[";
-        for (Object attrMap : attrList) {
-            JSONObject json = JSONObject.fromObject(attrMap);
-            jsonStr = jsonStr + json.toString() + ',';
-        }
-        jsonStr = jsonStr + "{ } ]";
-        if (UtilValidate.isEmpty(jsonStr)) {
-            Debug.logError("JSON Object was empty; fatal error!",module);
-        }
-        // set the X-JSON content type
-        response.setContentType("application/json");
-        // jsonStr.length is not reliable for unicode characters
-        try {
-            response.setContentLength(jsonStr.getBytes("UTF8").length);
-        } catch (UnsupportedEncodingException e) {
-            Debug.logError("Problems with Json encoding",module);
-        }
-        // return the JSON String
-        Writer out;
-        try {
-            out = response.getWriter();
-            out.write(jsonStr);
-            out.flush();
-        } catch (IOException e) {
-            Debug.logError("Unable to get response writer",module);
-        }
+        request.setAttribute("hrTree", categoryList);
+        return "success";
     }
 }
diff --git a/applications/humanres/webapp/humanres/WEB-INF/controller.xml b/applications/humanres/webapp/humanres/WEB-INF/controller.xml
index ff6c8a7..6c900f5 100644
--- a/applications/humanres/webapp/humanres/WEB-INF/controller.xml
+++ b/applications/humanres/webapp/humanres/WEB-INF/controller.xml
@@ -1051,7 +1051,8 @@
     <request-map uri="getHRChild">
         <security auth="false" https="true"/>
         <event type="java" path="org.ofbiz.humanres.HumanResEvents" invoke="getChildHRCategoryTree"/>
-        <response name="success" type="none"/>
+        <response name="success" type="request" value="json"/>
+        <response name="error" type="request" value="json"/>
     </request-map>
     <request-map uri="createInternalOrg">
         <security https="true" auth="true"/>
diff --git a/applications/humanres/webapp/humanres/humanres/category/CategoryTree.ftl b/applications/humanres/webapp/humanres/humanres/category/CategoryTree.ftl
index 38751b3..62a8ce4 100644
--- a/applications/humanres/webapp/humanres/humanres/category/CategoryTree.ftl
+++ b/applications/humanres/webapp/humanres/humanres/category/CategoryTree.ftl
@@ -69,7 +69,10 @@
                                 "hrefString" : "viewprofile?partyId=" ,
                                 "onclickFunction" : "callDocument"
                         }; 
-                    }
+                    },
+                              success : function(data) {
+                                  return data.hrTree;
+                              }
                 }
             },
             "types" : {
diff --git a/applications/product/src/org/ofbiz/product/category/CategoryServices.java b/applications/product/src/org/ofbiz/product/category/CategoryServices.java
index c0c3d18..90cb1c8 100644
--- a/applications/product/src/org/ofbiz/product/category/CategoryServices.java
+++ b/applications/product/src/org/ofbiz/product/category/CategoryServices.java
@@ -18,9 +18,6 @@
  *******************************************************************************/
 package org.ofbiz.product.category;
 
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
 import java.sql.Timestamp;
 import java.util.List;
 import java.util.Locale;
@@ -31,7 +28,6 @@
 
 import javolution.util.FastList;
 import javolution.util.FastMap;
-import net.sf.json.JSONObject;
 
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.GeneralException;
@@ -434,7 +430,7 @@
 
     // Please note : the structure of map in this function is according to the JSON data map of the jsTree
     @SuppressWarnings("unchecked")
-    public static void getChildCategoryTree(HttpServletRequest request, HttpServletResponse response){
+    public static String getChildCategoryTree(HttpServletRequest request, HttpServletResponse response){
         Delegator delegator = (Delegator) request.getAttribute("delegator");
         String productCategoryId = request.getParameter("productCategoryId");
         String isCatalog = request.getParameter("isCatalog");
@@ -528,42 +524,13 @@
                         categoryList.add(josonMap);
                     }
                     List<Map<Object, Object>> sortedCategoryList = UtilMisc.sortMaps(categoryList, sortList);
-                    toJsonObjectList(sortedCategoryList,response);
+                    request.setAttribute("treeData", sortedCategoryList);
                 }
             }
         } catch (GenericEntityException e) {
             e.printStackTrace();
+            return "error";
         }
-    }
-
-    public static void toJsonObjectList(List attrList, HttpServletResponse response){
-        StringBuilder jsonBuilder = new StringBuilder("[");
-        for (Object attrMap : attrList) {
-            JSONObject json = JSONObject.fromObject(attrMap);
-            jsonBuilder.append(json.toString());
-            jsonBuilder.append(',');
-        }
-        jsonBuilder.append("{ } ]");
-        String jsonStr = jsonBuilder.toString();
-        if (UtilValidate.isEmpty(jsonStr)) {
-            Debug.logError("JSON Object was empty; fatal error!",module);
-        }
-        // set the X-JSON content type
-        response.setContentType("application/json");
-        // jsonStr.length is not reliable for unicode characters
-        try {
-            response.setContentLength(jsonStr.getBytes("UTF8").length);
-        } catch (UnsupportedEncodingException e) {
-            Debug.logError("Problems with Json encoding",module);
-        }
-        // return the JSON String
-        Writer out;
-        try {
-            out = response.getWriter();
-            out.write(jsonStr);
-            out.flush();
-        } catch (IOException e) {
-            Debug.logError("Unable to get response writer",module);
-        }
+        return "success";
     }
 }
diff --git a/applications/product/src/org/ofbiz/product/imagemanagement/ImageManagementServices.java b/applications/product/src/org/ofbiz/product/imagemanagement/ImageManagementServices.java
index e1fb15a..586b29b 100644
--- a/applications/product/src/org/ofbiz/product/imagemanagement/ImageManagementServices.java
+++ b/applications/product/src/org/ofbiz/product/imagemanagement/ImageManagementServices.java
@@ -26,30 +26,17 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.RandomAccessFile;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
 import javax.imageio.ImageIO;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
 
 import javolution.util.FastList;
 import javolution.util.FastMap;
-import net.sf.json.JSONObject;
-
-import org.apache.commons.fileupload.FileItem;
-import org.apache.commons.fileupload.FileUploadException;
-import org.apache.commons.fileupload.disk.DiskFileItemFactory;
-import org.apache.commons.fileupload.servlet.ServletFileUpload;
 import org.jdom.JDOMException;
 import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.FileUtil;
 import org.ofbiz.base.util.UtilDateTime;
 import org.ofbiz.base.util.UtilGenerics;
 import org.ofbiz.base.util.UtilMisc;
@@ -66,8 +53,6 @@
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.LocalDispatcher;
 import org.ofbiz.service.ServiceUtil;
-import org.ofbiz.webapp.event.EventHandlerException;
-
 
 /**
  * Product Services
@@ -76,7 +61,6 @@
     
     public static final String module = ImageManagementServices.class.getName();
     public static final String resource = "ProductErrorUiLabels";
-    private static List<Map<String,Object>> josonMap = null;
     private static int imageCount = 0;
     private static String imagePath;
     
@@ -649,131 +633,7 @@
         result.put("scaleFactor", scaleFactor);
         return result;
     }
-    
-    public static String multipleUploadImage(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {
-        HttpSession session = request.getSession(true);
-        GenericValue userLogin = (GenericValue) session.getAttribute("userLogin");
-        LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
-        
-        Map<String, String> formInput = FastMap.newInstance();
-        ServletFileUpload fu = new ServletFileUpload(new DiskFileItemFactory(10240, FileUtil.getFile("runtime/tmp")));
-        List<FileItem> lst = null;
-        try {
-           lst = UtilGenerics.checkList(fu.parseRequest(request));
-        } catch (FileUploadException e4) {
-            return e4.getMessage();
-        }
-                
-        FileItem fi = null;
-        FileItem imageFi = null;
-        byte[] imageBytes = {};
-        for (int i=0; i < lst.size(); i++) {
-            fi = lst.get(i);
-            String fieldName = fi.getFieldName();
-            if (fi.isFormField()) {
-                String fieldStr = fi.getString();
-                formInput.put(fieldName, fieldStr);
-            } else if (fieldName.startsWith("imageData")) {
-                Map<String, Object> passedParams = FastMap.newInstance();
-                Map<String, Object> contentLength = FastMap.newInstance();
-                if(josonMap == null){
-                     josonMap = FastList.newInstance();
-                }
-                imageFi = fi;
-                String fileName = fi.getName();
-                String contentType = fi.getContentType();
-                imageBytes = imageFi.get();
-                ByteBuffer byteWrap = ByteBuffer.wrap(imageBytes);
-                passedParams.put("userLogin", userLogin);
-                passedParams.put("productId", formInput.get("productId"));
-                passedParams.put("productContentTypeId", "IMAGE");
-                passedParams.put("_uploadedFile_fileName", fileName);
-                passedParams.put("_uploadedFile_contentType", contentType);
-                passedParams.put("uploadedFile", byteWrap);
-                passedParams.put("imageResize", formInput.get("imageResize"));
-                contentLength.put("imageSize", imageFi.getSize());
-                josonMap.add(contentLength);
-                
-                if (passedParams.get("productId") != null) {
-                    try {
-                        dispatcher.runSync("addMultipleuploadForProduct", passedParams);
-                    } catch (GenericServiceException e) {
-                        Debug.logError(e, module);
-                        return e.getMessage();
-                    }
-                }
-                
-            }
-        }
-        return "success";
-    }
-    
-    public static String progressUploadImage(HttpServletRequest request, HttpServletResponse response) throws EventHandlerException{
-        toJsonObjectList(josonMap,response);
-        josonMap.clear();
-        return "success";
-    }
-    
-    public static void toJsonObject(Map<String,Object> attrMap, HttpServletResponse response){
-        JSONObject json = JSONObject.fromObject(attrMap);
-        String jsonStr = json.toString();
-        if (jsonStr == null) {
-            Debug.logError("JSON Object was empty; fatal error!",module);
-        }
-        // set the X-JSON content type
-        response.setContentType("application/json");
-        // jsonStr.length is not reliable for unicode characters
-        try {
-            response.setContentLength(jsonStr.getBytes("UTF8").length);
-        } catch (UnsupportedEncodingException e) {
-            Debug.logError("Problems with Json encoding",module);
-        }
-        // return the JSON String
-        Writer out;
-        try {
-            out = response.getWriter();
-            out.write(jsonStr);
-            out.flush();
-        } catch (IOException e) {
-            Debug.logError("Unable to get response writer",module);
-        }
-    }
-    
-    public static void toJsonObjectList(List<Map<String,Object>> list, HttpServletResponse response) throws EventHandlerException {
-        JSONObject json = null;
-        List<JSONObject> jsonList = new ArrayList<JSONObject>();
-        if (list != null) {
-            for (Map<String,Object> val : list) {
-                json = new JSONObject();
-                for (String rowKey: val.keySet()) {
-                    json.put(rowKey, val.get(rowKey));
-                }
-                jsonList.add(json);
-            }
-            String jsonStr = jsonList.toString();
-            if (jsonStr == null) {
-                throw new EventHandlerException("JSON Object was empty; fatal error!");
-            }
-            // set the X-JSON content type
-            response.setContentType("application/json");
-            // jsonStr.length is not reliable for unicode characters
-            try {
-                response.setContentLength(jsonStr.getBytes("UTF8").length);
-            } catch (UnsupportedEncodingException e) {
-                throw new EventHandlerException("Problems with Json encoding", e);
-            }
-            // return the JSON String
-            Writer out;
-            try {
-                out = response.getWriter();
-                out.write(jsonStr);
-                out.flush();
-            } catch (IOException e) {
-                throw new EventHandlerException("Unable to get response writer", e);
-            } 
-        }
-    }
-    
+
     public static File checkExistsImage(File file) {
         if (!file.exists()) {
             imageCount = 0;
diff --git a/applications/product/src/org/ofbiz/product/store/ProductStoreEvents.java b/applications/product/src/org/ofbiz/product/store/ProductStoreEvents.java
index 3acb8b6..7ccdd97 100644
--- a/applications/product/src/org/ofbiz/product/store/ProductStoreEvents.java
+++ b/applications/product/src/org/ofbiz/product/store/ProductStoreEvents.java
@@ -18,9 +18,6 @@
  *******************************************************************************/
 package org.ofbiz.product.store;
 
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
 import java.util.List;
 import java.util.Map;
 
@@ -30,9 +27,6 @@
 import javolution.util.FastList;
 import javolution.util.FastMap;
 
-import net.sf.json.JSONObject;
-
-import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilMisc;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.entity.Delegator;
@@ -47,7 +41,7 @@
 
     // Please note : the structure of map in this function is according to the JSON data map of the jsTree
     @SuppressWarnings("unchecked")
-    public static void getChildProductStoreGroupTree(HttpServletRequest request, HttpServletResponse response){
+    public static String getChildProductStoreGroupTree(HttpServletRequest request, HttpServletResponse response){
         Delegator delegator = (Delegator) request.getAttribute("delegator");
         String parentGroupId = request.getParameter("parentGroupId");
         String onclickFunction = request.getParameter("onclickFunction");
@@ -92,41 +86,13 @@
                         productStoreGroupList.add(josonMap);
                     }
                     List<Map<Object, Object>> sortedProductStoreGroupList = UtilMisc.sortMaps(productStoreGroupList, sortList);
-                    toJsonObjectList(sortedProductStoreGroupList,response);
+                    request.setAttribute("storeGroupTree", sortedProductStoreGroupList);
                 }
             }
         } catch (GenericEntityException e) {
             e.printStackTrace();
+            return "error";
         }
-    }
-
-    @SuppressWarnings("unchecked")
-    public static void toJsonObjectList(List attrList, HttpServletResponse response){
-        String jsonStr = "[";
-        for (Object attrMap : attrList) {
-            JSONObject json = JSONObject.fromObject(attrMap);
-            jsonStr = jsonStr + json.toString() + ',';
-        }
-        jsonStr = jsonStr + "{ } ]";
-        if (UtilValidate.isEmpty(jsonStr)) {
-            Debug.logError("JSON Object was empty; fatal error!",module);
-        }
-        // set the X-JSON content type
-        response.setContentType("application/json");
-        // jsonStr.length is not reliable for unicode characters
-        try {
-            response.setContentLength(jsonStr.getBytes("UTF8").length);
-        } catch (UnsupportedEncodingException e) {
-            Debug.logError("Problems with Json encoding",module);
-        }
-        // return the JSON String
-        Writer out;
-        try {
-            out = response.getWriter();
-            out.write(jsonStr);
-            out.flush();
-        } catch (IOException e) {
-            Debug.logError("Unable to get response writer",module);
-        }
+        return "success";
     }
 }
diff --git a/applications/product/webapp/catalog/WEB-INF/controller.xml b/applications/product/webapp/catalog/WEB-INF/controller.xml
index 7b1a9af..767cfb4 100644
--- a/applications/product/webapp/catalog/WEB-INF/controller.xml
+++ b/applications/product/webapp/catalog/WEB-INF/controller.xml
@@ -1457,7 +1457,8 @@
     <request-map uri="getProductStoreGroupRollupHierarchy">
         <security auth="false" https="true"/>
         <event type="java" path="org.ofbiz.product.store.ProductStoreEvents" invoke="getChildProductStoreGroupTree"/>
-        <response name="success" type="none"/>
+        <response name="success" type="request" value="json"/>
+        <response name="error" type="request" value="json"/>
     </request-map>
     <request-map uri="AddProductStoreToGroup">
         <security auth="true" https="true"/>
@@ -2900,17 +2901,6 @@
         <response name="success" type="view" value="viewPreviewImage"/>
         <response name="error" type="view" value="viewPreviewImage"/>
     </request-map>
-    <request-map uri="multipleUploadImage">
-        <security https="true" auth="true"/>
-        <event type="java" path="org.ofbiz.product.imagemanagement.ImageManagementServices" invoke="multipleUploadImage"/>
-        <response name="success" type="view" value="ImageUpload"/>
-        <response name="error" type="view" value="ImageUpload"/>
-    </request-map>
-    <request-map uri="progressUploadImage">
-        <security https="true" auth="true"/>
-        <event type="java" path="org.ofbiz.virtualvillage.imagemanagement.ImageManagementServices" invoke="progressUploadImage"/>
-        <response name="success" type="view" value="main"/>
-    </request-map>
     <request-map uri="chooseFrameImage">
         <security https="true" auth="true"/>
         <event type="java" path="org.ofbiz.product.imagemanagement.FrameImage" invoke="chooseFrameImage"/>
@@ -3022,7 +3012,8 @@
     <request-map uri="getChild">
         <security auth="false" https="true"/>
         <event type="java" path="org.ofbiz.product.category.CategoryServices" invoke="getChildCategoryTree"/>
-        <response name="success" type="none"/>
+        <response name="success" type="request" value="json"/>
+        <response name="error" type="request" value="json"/>
     </request-map>
     <request-map uri="listMiniproduct">
         <security auth="false" https="true"/>
diff --git a/applications/product/webapp/catalog/category/CategoryTree.ftl b/applications/product/webapp/catalog/category/CategoryTree.ftl
index a075216..7b14c8c 100644
--- a/applications/product/webapp/catalog/category/CategoryTree.ftl
+++ b/applications/product/webapp/catalog/category/CategoryTree.ftl
@@ -62,20 +62,24 @@
             $.cookie('jstree_select', "<#if productCategoryId??>${productCategoryId}<#elseif prodCatalogId??>${prodCatalogId}<#elseif showProductCategoryId??>${showProductCategoryId}</#if>");
         </#if>
         jQuery("#tree").jstree({
-        "plugins" : [ "themes", "json_data","ui" ,"cookies", "types"],
+            "plugins" : [ "themes", "json_data","ui" ,"cookies", "types"],
             "json_data" : {
                 "data" : rawdata,
-                          "ajax" : { "url" : "<@ofbizUrl>getChild</@ofbizUrl>", "type" : "POST",
-                          "data" : function (n) {
-                            return { 
-                                "isCategoryType" :  n.attr ? n.attr("isCatalog").replace("node_","") : 1 ,
-                                "isCatalog" :  n.attr ? n.attr("isCatalog").replace("node_","") : 1 ,
-                                "productCategoryId" : n.attr ? n.attr("id").replace("node_","") : 1 ,
-                                "additionParam" : "','category" ,
-                                "hrefString" : "EditCategory?productCategoryId=" ,
-                                "onclickFunction" : "callDocument"
-                        }; 
-                    }
+                "ajax" : { "url" : "<@ofbizUrl>getChild</@ofbizUrl>",
+                           "type" : "POST",
+                           "data" : function (n) {
+                                        return {
+                                            "isCategoryType" :  n.attr ? n.attr("isCatalog").replace("node_","") : 1 ,
+                                            "isCatalog" :  n.attr ? n.attr("isCatalog").replace("node_","") : 1 ,
+                                            "productCategoryId" : n.attr ? n.attr("id").replace("node_","") : 1 ,
+                                            "additionParam" : "','category" ,
+                                            "hrefString" : "EditCategory?productCategoryId=" ,
+                                            "onclickFunction" : "callDocument"
+                                        };
+                                    },
+                           success : function(data) {
+                               return data.treeData;
+                           }
                 }
             },
             "types" : {
diff --git a/applications/product/webapp/catalog/store/ProductStoreGroupTree.ftl b/applications/product/webapp/catalog/store/ProductStoreGroupTree.ftl
index b9aaa6c..e416c1c 100644
--- a/applications/product/webapp/catalog/store/ProductStoreGroupTree.ftl
+++ b/applications/product/webapp/catalog/store/ProductStoreGroupTree.ftl
@@ -49,17 +49,21 @@
         "plugins" : [ "themes", "json_data","ui" ,"cookies", "types"],
             "json_data" : {
                 "data" : rawdata,
-                          "ajax" : { "url" : "<@ofbizUrl>getProductStoreGroupRollupHierarchy</@ofbizUrl>", "type" : "POST",
-                          "data" : function (n) {
-                            return { 
-                                "parentGroupId" :  n.attr ? n.attr("parentGroupId").replace("node_","") : 1,
-                                "onclickFunction" : "callDocument"
-                        }; 
-                    }
+                "ajax" : { "url" : "<@ofbizUrl>getProductStoreGroupRollupHierarchy</@ofbizUrl>",
+                           "type" : "POST",
+                           "data" : function (n) {
+                               return {
+                                   "parentGroupId" :  n.attr ? n.attr("parentGroupId").replace("node_","") : 1,
+                                   "onclickFunction" : "callDocument"
+                               };
+                           },
+                           success : function (data) {
+                               return data.storeGroupTree;
+                           }
                 }
             },
             "types" : {
-             "valid_children" : [ "root" ]
+                "valid_children" : [ "root" ]
             }
         });
     });
diff --git a/framework/base/ant-scripts/ofbiz-jjtree.groovy b/framework/base/ant-scripts/ofbiz-jjtree.groovy
deleted file mode 100644
index f3abbfd..0000000
--- a/framework/base/ant-scripts/ofbiz-jjtree.groovy
+++ /dev/null
@@ -1,92 +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.
-*/
-
-import org.apache.tools.ant.BuildException
-
-def resolveFile = { name, base ->
-    return project.resolveFile(project.replaceProperties(name), base)
-}
-
-def getAttribute = { name, defaultValue ->
-    def value = attributes[name]
-    if (value == null) {
-        if (!defaultValue) throw new BuildException("No default for attribute($name)")
-        value = defaultValue
-    }
-    return value
-}
-
-def uptodate = { left, right ->
-    def uptodateTask = project.createTask('uptodate')
-    uptodateTask.srcfile = left
-    uptodateTask.targetFile = right
-    return uptodateTask.eval()
-}
-
-def basedir = project.baseDir
-def ant = new AntBuilder(self)
-def javacchome = resolveFile('${ofbiz.home.dir}/framework/base/lib/javacc', basedir)
-def src = getAttribute('src', 'src')
-def dir = getAttribute('dir', basedir)
-def file = getAttribute('file', basedir)
-def srcfile = resolveFile("$src/$dir/${file}.jjt", basedir)
-def srcpaths = [
-    jjtree:     resolveFile(getAttribute('gendir', '${build.dir}/gen-src') + '/jjtree/', basedir),
-    javacc:     resolveFile(getAttribute('gendir', '${build.dir}/gen-src') + '/javacc/', basedir),
-]
-def dirs = [
-    jjtree:     resolveFile(dir, srcpaths.jjtree),
-    javacc:     resolveFile(dir, srcpaths.javacc),
-]
-def gen = [
-    jjfile:     new File(dirs.jjtree, project.replaceProperties("${file}.jj")),
-    javafile:   new File(dirs.javacc, project.replaceProperties("${file}.java")),
-]
-def srcpath = project.getReference('src-path')
-def foundpath = [
-    jjtree:     false,
-    javacc:     false,
-]
-srcpath.each {
-    foundpath.jjtree |= it.file == srcpaths.jjtree
-    foundpath.javacc |= it.file == srcpaths.javacc
-}
-if (!foundpath.jjtree) srcpath.append(ant.path{pathelement(location: srcpaths.jjtree)})
-if (!foundpath.javacc) srcpath.append(ant.path{pathelement(location: srcpaths.javacc)})
-
-if (!uptodate(srcfile, gen.jjfile)) {
-    ant.delete(dir:dirs.jjtree)
-    ant.mkdir(dir:dirs.jjtree)
-    ant.jjtree(
-        target:             srcfile,
-        javacchome:         javacchome,
-        outputdirectory:    dirs.jjtree,
-    )
-}
-if (!uptodate(gen.jjfile, gen.javafile)) {
-    ant.delete(dir:dirs.javacc)
-    ant.mkdir(dir:dirs.javacc)
-
-    ant.javacc(
-        target:             gen.jjfile,
-        javacchome:         javacchome,
-        outputdirectory:    dirs.javacc,
-    )
-    ant.delete(dir:resolveFile('${build.classes}/' + dir, basedir))
-}
diff --git a/framework/base/build.xml b/framework/base/build.xml
index 3518724..a4ec0cc 100644
--- a/framework/base/build.xml
+++ b/framework/base/build.xml
@@ -51,6 +51,7 @@
         <file name="org/ofbiz/base/conversion/test/TestBooleanConverters.java"/>
         <file name="org/ofbiz/base/conversion/test/DateTimeTests.java"/>
         <file name="org/ofbiz/base/conversion/test/MiscTests.java"/>
+        <file name="org/ofbiz/base/conversion/test/TestJSONConverters.java"/>
         <file name="org/ofbiz/base/util/test/UtilIOTests.java"/>
         <file name="org/ofbiz/base/test/BaseUnitTests.java"/>
         <file name="org/ofbiz/base/util/collections/test/GenericMapTest.java"/>
@@ -80,20 +81,6 @@
         </patternset>
     </target>
 
-    <target name="gen-src">
-        <ofbiz-javacc dir="org/ofbiz/base/json" file="JSON"/>
-    </target>
-
-    <target name="classes" depends="prepare,gen-src">
-        <javac17>
-            <sourcepath>
-                <dirset dir="build/gen-src">
-                    <include name="javacc"/>
-                </dirset>
-            </sourcepath>
-        </javac17>
-    </target>
-
     <target name="jar" depends="classes">
         <main-jar>
             <main-elements>
diff --git a/framework/base/lib/jackson-annotations-2.4.0.jar b/framework/base/lib/jackson-annotations-2.4.0.jar
new file mode 100644
index 0000000..0b55559
--- /dev/null
+++ b/framework/base/lib/jackson-annotations-2.4.0.jar
Binary files differ
diff --git a/framework/base/lib/jackson-core-2.4.2.jar b/framework/base/lib/jackson-core-2.4.2.jar
new file mode 100644
index 0000000..fad6f9b
--- /dev/null
+++ b/framework/base/lib/jackson-core-2.4.2.jar
Binary files differ
diff --git a/framework/base/lib/jackson-databind-2.4.2.jar b/framework/base/lib/jackson-databind-2.4.2.jar
new file mode 100644
index 0000000..ea95c53
--- /dev/null
+++ b/framework/base/lib/jackson-databind-2.4.2.jar
Binary files differ
diff --git a/framework/base/src/org/ofbiz/base/conversion/JSONConverters.java b/framework/base/src/org/ofbiz/base/conversion/JSONConverters.java
index dc4983c..28cebc0 100644
--- a/framework/base/src/org/ofbiz/base/conversion/JSONConverters.java
+++ b/framework/base/src/org/ofbiz/base/conversion/JSONConverters.java
@@ -18,124 +18,15 @@
  *******************************************************************************/
 package org.ofbiz.base.conversion;
 
-import java.util.Collection;
+import java.io.IOException;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
-import javolution.util.FastSet;
-
-import org.ofbiz.base.json.JSON;
+import org.ofbiz.base.lang.JSON;
 import org.ofbiz.base.util.UtilGenerics;
 
 /** JSON Converter classes. */
 public class JSONConverters implements ConverterLoader {
-    public static class ObjectToJSONResultCreator<R extends JSONResult> implements ConverterCreator, ConverterLoader {
-        public void loadConverters() {
-            Converters.registerCreator(this);
-        }
-
-        public <S, T> Converter<S, T> createConverter(Class<S> sourceClass, Class<T> targetClass) {
-            if (!JSONResult.class.isAssignableFrom(targetClass)) {
-                return null;
-            }
-            if (Collection.class.isAssignableFrom(sourceClass)) {
-            } else if (Map.class.isAssignableFrom(sourceClass)) {
-            } else if (Byte.class == sourceClass) {
-            } else if (Character.class == sourceClass) {
-            } else if (Double.class == sourceClass) {
-            } else if (Float.class == sourceClass) {
-            } else if (Integer.class == sourceClass) {
-            } else if (Long.class == sourceClass) {
-            } else if (Short.class == sourceClass) {
-            } else {
-                return null;
-            }
-            return UtilGenerics.cast(new ObjectToJSONWriterResult<S, JSONResult>(sourceClass, UtilGenerics.<Class<JSONResult>>cast(targetClass)));
-        }
-    }
-
-    private static class ObjectToJSONWriterResult<S, T extends JSONResult> extends AbstractConverter<S, T> {
-        public ObjectToJSONWriterResult(Class<S> sourceClass, Class<T> targetClass) {
-            super(sourceClass, targetClass);
-        }
-
-        public T convert(S obj) throws ConversionException {
-            try {
-                T result = UtilGenerics.<T>cast(getTargetClass().newInstance());
-                result.getWriter().write(obj);
-                return result;
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new ConversionException(e);
-            }
-        }
-    }
-
-    public static class JSONToByte extends AbstractConverter<JSON, Byte> {
-        public JSONToByte() {
-            super(JSON.class, Byte.class);
-        }
-
-        public Byte convert(JSON obj) throws ConversionException {
-            try {
-                return obj.JSONLong().byteValue();
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new ConversionException(e);
-            }
-        }
-    }
-
-    public static class JSONToDouble extends AbstractConverter<JSON, Double> {
-        public JSONToDouble() {
-            super(JSON.class, Double.class);
-        }
-
-        public Double convert(JSON obj) throws ConversionException {
-            try {
-                return obj.JSONFloat();
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new ConversionException(e);
-            }
-        }
-    }
-
-    public static class JSONToFloat extends AbstractConverter<JSON, Float> {
-        public JSONToFloat() {
-            super(JSON.class, Float.class);
-        }
-
-        public Float convert(JSON obj) throws ConversionException {
-            try {
-                return obj.JSONFloat().floatValue();
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new ConversionException(e);
-            }
-        }
-    }
-
-    public static class JSONToInteger extends AbstractConverter<JSON, Integer> {
-        public JSONToInteger() {
-            super(JSON.class, Integer.class);
-        }
-
-        public Integer convert(JSON obj) throws ConversionException {
-            try {
-                return obj.JSONLong().intValue();
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new ConversionException(e);
-            }
-        }
-    }
 
     public static class JSONToList extends AbstractConverter<JSON, List<Object>> {
         public JSONToList() {
@@ -144,26 +35,8 @@
 
         public List<Object> convert(JSON obj) throws ConversionException {
             try {
-                return obj.JSONArray();
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
-                throw new ConversionException(e);
-            }
-        }
-    }
-
-    public static class JSONToLong extends AbstractConverter<JSON, Long> {
-        public JSONToLong() {
-            super(JSON.class, Long.class);
-        }
-
-        public Long convert(JSON obj) throws ConversionException {
-            try {
-                return obj.JSONLong();
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
+                return UtilGenerics.<List<Object>>cast(obj.toObject(List.class));
+            } catch (IOException e) {
                 throw new ConversionException(e);
             }
         }
@@ -176,44 +49,36 @@
 
         public Map<String, Object> convert(JSON obj) throws ConversionException {
             try {
-                return obj.JSONObject();
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
+                return UtilGenerics.<Map<String, Object>>cast(obj.toObject(Map.class));
+            } catch (IOException e) {
                 throw new ConversionException(e);
             }
         }
     }
 
-    public static class JSONToShort extends AbstractConverter<JSON, Short> {
-        public JSONToShort() {
-            super(JSON.class, Short.class);
+    public static class ListToJSON extends AbstractConverter<List<Object>, JSON> {
+        public ListToJSON() {
+            super(List.class, JSON.class);
         }
 
-        public Short convert(JSON obj) throws ConversionException {
+        public JSON convert(List<Object> obj) throws ConversionException {
             try {
-                return obj.JSONLong().shortValue();
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
+                return JSON.from(obj);
+            } catch (IOException e) {
                 throw new ConversionException(e);
             }
         }
     }
 
-    public static class JSONToSet extends AbstractConverter<JSON, Set<Object>> {
-        public JSONToSet() {
-            super(JSON.class, Set.class);
+    public static class MapToJSON extends AbstractConverter<Map<String, Object>, JSON> {
+        public MapToJSON() {
+            super(Map.class, JSON.class);
         }
 
-        public Set<Object> convert(JSON obj) throws ConversionException {
+        public JSON convert(Map<String, Object> obj) throws ConversionException {
             try {
-                Set<Object> set = FastSet.newInstance();
-                set.addAll(obj.JSONArray());
-                return set;
-            } catch (RuntimeException e) {
-                throw e;
-            } catch (Exception e) {
+                return JSON.from(obj);
+            } catch (IOException e) {
                 throw new ConversionException(e);
             }
         }
diff --git a/framework/base/src/org/ofbiz/base/conversion/JSONResult.java b/framework/base/src/org/ofbiz/base/conversion/JSONResult.java
deleted file mode 100644
index 99a3785..0000000
--- a/framework/base/src/org/ofbiz/base/conversion/JSONResult.java
+++ /dev/null
@@ -1,42 +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.base.conversion;
-
-import java.io.StringWriter;
-
-import org.ofbiz.base.json.JSONWriter;
-
-public interface JSONResult {
-    JSONWriter getWriter();
-    String getResult();
-
-    public static class Indenting implements JSONResult {
-        private final StringWriter sw = new StringWriter();
-        private final JSONWriter writer = new JSONWriter(sw);
-
-        public JSONWriter getWriter() {
-            return writer;
-        }
-
-        public String getResult() {
-            return sw.toString();
-        }
-    }
-}
-
diff --git a/framework/base/src/org/ofbiz/base/conversion/test/MiscTests.java b/framework/base/src/org/ofbiz/base/conversion/test/MiscTests.java
index beed261..c4e40e2 100644
--- a/framework/base/src/org/ofbiz/base/conversion/test/MiscTests.java
+++ b/framework/base/src/org/ofbiz/base/conversion/test/MiscTests.java
@@ -21,7 +21,6 @@
 import java.math.BigDecimal;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -32,12 +31,10 @@
 import org.ofbiz.base.conversion.Converter;
 import org.ofbiz.base.conversion.ConverterLoader;
 import org.ofbiz.base.conversion.Converters;
-import org.ofbiz.base.conversion.JSONResult;
 import org.ofbiz.base.lang.SourceMonitored;
 import org.ofbiz.base.test.GenericTestCaseBase;
 import org.ofbiz.base.util.UtilGenerics;
 import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.base.util.collections.LRUMap;
 
 @SourceMonitored
 public class MiscTests extends GenericTestCaseBase {
@@ -46,12 +43,6 @@
         super(name);
     }
 
-    private static <S, T extends JSONResult.Indenting> void assertConversion(String label, String wanted, Class<T> targetClass, Object source, Class<S> sourceClass) throws Exception {
-        Converter<S, T> converter = Converters.getConverter(sourceClass, targetClass);
-        assertTrue(label + " can convert", converter.canConvert(sourceClass, targetClass));
-        assertEquals(label, wanted, converter.convert(UtilGenerics.<S>cast(source)).getResult());
-    }
-
     public void testStaticHelperClass() throws Exception {
         assertStaticHelperClass(Converters.class);
     }
@@ -66,22 +57,6 @@
         Converters.loadContainedConverters(MiscTests.class);
     }
 
-    public void testExtendsImplements() throws Exception {
-        List<String> arraysList = Arrays.asList("a", "b", "c");
-        assertConversion("", "[\n \"a\",\n \"b\",\n \"c\"\n]", JSONResult.Indenting.class, arraysList, arraysList.getClass());
-        Exception caught = null;
-        try {
-            Converters.getConverter(MiscTests.class, String.class);
-        } catch (ClassNotFoundException e) {
-            caught = e;
-        } finally {
-            assertNotNull("ClassNotFoundException thrown for MiscTests.class", caught);
-        }
-        LRUMap<String, String> map = new LRUMap<String, String>();
-        map.put("a", "1");
-        assertConversion("", "{\n \"a\": \"1\"\n}", JSONResult.Indenting.class, map, LRUMap.class);
-    }
-
     public static <S> void assertPassThru(Object wanted, Class<S> sourceClass) throws Exception {
         assertPassThru(wanted, sourceClass, sourceClass);
     }
diff --git a/framework/base/src/org/ofbiz/base/conversion/test/TestJSONConverters.java b/framework/base/src/org/ofbiz/base/conversion/test/TestJSONConverters.java
new file mode 100644
index 0000000..ec4ae09
--- /dev/null
+++ b/framework/base/src/org/ofbiz/base/conversion/test/TestJSONConverters.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.conversion.test;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.ofbiz.base.conversion.Converter;
+import org.ofbiz.base.conversion.ConverterLoader;
+import org.ofbiz.base.conversion.Converters;
+import org.ofbiz.base.conversion.JSONConverters;
+import org.ofbiz.base.lang.JSON;
+
+public class TestJSONConverters  extends TestCase {
+    public TestJSONConverters(String name) {
+        super(name);
+        ConverterLoader loader = new JSONConverters();
+        loader.loadConverters();
+    }
+
+    public void testJSONToMap() throws Exception {
+        Converter<JSON, Map> converter = Converters.getConverter(JSON.class, Map.class);
+        Map map, convertedMap;
+        map = new HashMap();
+        map.put("field1", "value1");
+        JSON json = JSON.from(map);
+        convertedMap = converter.convert(json);
+        assertEquals("JSON to Map", map, convertedMap);
+    }
+
+    public void testJSONToList() throws Exception {
+        Converter<JSON, List> converter = Converters.getConverter(JSON.class, List.class);
+        List list, convertedList;
+        list = new ArrayList();
+        list.add("field1");
+        list.add("field2");
+        JSON json = JSON.from(list);
+        convertedList = converter.convert(json);
+        assertEquals("JSON to List", list, convertedList);
+    }
+
+    public void testMapToJSON() throws Exception {
+        Converter<Map, JSON> converter = Converters.getConverter(Map.class, JSON.class);
+        JSON json;
+        Map map = new LinkedHashMap();
+        map.put("field1", "value1");
+        map.put("field2", new BigDecimal("3.7"));
+        json = converter.convert(map);
+        assertEquals("Map to JSON", "{\"field1\":\"value1\",\"field2\":3.7}", json.toString());
+    }
+
+    public void testListToJSON() throws Exception {
+        Converter<List, JSON> converter = Converters.getConverter(List.class, JSON.class);
+        JSON json;
+        List list = new ArrayList();
+        list.add("field1");
+        list.add("field2");
+        json = converter.convert(list);
+        assertEquals("List to JSON", "[\"field1\",\"field2\"]", json.toString());
+    }
+}
+
diff --git a/framework/base/src/org/ofbiz/base/json/JSON.jj b/framework/base/src/org/ofbiz/base/json/JSON.jj
deleted file mode 100644
index 4610ae4..0000000
--- a/framework/base/src/org/ofbiz/base/json/JSON.jj
+++ /dev/null
@@ -1,319 +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.
- *******************************************************************************/
-options {
-  ERROR_REPORTING = true;
-  STATIC = false;
-//  DEBUG_PARSER = true;
-//  DEBUG_LOOKAHEAD = true;
-//  DEBUG_TOKEN_MANAGER = true;
-  LOOKAHEAD = 1;
-//  CHOICE_AMBIGUITY_CHECK = 3;
-//  OTHER_AMBIGUITY_CHECK = 3;
-}
-
-PARSER_BEGIN(JSON)
-
-package org.ofbiz.base.json;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import javolution.util.FastMap;
-
-import org.ofbiz.base.util.UtilIO;
-
-public class JSON {
-    private boolean allowResolve;
-
-    public JSON(String fileName) {
-        this(System.in);
-        try { ReInit(new FileInputStream(new File(fileName))); }
-        catch(Exception e) { e.printStackTrace(); }
-//        allowed[TEXT] = 1;
-//        allowed[FIRST_COLUMN_TEXT] = 1;
-    }
-
-    public JSON allowResolve(boolean allowResolve) {
-        this.allowResolve = allowResolve;
-    token_source.SwitchTo(allowResolve ? RESOLVE : DEFAULT);
-    return this;
-    }
-}
-
-PARSER_END(JSON)
-TOKEN_MGR_DECLS: {
-    protected LinkedList<Integer> stateStack = new LinkedList<Integer>();
-    protected StringBuilder statePrefix = new StringBuilder();
-
-    protected void pushState(int state) {
-        //System.err.println(statePrefix + "push: " + lexStateNames[curLexState] + " -> " + lexStateNames[state]);
-        stateStack.add(curLexState);
-        statePrefix.append(' ');
-        SwitchTo(state);
-    }
-
-    protected void popState() {
-        int oldState = stateStack.removeLast();
-        statePrefix.setLength(statePrefix.length() - 1);
-        //System.err.println(statePrefix + "pop: " + lexStateNames[curLexState] + " -> " + lexStateNames[oldState]);
-        SwitchTo(oldState);
-    }
-}
-<DEFAULT,RESOLVE>
-TOKEN:
-{
-  <OBJECT_BEGIN: "{">
-| <OBJECT_END: "}">
-| <ARRAY_BEGIN: "[">
-| <ARRAY_END: "]">
-| <ITEM_SEP: ",">
-| <KEY_SEP: ":">
-| <TRUE: "true">
-| <FALSE: "false">
-| <NULL: "null">
-| <WHOLE_NUMBER:
-    <NUMBER_PREFIX>
-  >
-| <FLOAT_NUMBER:
-    <NUMBER_PREFIX>
-    ("." (["0"-"9"])*)?
-    (
-      ["e", "E"]
-      (["+", "-"])?
-      (["0"-"9"])+
-    )?
-  >
-| <#NUMBER_PREFIX:
-    (["-"])?
-    (
-      "0"
-    | ["1"-"9"] (["0"-"9"])*
-    )
-  >
-}
-
-<DEFAULT,RESOLVE,IN_RESOLVE_VALUE>
-TOKEN:
-{
-  <STRING_START: "\""> { pushState(IN_STRING); }
-}
-
-<IN_RESOLVE_VALUE>
-TOKEN:
-{
-  <CLOSE_PAREN: ")"> { popState(); }
-}
-
-<RESOLVE>
-TOKEN:
-{
-  <RESOLVE_BEGIN: "resolve("> { pushState(IN_RESOLVE_VALUE); }
-}
-
-<IN_STRING>
-TOKEN:
-{
-  <CHARACTER: (~["\"","\\","\u0000"-"\u001f"])+>
-| <STRING_END: "\""> { popState(); }
-| <CONTROL_CHAR: "\\" ["\"", "\\", "/", "b","f","n","r","t"]>
-| <UNICODE: "\\u"
-    ["a"-"f", "A"-"F", "0"-"9"]
-    ["a"-"f", "A"-"F", "0"-"9"]
-    ["a"-"f", "A"-"F", "0"-"9"]
-    ["a"-"f", "A"-"F", "0"-"9"]
-  >
-}
-
-<DEFAULT,RESOLVE>
-SKIP:
-{
-  <WHITESPACE: [" ", "\r", "\n", "\t"]>
-}
-
-<DEFAULT,RESOLVE>
-MORE:
-{
-  <COMMENT_START: "/*"> { if (curLexState != IN_COMMENT) pushState(IN_COMMENT); }
-}
-
-<IN_COMMENT>
-MORE:
-{
-  <(~[])>
-}
-
-<IN_COMMENT>
-MORE:
-{
-  <COMMENT_END: "*/"> { popState(); }
-}
-
-Object JSONValue():
-{ Object value; }
-{
-  value=JSONItem()
-  <EOF>
-  { return value; }
-}
-
-Object JSONItem():
-{ Object value; }
-{
-  (
-    value=JSONString()
-  | value=JSONLong()
-  | value=JSONFloat()
-  | value=JSONObject()
-  | value=JSONArray()
-  | value=True()
-  | value=False()
-  | value=Null()
-  | value=JSONResolve()
-  )
-  { return value; }
-}
-
-Object JSONResolve():
-{
-  String name, value;
-}
-{
-  <RESOLVE_BEGIN>
-  value=JSONString()
-  <CLOSE_PAREN>
-  {
-    try {
-      return UtilIO.readObject(value.toCharArray());
-    } catch (ClassNotFoundException e) {
-      throw generateParseException();
-    } catch (IOException e) {
-      throw generateParseException();
-    }
-  }
-}
-String JSONString():
-{
-  StringBuilder sb = new StringBuilder();
-}
-{
-  <STRING_START> (
-    <CHARACTER> { sb.append(getToken(0).image); }
-  | <CONTROL_CHAR> {
-    switch (getToken(0).image.charAt(1)) {
-      case '"': sb.append('"'); break;
-      case '\\': sb.append('\\'); break;
-      case '/': sb.append('/'); break;
-      case 'b': sb.append('\b'); break;
-      case 'f': sb.append('\f'); break;
-      case 'n': sb.append('\n'); break;
-      case 'r': sb.append('\r'); break;
-      case 't': sb.append('\t'); break;
-    }
-  }
-  | <UNICODE> {
-    int v = Integer.parseInt(getToken(0).image.substring(2), 16);
-    sb.append((char) v);
-  }
-  )*
-  <STRING_END>
-  { return sb.toString(); }
-}
-
-Long JSONLong():
-{}
-{
-  try {
-    <WHOLE_NUMBER> { return new Long(getToken(0).image); }
-  } catch (NumberFormatException e) {
-    throw generateParseException();
-  }
-}
-
-Double JSONFloat():
-{}
-{
-  try {
-    <FLOAT_NUMBER> { return new Double(getToken(0).image); }
-  } catch (NumberFormatException e) {
-    throw generateParseException();
-  }
-}
-
-Map<String, Object> JSONObject():
-{
-  Map<String, Object> map = FastMap.newInstance();
-}
-{
-  <OBJECT_BEGIN>
-  (JSONObjectEntry(map))? (<ITEM_SEP> (JSONObjectEntry(map))?)*
-  <OBJECT_END>
-  { return map; }
-}
-
-void JSONObjectEntry(Map<String, Object> map):
-{
-  String key;
-  Object value;
-}
-{
-  key=JSONString() <KEY_SEP> value=JSONItem()
-  { map.put(key, value); }
-}
-
-List<Object> JSONArray():
-{
-  ArrayList<Object> list = new ArrayList<Object>();
-  Object value;
-}
-{
-  <ARRAY_BEGIN>
-  (<ITEM_SEP>)*
-  (
-    value=JSONItem() { list.add(value); }
-    (
-      <ITEM_SEP>
-      (value=JSONItem() { list.add(value); })?
-    )*
-  )?
-  <ARRAY_END>
-  { return list; }
-}
-
-Boolean True():
-{}
-{
-  <TRUE> { return Boolean.TRUE; }
-}
-
-Boolean False():
-{}
-{
-  <FALSE> { return Boolean.FALSE; }
-}
-
-Object Null():
-{}
-{
-  <NULL> { return null; }
-}
diff --git a/framework/base/src/org/ofbiz/base/json/JSONWriter.java b/framework/base/src/org/ofbiz/base/json/JSONWriter.java
deleted file mode 100644
index 6243c0d..0000000
--- a/framework/base/src/org/ofbiz/base/json/JSONWriter.java
+++ /dev/null
@@ -1,233 +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.base.json;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.ofbiz.base.lang.SourceMonitored;
-import org.ofbiz.base.util.IndentingWriter;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilIO;
-
-@SourceMonitored
-public class JSONWriter {
-    private final IndentingWriter writer;
-    private final FallbackHandler fallbackHandler;
-
-    public JSONWriter(IndentingWriter writer) {
-        this(writer, StandardFallbackHandler);
-    }
-
-    public JSONWriter(IndentingWriter writer, FallbackHandler fallbackHandler) {
-        this.writer = writer;
-        this.fallbackHandler = fallbackHandler;
-    }
-
-    public JSONWriter(Writer writer) {
-        this(IndentingWriter.makeIndentingWriter(writer));
-    }
-
-    public JSONWriter(Writer writer, FallbackHandler fallbackHandler) {
-        this(IndentingWriter.makeIndentingWriter(writer), fallbackHandler);
-    }
-
-    public IndentingWriter getWriter() {
-        return writer;
-    }
-
-    public JSONWriter close() throws IOException {
-        getWriter().close();
-        return this;
-    }
-
-    public JSONWriter write(byte b) throws IOException {
-        writer.write(Byte.toString(b));
-        return this;
-    }
-
-    public JSONWriter write(short s) throws IOException {
-        writer.write(Short.toString(s));
-        return this;
-    }
-
-    public JSONWriter write(int i) throws IOException {
-        writer.write(Integer.toString(i));
-        return this;
-    }
-
-    public JSONWriter write(long l) throws IOException {
-        writer.write(Long.toString(l));
-        return this;
-    }
-
-    public JSONWriter write(float f) throws IOException {
-        writer.write(Float.toString(f));
-        return this;
-    }
-
-    public JSONWriter write(double d) throws IOException {
-        writer.write(Double.toString(d));
-        return this;
-    }
-
-    public JSONWriter write(char c) throws IOException {
-        write(Character.toString(c));
-        return this;
-    }
-
-    public JSONWriter write(String s) throws IOException {
-        writer.write('"');
-        for (int i = 0; i < s.length(); i++) {
-            char c = s.charAt(i);
-            switch (c) {
-                case '\\':  writer.write("\\\\"); continue;
-                case '/':  writer.write("\\/"); continue;
-                case '"':  writer.write("\\\""); continue;
-                case '\b':  writer.write("\\b"); continue;
-                case '\f':  writer.write("\\f"); continue;
-                case '\n':  writer.write("\\n"); continue;
-                case '\r':  writer.write("\\r"); continue;
-                case '\t':  writer.write("\\t"); continue;
-            }
-            if (c >= 32 && c < 256) {
-                writer.write(c);
-            } else {
-                writer.write("\\u");
-                String n = Integer.toString(c, 16);
-                for (int j = 4 - n.length(); j > 0; j--) writer.write('0');
-                writer.write(n);
-            }
-        }
-        writer.write('"');
-        return this;
-    }
-
-    public <K, V> JSONWriter write(Map<K, V> m) throws IOException {
-        writer.write('{');
-        writer.push();
-        Iterator<Map.Entry<K, V>> it = m.entrySet().iterator();
-        if (it.hasNext()) writer.newline();
-        while (it.hasNext()) {
-            Map.Entry<K, V> entry = it.next();
-            write(entry.getKey());
-            writer.write(':');
-            writer.space();
-            write(entry.getValue());
-            if (it.hasNext()) writer.write(',');
-            writer.newline();
-        }
-        writer.pop();
-        writer.write('}');
-        return this;
-    }
-
-    public <E> JSONWriter write(Collection<E> c) throws IOException {
-        this.write(c.iterator());
-        return this;
-    }
-
-    public <E> JSONWriter write(Iterator<E> it) throws IOException {
-        writer.write('[');
-        writer.push();
-        if (it.hasNext()) writer.newline();
-        while (it.hasNext()) {
-            write(it.next());
-            if (it.hasNext()) writer.write(',');
-            writer.newline();
-        }
-        writer.pop();
-        writer.write(']');
-        return this;
-    }
-
-    public <T> JSONWriter write(T... o) throws IOException {
-        writer.write('[');
-        writer.push();
-        for (int i = 0; i < o.length; i++) {
-            if (i != 0) writer.write(',');
-            writer.newline();
-            write(o[i]);
-        }
-        if (o.length > 0) writer.newline();
-        writer.pop();
-        writer.write(']');
-        return this;
-    }
-
-    public JSONWriter write(Object o) throws IOException {
-        if (o == null) {
-            writer.write("null");
-            return this;
-        } else if (o instanceof Boolean) {
-            writer.write(((Boolean) o).booleanValue() ? "true" : "false");
-            return this;
-        } else if (o instanceof String) {
-            return write((String) o);
-        } else if (o instanceof Map<?, ?>) {
-            return write(UtilGenerics.<Map<?, ?>>cast(o));
-        } else if (o instanceof Collection<?>) {
-            return write(UtilGenerics.<Collection<?>>cast(o));
-        } else if (o instanceof Iterator<?>) {
-            return write(UtilGenerics.<Iterator<?>>cast(o));
-        } else if (o instanceof Byte) {
-            return write(((Byte) o).byteValue());
-        } else if (o instanceof Character) {
-            return write(((Character) o).charValue());
-        } else if (o instanceof Double) {
-            return write(((Double) o).doubleValue());
-        } else if (o instanceof Float) {
-            return write(((Float) o).floatValue());
-        } else if (o instanceof Integer) {
-            return write(((Integer) o).intValue());
-        } else if (o instanceof Long) {
-            return write(((Long) o).longValue());
-        } else if (o instanceof Short) {
-            return write(((Short) o).shortValue());
-        } else if (o.getClass().isArray()) {
-            return write((Object[]) o);
-        } else {
-            fallbackHandler.writeJSON(this, writer, o);
-            return this;
-        }
-    }
-
-    public interface FallbackHandler {
-        void writeJSON(JSONWriter json, Writer writer, Object o) throws IOException;
-    }
-
-    public static final FallbackHandler StandardFallbackHandler = new FallbackHandler() {
-        public void writeJSON(JSONWriter json, Writer writer, Object o) throws IOException {
-            throw new IOException("Can't write(" + o + ":" + o.getClass() + ")");
-        }
-    };
-
-    public static final FallbackHandler ResolvingFallbackHandler = new FallbackHandler() {
-        public void writeJSON(JSONWriter json, Writer writer, Object o) throws IOException {
-            StringBuilder sb = new StringBuilder();
-            UtilIO.writeObject(sb, o);
-            writer.write("resolve(");
-            json.write(sb.toString());
-            writer.write(")");
-        }
-    };
-}
diff --git a/framework/base/src/org/ofbiz/base/json/test/JSONTests.java b/framework/base/src/org/ofbiz/base/json/test/JSONTests.java
deleted file mode 100644
index 9436a3e..0000000
--- a/framework/base/src/org/ofbiz/base/json/test/JSONTests.java
+++ /dev/null
@@ -1,334 +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.base.json.test;
-
-import java.io.IOException;
-import java.io.ByteArrayOutputStream;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.OutputStreamWriter;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-import org.ofbiz.base.json.JSON;
-import org.ofbiz.base.json.JSONConstants;
-import org.ofbiz.base.json.JSONWriter;
-import org.ofbiz.base.json.ParseException;
-import org.ofbiz.base.json.Token;
-import org.ofbiz.base.json.TokenMgrError;
-import org.ofbiz.base.lang.SourceMonitored;
-import org.ofbiz.base.test.GenericTestCaseBase;
-import org.ofbiz.base.util.IndentingWriter;
-
-@SourceMonitored
-public class JSONTests extends GenericTestCaseBase {
-    public JSONTests(String name) {
-        super(name);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    protected Object parseJSON(String value, boolean allowResolve) throws Exception {
-        return new JSON(new StringReader(value)).allowResolve(allowResolve).JSONValue();
-    }
-
-    protected String getJSON(Object object, boolean allowResolve) throws Exception {
-        StringWriter writer = new StringWriter();
-        JSONWriter jsonWriter;
-        if (allowResolve) {
-            jsonWriter = new JSONWriter(writer, JSONWriter.ResolvingFallbackHandler);
-        } else {
-            jsonWriter = new JSONWriter(writer);
-        }
-        assertTrue("writer is IndentingWriter", jsonWriter.getWriter() instanceof IndentingWriter);
-        jsonWriter.write(object);
-        return writer.toString();
-    }
-
-    protected void assertSimpleJSONByte(byte n, String json) throws Exception {
-        assertSimpleJSON("integer - byte", new Byte(n), json, new Long(n));
-        assertSimpleJSONShort(n, json);
-    }
-
-    protected void assertSimpleJSONShort(short n, String json) throws Exception {
-        assertSimpleJSON("integer - short", new Integer(n), json, new Long(n));
-        assertSimpleJSONInteger(n, json);
-    }
-
-    protected void assertSimpleJSONInteger(int n, String json) throws Exception {
-        assertSimpleJSON("integer - int", new Short((short) n), json, new Long(n));
-        assertSimpleJSONLong(n, json);
-    }
-
-    protected void assertSimpleJSONLong(long n, String json) throws Exception {
-        assertSimpleJSON("integer - long", new Long(n), json, new Long(n));
-    }
-
-    protected void assertSimpleJSONFloat(float n, String json) throws Exception {
-        assertSimpleJSON("float - float", new Float(n), json, new Double(n));
-        assertSimpleJSONDouble(n, json);
-    }
-
-    protected void assertSimpleJSONDouble(double n, String json) throws Exception {
-        assertSimpleJSON("float - double", new Double(n), json);
-    }
-
-    protected void assertSimpleJSON(String type, Object object, String json) throws Exception {
-        assertSimpleJSON(type, object, json, object);
-    }
-
-    protected void assertSimpleJSON(String type, Object before, String json, Object after) throws Exception {
-        assertEquals("write " + type, json, getJSON(before, false));
-        assertEquals("parse " + type, after, parseJSON(json, false));
-    }
-
-    protected void assertResolveJSON(String type, Object obj, String json) throws Exception {
-        assertEquals("write " + type, json, getJSON(obj, true));
-        assertEquals("parse " + type, obj, parseJSON(json, true));
-    }
-
-    public void testClose() throws Exception {
-        JSONWriter writer = new JSONWriter(new OutputStreamWriter(new ByteArrayOutputStream()));
-        writer.close();
-        IOException caught = null;
-        try {
-            writer.write("");
-        } catch (IOException e) {
-            caught = e;
-        } finally {
-            assertNotNull("write after close", caught);
-        }
-    }
-
-    public void testString() throws Exception {
-        StringBuilder wanted = new StringBuilder();
-        StringBuilder json = new StringBuilder().append('"');
-        for (int i = 0; i < 5120; i++) {
-            wanted.append((char) i);
-            if (i == '\b') {
-                json.append("\\b");
-            } else if (i == '\f') {
-                json.append("\\f");
-            } else if (i == '\t') {
-                json.append("\\t");
-            } else if (i == '\n') {
-                json.append("\\n");
-            } else if (i == '\r') {
-                json.append("\\r");
-            } else if (i == '"') {
-                json.append("\\\"");
-            } else if (i == '\\') {
-                json.append("\\\\");
-            } else if (i == '/') {
-                json.append("\\/");
-            } else if (i < 32 || i >= 256) {
-                json.append("\\u");
-                if (i < 16) json.append('0');
-                if (i < 256) json.append('0');
-                if (i < 4096) json.append('0');
-                json.append(Integer.toString(i, 16));
-            } else {
-                json.append((char) i);
-            }
-        }
-        json.append('"');
-        assertSimpleJSON("string", wanted.toString(), json.toString());
-    }
-
-    public void testParseBasicTypes() throws Exception {
-        assertSimpleJSON("character", new Character('c'), "\"c\"", "c");
-        assertSimpleJSON("false", Boolean.FALSE, "false");
-        assertSimpleJSON("null", null, "null");
-        assertSimpleJSON("true", Boolean.TRUE, "true");
-        assertSimpleJSON("simple string", "foo", "\"foo\"");
-        assertSimpleJSONByte((byte) 42, "42");
-        assertSimpleJSONFloat(Float.valueOf("1.0625"), "1.0625");
-        assertSimpleJSON(
-            "complex string",
-            "quote(\") backslash(\\) forwardslash(/) backspace(\b) formfeed(\f) newline(\n) carriagereturn(\r) tab(\t) trademark(\u2122)",
-            "\"quote(\\\") backslash(\\\\) forwardslash(\\/) backspace(\\b) formfeed(\\f) newline(\\n) carriagereturn(\\r) tab(\\t) trademark(\\u2122)\""
-        );
-    }
-
-    public void testParseComplexTypes() throws Exception {
-        assertEquals(
-            "parse simple array",
-            list(new Object[] {"foo", new Long(1234), new Double(5.678)}),
-            parseJSON("[, ,\t,\r,\n,\r\n,\"foo\", 1234, 5.678,]", false)
-        );
-        assertSimpleJSON(
-            "simple empty list",
-            list(new Object[] {}),
-            "[]"
-        );
-        assertSimpleJSON(
-            "simple empty array",
-            new Object[] {},
-            "[]",
-            list(new Object[] {})
-        );
-        assertSimpleJSON(
-            "simple array->list",
-            new Object[] {"foo", new Long(1234), new Double(5.678)},
-            "[\n \"foo\",\n 1234,\n 5.678\n]",
-            list(new Object[] {"foo", new Long(1234), new Double(5.678)})
-        );
-        assertSimpleJSON(
-            "simple array",
-            list(new Object[] {"foo", new Long(1234), new Double(5.678)}),
-            "[\n \"foo\",\n 1234,\n 5.678\n]",
-            list(new Object[] {"foo", new Long(1234), new Double(5.678)})
-        );
-        assertEquals(
-            "parse simple map",
-            map(new Object[] {"foo", new Long(1234), "bar", new Double(5.678)}),
-            parseJSON("{, ,\t,\r,\n,\r\n,\"foo\": 1234, \"bar\": 5.678,}", false)
-        );
-        assertSimpleJSON(
-            "parse map",
-            map(new Object[] {"foo", new Long(1234), "bar", new Double(5.678)}),
-            "{\n \"foo\": 1234,\n \"bar\": 5.678\n}"
-        );
-        assertSimpleJSON(
-            "parse empty map",
-            map(new Object[] {}),
-            "{}"
-        );
-        assertEquals(
-            "parse nested map",
-            map(new Object[] {
-                "string",       "this is a string",
-                "integer",      new Long(5000),
-                "double",       new Double(3.1415926),
-                "array",        new Object[] {
-                    "string",
-                    new Long(6000)
-                },
-                "list",         list(new Object[] {
-                    "nested string",
-                    "something",
-                }),
-                "empty-list",   new ArrayList<String>(),
-                "empty-array",  new String[0],
-                "empty-map",    new HashMap<String, Object>(),
-            }),
-            parseJSON("{\"string\": \"this is a string\", \"integer\": 5000, \"double\": 3.1415926, \"array\": [\"string\", 6000], \"list\": [\"nested string\", \"something\"], \"empty-list\": [], \"empty-array\": [], \"empty-map\": {}}", false)
-        );
-    }
-
-    public void testParseErrors() throws Exception {
-        for (char c = 1; c < 1024; c++) {
-            if (c == '\t') {
-                doWhitespaceExceptionTest(Character.toString(c), 8);
-            } else if (c == '\n' || c == '\r' || c == ' ') {
-                doWhitespaceExceptionTest(Character.toString(c), 1);
-            } else if (c == '"') {
-                doParseExceptionTest("\"", JSONConstants.EOF);
-            } else if (c == ',') {
-                doParseExceptionTest(",", JSONConstants.ITEM_SEP);
-            } else if (c == '-' || c == '.' || (c >= '0' && c <= '9')) {
-                // numbers
-            } else if (c == ':') {
-                doParseExceptionTest(":", JSONConstants.KEY_SEP);
-            } else if (c == '[') {
-                doParseExceptionTest("[:", JSONConstants.KEY_SEP);
-            } else if (c == ']') {
-                doParseExceptionTest("]", JSONConstants.ARRAY_END);
-            } else if (c == 't') {
-                doParseExceptionTest("true:", JSONConstants.KEY_SEP);
-            } else if (c == 'f') {
-                doParseExceptionTest("false:", JSONConstants.KEY_SEP);
-            } else if (c == 'n') {
-                doParseExceptionTest("null:", JSONConstants.KEY_SEP);
-            } else if (c == '{') {
-                doParseExceptionTest("{:", JSONConstants.KEY_SEP);
-            } else if (c == '}') {
-                doParseExceptionTest("}", JSONConstants.OBJECT_END);
-            } else {
-                doTokenMgrErrorTest(c);
-            }
-        }
-    }
-
-    protected void doWhitespaceExceptionTest(String s, int column) {
-        ParseException caught = null;
-        try {
-            new JSON(new StringReader(s)).JSONValue();
-        } catch (ParseException e) {
-            caught = e;
-        } finally {
-            assertNotNull("caught exception", caught);
-            assertNotNull("next token(" + s + ")", caught.currentToken);
-            Token next = caught.currentToken.next;
-            assertEquals("next token(" + s + ") is eof", 0, next.kind);
-            assertEquals("begin line(" + s + ")", 1, next.beginLine);
-            assertEquals("begin column(" + s + ")", column, next.beginColumn);
-        }
-    }
-
-    protected void doParseExceptionTest(String s, int nextKind) {
-        ParseException caught = null;
-        try {
-            new JSON(new StringReader(s)).JSONValue();
-        } catch (ParseException e) {
-            caught = e;
-        } finally {
-            assertNotNull("caught exception", caught);
-            assertNotNull("exception message(" + s + ")", caught.getMessage());
-            assertNotNull("next token(" + s + ")", caught.currentToken);
-            Token next = caught.currentToken.next;
-            assertEquals("next token(" + s + ") is correct", nextKind, next.kind);
-            assertEquals("begin line(" + s + ")", 1, next.beginLine);
-            assertEquals("begin column(" + s + ")", s.length(), next.beginColumn);
-        }
-    }
-
-    protected void doTokenMgrErrorTest(char c) throws Exception {
-        TokenMgrError caught = null;
-        try {
-            parseJSON(c + "\"string\"", false);
-        } catch (TokenMgrError e) {
-            caught = e;
-        } finally {
-            assertNotNull("No TokenMgrError thrown for character(" + ((int) c) + ")", caught);
-            // FIXME: maybe extend javacc to return more info in TokenMgrError
-        }
-    }
-
-    public void testResolve() throws Exception {
-        assertResolveJSON("url", new URL("http://ofbiz.apache.org"), "resolve(\"java.net.URL:http:\\/\\/ofbiz.apache.org\")");
-        IOException caught = null;
-        try {
-            getJSON(new URL("http://ofbiz.apache.org"), false);
-        } catch (IOException e) {
-            caught = e;
-        } finally {
-            assertNotNull("url not allowed", caught);
-        }
-    }
-}
diff --git a/framework/base/src/org/ofbiz/base/lang/JSON.java b/framework/base/src/org/ofbiz/base/lang/JSON.java
new file mode 100644
index 0000000..16a0143
--- /dev/null
+++ b/framework/base/src/org/ofbiz/base/lang/JSON.java
@@ -0,0 +1,136 @@
+/*******************************************************************************

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ *

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

+ *

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

+ * software distributed under the License is distributed on an

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

+

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.Reader;

+

+import org.apache.commons.io.IOUtils;

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

+

+import com.fasterxml.jackson.databind.ObjectMapper;

+

+/** A JSON object. */

+@ThreadSafe

+public final class JSON {

+

+    // TODO: Find a generic way to modify mapper options

+    private static final ObjectMapper mapper = new ObjectMapper();

+

+    /**

+     * Creates a <code>JSON</code> instance from an <code>InputStream</code>.

+     * The method assumes the character set is UTF-8.

+     * 

+     * @param inStream

+     * @return a <code>JSON</code> instance

+     * @throws IOException

+     */

+    public static JSON from(InputStream inStream) throws IOException {

+        Assert.notNull("inStream", inStream);

+        String jsonString = IOUtils.toString(inStream, "UTF-8");

+        return from(jsonString);

+    }

+

+    /**

+     * Creates a <code>JSON</code> instance from an unknown data type.

+     * 

+     * @param object

+     * @return a <code>JSON</code> instance

+     * @throws IOException

+     */

+    public static JSON from(Object object) throws IOException {

+        Assert.notNull("object", object);

+        try {

+            return from(mapper.writeValueAsString(object));

+        } catch (Exception e) {

+            throw new IOException(e);

+        }

+    }

+

+    /**

+     * Creates a <code>JSON</code> instance from a <code>Reader</code>.

+     * 

+     * @param reader

+     * @return a <code>JSON</code> instance

+     * @throws IOException

+     */

+    public static JSON from(Reader reader) throws IOException {

+        Assert.notNull("reader", reader);

+        String jsonString = IOUtils.toString(reader);

+        return from(jsonString);

+    }

+

+    /**

+     * Creates a <code>JSON</code> instance from a <code>String</code>.

+     * 

+     * @param jsonString

+     * @return a <code>JSON</code> instance

+     */

+    public static JSON from(String jsonString) {

+        Assert.notNull("jsonString", jsonString);

+        // TODO: Validate String

+        return new JSON(jsonString);

+    }

+

+    private final String jsonString;

+

+    private JSON(String jsonString) {

+        this.jsonString = jsonString;

+    }

+

+    @Override

+    public boolean equals(Object obj) {

+        if (obj == this) {

+            return true;

+        }

+        if (obj instanceof JSON) {

+            return jsonString.equals(((JSON)obj).jsonString);

+        }

+        return false;

+    }

+

+    @Override

+    public int hashCode() {

+        return jsonString.hashCode();

+    }

+

+    /**

+     * Converts this <code>JSON</code> object to the specified type.

+     * 

+     * @param targetClass

+     * @return an object of the specified type

+     * @throws IOException

+     */

+    public <T> T toObject(Class<T> targetClass) throws IOException {

+        Assert.notNull("targetClass", targetClass);

+        try {

+            return mapper.readValue(jsonString, targetClass);

+        } catch (IOException e) {

+            throw e;

+        } catch (Exception e) {

+            throw new IOException(e);

+        }

+    }

+

+    @Override

+    public String toString() {

+        return jsonString;

+    }

+}

diff --git a/framework/base/src/org/ofbiz/base/util/UtilIO.java b/framework/base/src/org/ofbiz/base/util/UtilIO.java
index 3e61434..ecbfee6 100644
--- a/framework/base/src/org/ofbiz/base/util/UtilIO.java
+++ b/framework/base/src/org/ofbiz/base/util/UtilIO.java
@@ -19,34 +19,20 @@
 package org.ofbiz.base.util;
 
 import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
 import java.io.Reader;
-import java.io.Serializable;
-import java.io.StringReader;
-import java.io.StringWriter;
 import java.io.Writer;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 import java.nio.charset.Charset;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringUtils;
-import org.ofbiz.base.conversion.Converter;
-import org.ofbiz.base.conversion.Converters;
-import org.ofbiz.base.json.JSON;
-import org.ofbiz.base.json.JSONWriter;
 
 public final class UtilIO {
     public static final Charset UTF8 = Charset.forName("UTF-8");
@@ -329,141 +315,4 @@
         writer.write(value.substring(r));
         writer.close();
     }
-
-    public static Object readObject(File file) throws ClassNotFoundException, IOException {
-        return readObject(new FileInputStream(file), false);
-    }
-
-    public static Object readObject(File file, boolean allowJsonResolve) throws ClassNotFoundException, IOException {
-        return readObject(new FileInputStream(file), allowJsonResolve);
-    }
-
-    public static Object readObject(InputStream in) throws ClassNotFoundException, IOException {
-        return readObject(in, false);
-    }
-
-    public static Object readObject(InputStream in, boolean allowJsonResolve) throws ClassNotFoundException, IOException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        IOUtils.copy(in, baos);
-        in.close();
-        byte[] bytes = baos.toByteArray();
-        try {
-            char[] buffer = StringUtils.chomp(readString(bytes)).toCharArray();
-            return parseObject(buffer, 0, buffer.length, allowJsonResolve);
-        } catch (Exception e) {
-        }
-        ObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(bytes));
-        Serializable value = (Serializable) oin.readObject();
-        oin.close();
-        return value;
-    }
-
-    public static Object readObject(char[] buffer) throws ClassNotFoundException, IOException {
-        return parseObject(buffer, 0, buffer.length, false);
-    }
-
-    public static Object readObject(char[] buffer, int offset, int length) throws ClassNotFoundException, IOException {
-        return parseObject(buffer, offset, length, false);
-    }
-
-    private static <S, T> T convertObject(Class<S> sourceClass, S value, Class<T> targetClass) throws Exception {
-        Converter<S, T> converter = Converters.getConverter(sourceClass, targetClass);
-        return converter.convert(targetClass, value);
-    }
-
-    private static Object parseObject(char[] buffer, int offset, int length, boolean allowJsonResolve) throws ClassNotFoundException, IOException {
-        try {
-            int i;
-            for (i = offset; i < length && buffer[i] != ':'; i++);
-            if (i > offset && i < length) {
-                String className = new String(buffer, offset, i);
-                Class<?> type = Class.forName(className);
-                if (buffer[length - 1] == '\n') {
-                    length--;
-                }
-                if (buffer[length - 1] == '\r') {
-                    length--;
-                }
-                return convertObject(String.class, new String(buffer, i + 1, length - i - 1), type);
-            }
-        } catch (Exception e) {
-        }
-        try {
-            return new JSON(new StringReader(new String(buffer, offset, length))).allowResolve(allowJsonResolve).JSONValue();
-        } catch (Error e) {
-        } catch (Exception e) {
-        }
-        throw new IOException("Can't read (" + new String(buffer, offset, length) + ")");
-    }
-
-    public static void writeObject(File file, Object value) throws IOException {
-        writeObject(new FileOutputStream(file), value, false);
-    }
-
-    public static void writeObject(File file, Object value, boolean allowJsonResolve) throws IOException {
-        writeObject(new FileOutputStream(file), value, allowJsonResolve);
-    }
-
-    public static void writeObject(OutputStream out, Object value) throws IOException {
-        writeObject(out, value, false);
-    }
-
-    public static void writeObject(OutputStream out, Object value, boolean allowJsonResolve) throws IOException {
-        try {
-            PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, UTF8));
-            if (encodeObject(writer, value, allowJsonResolve)) {
-                writer.println();
-                writer.close();
-                return;
-            }
-        } catch (Exception e) {
-        }
-        ObjectOutputStream oout = new ObjectOutputStream(out);
-        oout.writeObject(value);
-        oout.close();
-        out.close();
-    }
-
-    private static <T> boolean encodeObject(Writer writer, T value, boolean allowJsonResolve) throws Exception {
-        Converter<T, String> converter = UtilGenerics.cast(Converters.getConverter(value.getClass(), String.class));
-        if (converter != null) {
-            Class<?> clz = converter.getSourceClass();
-            String str = converter.convert(value);
-            if (clz != null) {
-                writer.write(clz.getName());
-            } else {
-                writer.write(value.getClass().getName());
-            }
-            writer.write(':');
-            writer.write(str);
-            return true;
-        } else {
-            StringWriter sw = new StringWriter();
-            IndentingWriter indenting = new IndentingWriter(writer, true, false);
-            JSONWriter jsonWriter;
-            if (allowJsonResolve) {
-                jsonWriter = new JSONWriter(indenting, JSONWriter.ResolvingFallbackHandler);
-            } else {
-                jsonWriter = new JSONWriter(indenting);
-            }
-            jsonWriter.write(value);
-            writer.write(sw.toString());
-            return true;
-        }
-    }
-
-    public static void writeObject(StringBuilder sb, Object value) throws IOException {
-        writeObject(sb, value, false);
-    }
-
-    public static void writeObject(StringBuilder sb, Object value, boolean allowJsonResolve) throws IOException {
-        try {
-            StringWriter writer = new StringWriter();
-            if (encodeObject(writer, value, allowJsonResolve)) {
-                sb.append(writer.toString());
-                return;
-            }
-        } catch (Exception e) {} //Empty catch because writeObject() calls encodeObject(), which *always* returns true, unless an error occurs.  
-        throw new IOException("Can't write (" + value + ")");            
-    }
 }
diff --git a/framework/base/src/org/ofbiz/base/util/test/UtilIOTests.java b/framework/base/src/org/ofbiz/base/util/test/UtilIOTests.java
index 9fa09e2..ea0b7b4 100644
--- a/framework/base/src/org/ofbiz/base/util/test/UtilIOTests.java
+++ b/framework/base/src/org/ofbiz/base/util/test/UtilIOTests.java
@@ -129,53 +129,4 @@
         UtilIO.writeString(baos, UtilIO.UTF8, toWrite);
         assertEquals("writeString UTF8:" + label, wanted, baos.toByteArray());
     }
-
-    protected void checkBasicReadObject(Object value, String text) throws Exception {
-        byte[] bytes = text.getBytes("UTF-8");
-        assertEquals("read bytes " + value.getClass().getName(), value, UtilIO.readObject(new ByteArrayInputStream(bytes)));
-        assertEquals("read chars " + value.getClass().getName(), value, UtilIO.readObject(text.toCharArray()));
-        assertEquals("read chars offset " + value.getClass().getName(), value, UtilIO.readObject(text.toCharArray(), 0, text.length()));
-    }
-
-    protected void checkBasicReadWriteObject(Object value, String text) throws Exception {
-        String lineEnding = System.getProperty("line.separator");
-        text = text.replaceAll("\n", lineEnding);
-        byte[] bytes = text.getBytes("UTF-8");
-        assertEquals("read bytes " + value.getClass().getName(), value, UtilIO.readObject(new ByteArrayInputStream(bytes)));
-        assertEquals("read chars " + value.getClass().getName(), value, UtilIO.readObject(text.toCharArray()));
-        assertEquals("read chars offset " + value.getClass().getName(), value, UtilIO.readObject(text.toCharArray(), 0, text.length()));
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        UtilIO.writeObject(baos, value);
-        assertEquals("write stream " + value.getClass().getName(), text, new String(baos.toByteArray(), "UTF-8"));
-        StringBuilder sb = new StringBuilder();
-        UtilIO.writeObject(sb, value);
-        sb.append(lineEnding);
-        assertEquals("write builder " + value.getClass().getName(), text, sb.toString());
-    }
-
-    public void testReadWriteObject() throws Exception {
-        checkBasicReadWriteObject(Boolean.TRUE, "java.lang.Boolean:true\n");
-        checkBasicReadWriteObject(Byte.valueOf("1"), "java.lang.Byte:1\n");
-        checkBasicReadWriteObject(Double.valueOf("1.0"), "java.lang.Double:1.0\n");
-        checkBasicReadWriteObject(Float.valueOf("1.0"), "java.lang.Float:1.0\n");
-        checkBasicReadWriteObject(Integer.valueOf("1"), "java.lang.Integer:1\n");
-        checkBasicReadWriteObject(Long.valueOf("1"), "java.lang.Long:1\n");
-        checkBasicReadWriteObject(Short.valueOf("1"), "java.lang.Short:1\n");
-        checkBasicReadWriteObject(BigDecimal.valueOf(500.5), "java.math.BigDecimal:500.5\n");
-        checkBasicReadWriteObject(BigInteger.valueOf(500), "java.math.BigInteger:500\n");
-        checkBasicReadWriteObject("1", "java.lang.String:1\n");
-        checkBasicReadObject(Arrays.asList(new Object[] {"a", UtilMisc.toMap("b", Long.valueOf(1))}), "[\n \"a\",\n {\n  \"b\": 1\n }\n]\n");
-        checkBasicReadWriteObject(MemoryType.HEAP, "java.lang.management.MemoryType:HEAP\n");
-        checkBasicReadWriteObject(MemoryType.NON_HEAP, "java.lang.management.MemoryType:NON_HEAP\n");
-        checkBasicReadWriteObject(UtilIO.UTF8, "java.nio.charset.Charset:UTF-8\n");
-        checkBasicReadWriteObject(InetAddress.getByAddress("localhost", new byte[] {127, 0, 0, 1}), "java.net.InetAddress:localhost\n");
-        //checkBasicReadWriteObject(Pattern.compile("^([a-z]{3}.*?):$"), "java.util.regex.Pattern:^([a-z]{3}.*?):$\n");
-        checkBasicReadWriteObject(Time.valueOf("12:34:56"), "java.sql.Time:12:34:56\n");
-        //checkBasicReadWriteObject(new Timestamp(1234567890), "java.sql.Timestamp:1234567890 00:00:00\n");
-        //checkBasicReadWriteObject(new java.util.Date(1234567890), "java.util.Date:1234567890\n");
-        checkBasicReadWriteObject(UUID.fromString("c3241927-9f77-43e1-be16-bd71d245ef64"), "java.util.UUID:c3241927-9f77-43e1-be16-bd71d245ef64\n");
-        checkBasicReadWriteObject(TimeZone.getTimeZone("America/Chicago"), "java.util.TimeZone:America/Chicago\n");
-        checkBasicReadWriteObject(new SimpleDateFormat("MM/dd/yyyy hh:mm a"), "java.text.SimpleDateFormat:MM/dd/yyyy hh:mm a\n");
-        checkBasicReadWriteObject(new Locale("en", "us"), "java.util.Locale:en_US\n");
-    }
 }
diff --git a/framework/base/testdef/basetests.xml b/framework/base/testdef/basetests.xml
index adfcf90..564c817 100644
--- a/framework/base/testdef/basetests.xml
+++ b/framework/base/testdef/basetests.xml
@@ -32,7 +32,8 @@
         <junit-test-suite class-name="org.ofbiz.base.util.cache.test.UtilCacheTests"/>
         <junit-test-suite class-name="org.ofbiz.base.conversion.test.DateTimeTests"/>
         <junit-test-suite class-name="org.ofbiz.base.conversion.test.MiscTests"/>
-        <junit-test-suite class-name="org.ofbiz.base.json.test.JSONTests"/>
+        <junit-test-suite class-name="org.ofbiz.base.conversion.test.TestBooleanConverters"/>
+        <junit-test-suite class-name="org.ofbiz.base.conversion.test.TestJSONConverters"/>
         <!--junit-test-suite class-name="org.ofbiz.base.util.test.UtilIOTests"/-->
         <junit-test-suite class-name="org.ofbiz.base.test.BaseUnitTests"/>
         <junit-test-suite class-name="org.ofbiz.base.util.test.UtilPropertiesTests"/>
diff --git a/framework/common/src/org/ofbiz/common/CommonEvents.java b/framework/common/src/org/ofbiz/common/CommonEvents.java
index b1b8f51..72c7b44 100644
--- a/framework/common/src/org/ofbiz/common/CommonEvents.java
+++ b/framework/common/src/org/ofbiz/common/CommonEvents.java
@@ -28,8 +28,8 @@
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
+import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Locale;
@@ -41,13 +41,10 @@
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
-import net.sf.json.JSON;
-import net.sf.json.JSONArray;
-import net.sf.json.JSONObject;
-import net.sf.json.JSONSerializer;
 
 import org.apache.commons.lang.RandomStringUtils;
 import org.apache.commons.lang.StringUtils;
+import org.ofbiz.base.lang.JSON;
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.StringUtil;
 import org.ofbiz.base.util.UtilGenerics;
@@ -289,15 +286,16 @@
                 attrMap.remove(ignoreAttr);
             }
         }
-
-        // create a JSON Object for return
-        JSONObject json = JSONObject.fromObject(attrMap);
-        writeJSONtoResponse(json, request.getMethod(), response);
-
+        try {
+            JSON json = JSON.from(attrMap);
+            writeJSONtoResponse(json, request.getMethod(), response);
+        } catch (Exception e) {
+            return "error";
+        }
         return "success";
     }
 
-    private static void writeJSONtoResponse(JSON json, String httpMethod, HttpServletResponse response) {
+    private static void writeJSONtoResponse(JSON json, String httpMethod, HttpServletResponse response) throws UnsupportedEncodingException {
         String jsonStr = json.toString();
         if (jsonStr == null) {
             Debug.logError("JSON Object was empty; fatal error!", module);
@@ -307,21 +305,17 @@
         // This was added for security reason (OFBIZ-5409), you might need to remove the "//" prefix when handling the JSON response
         // Though normally you simply have to access the data you want, so should not be annoyed by the "//" prefix
         if ("GET".equalsIgnoreCase(httpMethod)) {
-            Debug.logWarning("for security reason (OFBIZ-5409) the the '//' prefix was added handling the JSON response.  " +
-                    "Normally you simply have to access the data you want, so should not be annoyed by the '//' prefix." +
-                    "You might need to remove it if you use Ajax GET responses (not recommended)." +
-                    "In case, the util.js scrpt is there to help you", module);
+            Debug.logWarning("for security reason (OFBIZ-5409) the the '//' prefix was added handling the JSON response.  "
+                    + "Normally you simply have to access the data you want, so should not be annoyed by the '//' prefix."
+                    + "You might need to remove it if you use Ajax GET responses (not recommended)."
+                    + "In case, the util.js scrpt is there to help you", module);
             jsonStr = "//" + jsonStr;
         }
 
         // set the X-JSON content type
         response.setContentType("application/x-json");
         // jsonStr.length is not reliable for unicode characters
-        try {
-            response.setContentLength(jsonStr.getBytes("UTF8").length);
-        } catch (UnsupportedEncodingException e) {
-            Debug.logError("Problems with Json encoding: " + e, module);
-        }
+        response.setContentLength(jsonStr.getBytes("UTF8").length);
 
         // return the JSON String
         Writer out;
@@ -334,81 +328,65 @@
         }
     }
 
-
-    public static String getJSONuiLabelArray(HttpServletRequest request, HttpServletResponse response) {
-        String requiredLabels = request.getParameter("requiredLabels");
-
-        JSONObject uiLabelObject = null;
-        if (UtilValidate.isNotEmpty(requiredLabels)) {
-            // Transform JSON String to Object
-            uiLabelObject = (JSONObject) JSONSerializer.toJSON(requiredLabels);
+    public static String getJSONuiLabelArray(HttpServletRequest request, HttpServletResponse response)
+            throws UnsupportedEncodingException, IOException {
+        // Format - {resource1 : [key1, key2 ...], resource2 : [key1, key2, ...], ...}
+        String jsonString = request.getParameter("requiredLabels");
+        Map<String, List<String>> uiLabelObject = null;
+        if (UtilValidate.isNotEmpty(jsonString)) {
+            JSON json = JSON.from(jsonString);
+            uiLabelObject = UtilGenerics.<Map<String, List<String>>> cast(json.toObject(Map.class));
         }
-
-        JSONObject jsonUiLabel = new JSONObject();
+        if (UtilValidate.isEmpty(uiLabelObject)) {
+            Debug.logError("No resource and labels found in JSON string: " + jsonString, module);
+            return "error";
+        }
         Locale locale = request.getLocale();
-        if(!uiLabelObject.isEmpty()) {
-            Set<String> resourceSet = UtilGenerics.checkSet(uiLabelObject.keySet());
-            // Iterate over the resouce set
-            for (String resource : resourceSet) {
-                JSONArray labels = uiLabelObject.getJSONArray(resource);
-                if (labels.isEmpty() || labels == null) {
-                    continue;
+        Map<String, List<String>> uiLabelMap = new HashMap<String, List<String>>();
+        Set<Map.Entry<String, List<String>>> entrySet = uiLabelObject.entrySet();
+        for (Map.Entry<String, List<String>> entry : entrySet) {
+            String resource = entry.getKey();
+            List<String> resourceKeys = entry.getValue();
+            if (resourceKeys != null) {
+                List<String> labels = new ArrayList<String>(resourceKeys.size());
+                for (String resourceKey : resourceKeys) {
+                    String label = UtilProperties.getMessage(resource, resourceKey, locale);
+                    labels.add(label);
                 }
-
-                // Iterate over the uiLabel List
-                Iterator<String> jsonLabelIterator = UtilGenerics.cast(labels.iterator());
-                JSONArray resourceLabelList = new JSONArray();
-                while(jsonLabelIterator.hasNext()) {
-                    String label = jsonLabelIterator.next();
-                    String receivedLabel = UtilProperties.getMessage(resource, label, locale);
-                    if (UtilValidate.isNotEmpty(receivedLabel)) {
-                        resourceLabelList.add(receivedLabel);
-                    }
-                }
-                jsonUiLabel.element(resource, resourceLabelList);
+                uiLabelMap.put(resource, labels);
             }
         }
-
-        writeJSONtoResponse(jsonUiLabel, request.getMethod(), response);
+        writeJSONtoResponse(JSON.from(uiLabelMap), request.getMethod(), response);
         return "success";
     }
 
-    public static String getJSONuiLabel(HttpServletRequest request, HttpServletResponse response) {
-        String requiredLabels = request.getParameter("requiredLabel");
-
-        JSONObject uiLabelObject = null;
-        if (UtilValidate.isNotEmpty(requiredLabels)) {
-            // Transform JSON String to Object
-            uiLabelObject = (JSONObject) JSONSerializer.toJSON(requiredLabels);
+    public static String getJSONuiLabel(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException, IOException {
+        // Format - {resource : key}
+        String jsonString = request.getParameter("requiredLabel");
+        Map<String, String> uiLabelObject = null;
+        if (UtilValidate.isNotEmpty(jsonString)) {
+            JSON json = JSON.from(jsonString);
+            uiLabelObject = UtilGenerics.<Map<String, String>>cast(json.toObject(Map.class));
         }
-
-        JSONArray jsonUiLabel = new JSONArray();
+        if (UtilValidate.isEmpty(uiLabelObject)) {
+            Debug.logError("No resource and labels found in JSON string: " + jsonString, module);
+            return "error";
+        } else if (uiLabelObject.size() > 1) {
+            Debug.logError("More than one resource found, please use the method: getJSONuiLabelArray", module);
+            return "error";
+        }
         Locale locale = request.getLocale();
-        if(!uiLabelObject.isEmpty()) {
-            Set<String> resourceSet = UtilGenerics.checkSet(uiLabelObject.keySet());
-            // Iterate over the resource set
-            // here we need a keySet because we don't now which label resource to load
-            // the key set should have the size one, if greater or empty error should returned
-            if (UtilValidate.isEmpty(resourceSet)) {
-                Debug.logError("No resource and labels found", module);
-                return "error";
-            } else if (resourceSet.size() > 1) {
-                Debug.logError("More than one resource found, please use the method: getJSONuiLabelArray", module);
-                return "error";
-            }
-
-            for (String resource : resourceSet) {
-                String label = uiLabelObject.getString(resource);
-                if (UtilValidate.isEmail(label)) {
-                    continue;
-                }
-
-                String receivedLabel = UtilProperties.getMessage(resource, label, locale);
-                jsonUiLabel.add(receivedLabel);
+        Map<String, String> uiLabelMap = new HashMap<String, String>();
+        Set<Map.Entry<String, String>> entrySet = uiLabelObject.entrySet();
+        for (Map.Entry<String, String> entry : entrySet) {
+            String resource = entry.getKey();
+            String resourceKey = entry.getValue();
+            if (resourceKey != null) {
+                String label = UtilProperties.getMessage(resource, resourceKey, locale);
+                uiLabelMap.put(resource, label);
             }
         }
-
-        writeJSONtoResponse(jsonUiLabel, request.getMethod(), response);
+        writeJSONtoResponse(JSON.from(uiLabelMap), request.getMethod(), response);
         return "success";
     }
 
diff --git a/framework/entity/src/org/ofbiz/entity/sql/SQLUtil.java b/framework/entity/src/org/ofbiz/entity/sql/SQLUtil.java
deleted file mode 100644
index 44668ce..0000000
--- a/framework/entity/src/org/ofbiz/entity/sql/SQLUtil.java
+++ /dev/null
@@ -1,46 +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.entity.sql;
-
-import java.io.StringReader;
-
-import org.ofbiz.sql.OrderByItem;
-import org.ofbiz.sql.ParseException;
-import org.ofbiz.sql.Parser;
-
-public class SQLUtil {
-    private static final EntityPlanner planner = new EntityPlanner();
-
-    private static Parser updateParserFlags(Parser parser) {
-        return parser.deleteSupportsUsing(false).updateSupportsFrom(false);
-    }
-
-    public static EntitySelectPlan parseSelect(String sql) throws ParseException {
-       return planner.planSelect(updateParserFlags(new Parser(new StringReader(sql))).SelectStatement());
-    }
-
-    public static OrderByItem parseOrderByItem(String sql) throws ParseException {
-       return updateParserFlags(new Parser(new StringReader(sql))).OrderByItem();
-    }
-    /*
-    public static EntityCondition parseCondition(String condition) throws ParseException {
-        return new Parser(new StringReader(condition)).EntityCondition();
-    }
-    */
-}
diff --git a/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java b/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java
index fac34fb..e570452 100644
--- a/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java
+++ b/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java
@@ -37,7 +37,9 @@
 import javax.sql.rowset.serial.SerialBlob;
 
 import org.ofbiz.base.concurrent.ExecutionPool;
+import org.ofbiz.base.lang.JSON;
 import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.ObjectType;
 import org.ofbiz.base.util.Observable;
 import org.ofbiz.base.util.Observer;
 import org.ofbiz.base.util.UtilDateTime;
@@ -1209,6 +1211,23 @@
         assertTrue("One big transaction was not faster than several small ones", totalTimeOneTransaction < totalTimeSeveralSmallTransactions);
     }
 
+    public void testConverters() throws Exception {
+        // Must use the default delegator because the deserialized GenericValue can't
+        // find the randomized one.
+        Delegator localDelegator = DelegatorFactory.getDelegator("default");
+        GenericValue testValue = localDelegator.create("Testing", "testingId", "JSON_TEST", "testingTypeId", "TEST-UPDATE-1",
+                "description", "Testing JSON Converters", "testingSize", (long) 123, "testingDate",
+                new Timestamp(System.currentTimeMillis()));
+        assertNotNull("Created GenericValue not null", testValue);
+        JSON json = (JSON) ObjectType.simpleTypeConvert(testValue, "org.ofbiz.base.lang.JSON", null, null);
+        assertNotNull("JSON instance not null", json);
+        GenericValue convertedValue = (GenericValue) ObjectType.simpleTypeConvert(json, "org.ofbiz.entity.GenericValue", null,
+                null);
+        assertNotNull("GenericValue converted from JSON not null", convertedValue);
+        assertEquals("GenericValue converted from JSON equals original value", testValue, convertedValue);
+        testValue.remove();
+    }
+
     private final class TestObserver implements Observer {
         private Observable observable;
         private Object arg;
diff --git a/framework/entity/src/org/ofbiz/entity/util/Converters.java b/framework/entity/src/org/ofbiz/entity/util/Converters.java
index aabf825..cb269cd 100644
--- a/framework/entity/src/org/ofbiz/entity/util/Converters.java
+++ b/framework/entity/src/org/ofbiz/entity/util/Converters.java
@@ -18,19 +18,79 @@
  *******************************************************************************/
 package org.ofbiz.entity.util;
 
+import java.io.IOException;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.ofbiz.base.conversion.AbstractConverter;
 import org.ofbiz.base.conversion.ConversionException;
 import org.ofbiz.base.conversion.ConverterLoader;
+import org.ofbiz.base.lang.JSON;
+import org.ofbiz.base.util.ObjectType;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.DelegatorFactory;
 import org.ofbiz.entity.GenericEntity;
 import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.model.ModelField;
+import org.ofbiz.entity.model.ModelFieldType;
 
 /** Entity Engine <code>Converter</code> classes. */
 public class Converters implements ConverterLoader {
+
+    public static class JSONToGenericValue extends AbstractConverter<JSON, GenericValue> {
+        public JSONToGenericValue() {
+            super(JSON.class, GenericValue.class);
+        }
+
+        public GenericValue convert(JSON obj) throws ConversionException {
+            Map<String, Object> fieldMap;
+            try {
+                fieldMap = UtilGenerics.<Map<String, Object>>cast(obj.toObject(Map.class));
+                String delegatorName = (String) fieldMap.remove("_DELEGATOR_NAME_");
+                String entityName = (String) fieldMap.remove("_ENTITY_NAME_");
+                if (delegatorName == null || entityName == null) {
+                    throw new ConversionException("Invalid JSON object");
+                }
+                Delegator delegator = DelegatorFactory.getDelegator(delegatorName);
+                GenericValue value = delegator.makeValue(entityName);
+                for (Map.Entry<String, Object> entry : fieldMap.entrySet()) {
+                    String fieldName = entry.getKey();
+                    Object fieldValue = entry.getValue();
+                    ModelField field = value.getModelEntity().getField(fieldName);
+                    ModelFieldType type = delegator.getEntityFieldType(value.getModelEntity(), field.getType());
+                    value.set(fieldName, ObjectType.simpleTypeConvert(fieldValue, type.getJavaType(), null, null));
+                }
+                return value;
+            } catch (ConversionException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new ConversionException(e);
+            }
+        }
+    }
+
+    public static class GenericValueToJSON extends AbstractConverter<GenericValue, JSON> {
+        public GenericValueToJSON() {
+            super(GenericValue.class, JSON.class);
+        }
+
+        public JSON convert(GenericValue obj) throws ConversionException {
+            Map<String, Object> fieldMap = new HashMap<String, Object>(obj);
+            fieldMap.put("_DELEGATOR_NAME_", obj.getDelegator().getDelegatorName());
+            fieldMap.put("_ENTITY_NAME_", obj.getEntityName());
+            try {
+                return JSON.from(fieldMap);
+            } catch (IOException e) {
+                throw new ConversionException(e);
+            }
+        }
+    }
+
     public static class GenericValueToList extends AbstractConverter<GenericValue, List<GenericValue>> {
         public GenericValueToList() {
             super(GenericValue.class, List.class);
diff --git a/framework/sql/build.xml b/framework/sql/build.xml
index 6b5aef7..baa8300 100644
--- a/framework/sql/build.xml
+++ b/framework/sql/build.xml
@@ -45,11 +45,8 @@
         <file name="org/ofbiz/sql/test/ValuesTest.java"/>
         <file name="org/ofbiz/sql/test/ConditionsTest.java"/>
         <file name="org/ofbiz/sql/test/SelectTest.java"/>
-        <file name="org/ofbiz/sql/test/SQLTest.java"/>
     </filelist>
     <patternset id="cobertura-src-dirs">
-        <include name="build/gen-src/javacc"/>
-        <include name="build/gen-src/jjtree"/>
         <include name="src"/>
     </patternset>
 
@@ -57,21 +54,6 @@
     <!-- Compilation of the source files                                                                                                                         -->
     <!-- ================================================================== -->
 
-    <target name="gen-src">
-        <ofbiz-javacc dir="org/ofbiz/sql" file="Parser"/>
-    </target>
-
-    <target name="classes" depends="prepare,gen-src">
-        <javac17>
-            <sourcepath>
-                <dirset dir="build/gen-src">
-                    <include name="javacc"/>
-                    <include name="jjtree"/>
-                </dirset>
-            </sourcepath>
-        </javac17>
-    </target>
-
     <target name="jar" depends="classes">
         <main-jar/>
         <test-jar/>
@@ -83,10 +65,6 @@
 
     <target name="docs" depends="prepare-docs">
         <default-javadoc>
-            <fileset dir="build/gen-src/javacc" defaultexcludes="yes">
-                <patternset refid="src.inc.set"/>
-                <patternset refid="src.exc.set"/>
-            </fileset>
             <fileset dir="${src.dir}" defaultexcludes="yes">
                 <patternset refid="src.inc.set"/>
                 <patternset refid="src.exc.set"/>
diff --git a/framework/sql/src/org/ofbiz/sql/Main.java b/framework/sql/src/org/ofbiz/sql/Main.java
deleted file mode 100644
index c27e7ff..0000000
--- a/framework/sql/src/org/ofbiz/sql/Main.java
+++ /dev/null
@@ -1,102 +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.sql;
-
-import java.util.List;
-import java.util.Map;
-
-public final class Main {
-    public static void main(String[] args) throws Exception {
-        Planner<?, ?, ?, ?, ?, ?, ?> planner = new DebugPlanner();
-        List<SQLStatement<?>> statements = new Parser(System.in).SQLFile();
-        for (SQLStatement<?> statement: statements) {
-            run(statement, planner);
-        }
-    }
-
-    private static final void run(SQLStatement<?> statement, Planner<?, ?, ?, ?, ?, ?, ?> planner) {
-        System.err.println(statement);
-        SQLPlan<?> plan = planner.plan(statement);
-        System.err.println("\tplan=" + plan);
-    }
-
-    private final static class DebugPlanner extends Planner<DebugPlanner, DebugCondition, DebugDeletePlan, DebugInsertPlan, DebugSelectPlan, DebugUpdatePlan, DebugViewPlan> {
-        public DebugPlanner() {
-            super(new DebugConditionPlanner());
-        }
-
-        @Override
-        public DebugDeletePlan planDelete(SQLDelete deleteStatement) {
-            return null;
-        }
-
-        @Override
-        public DebugInsertPlan planInsert(SQLInsert insertStatement) {
-            return null;
-        }
-
-        @Override
-        public DebugSelectPlan planSelect(SQLSelect selectStatement) {
-            return null;
-        }
-
-        @Override
-        public DebugUpdatePlan planUpdate(SQLUpdate updateStatement) {
-            return null;
-        }
-
-        @Override
-        public DebugViewPlan planView(SQLView viewStatement) {
-            return null;
-        }
-    }
-
-    private final static class DebugConditionPlanner implements ConditionPlanner<DebugCondition> {
-        public DebugCondition parse(Condition originalCondition, Map<String, ? extends Object> params) throws ParameterizedConditionException {
-            return null;
-        }
-    }
-
-    private final static class DebugCondition {
-    }
-
-    private final static class DebugDeletePlan extends DeletePlan<DebugDeletePlan, DebugCondition> {
-        protected DebugDeletePlan(ConditionPlan<DebugCondition> wherePlan) {
-            super(wherePlan);
-        }
-    }
-
-    private final static class DebugInsertPlan extends InsertPlan<DebugInsertPlan> {
-    }
-
-    private final static class DebugSelectPlan extends SelectPlan<DebugSelectPlan, DebugCondition> {
-        protected DebugSelectPlan(ConditionPlan<DebugCondition> wherePlan, ConditionPlan<DebugCondition> havingPlan) {
-            super(wherePlan, havingPlan);
-        }
-    }
-
-    private final static class DebugUpdatePlan extends UpdatePlan<DebugUpdatePlan, DebugCondition> {
-        protected DebugUpdatePlan(ConditionPlan<DebugCondition> wherePlan) {
-            super(wherePlan);
-        }
-    }
-
-    private final static class DebugViewPlan extends ViewPlan<DebugViewPlan> {
-    }
-}
diff --git a/framework/sql/src/org/ofbiz/sql/Parser.jj b/framework/sql/src/org/ofbiz/sql/Parser.jj
deleted file mode 100644
index 19db7e7..0000000
--- a/framework/sql/src/org/ofbiz/sql/Parser.jj
+++ /dev/null
@@ -1,928 +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.
- */
-options {
-    JAVA_UNICODE_ESCAPE = false;
-    ERROR_REPORTING = true;
-    STATIC = false;
-//  MULTI = true;
-    JDK_VERSION = "1.5";
-//  VISITOR = true;
-//  BUILD_NODE_FILES = true;
-//  NODE_FACTORY = false;
-//  NODE_USES_PARSER = true;
-//  NODE_SCOPE_HOOK = true;
-//  NODE_PREFIX = "SQL";
-//  DEBUG_PARSER = true;
-//  DEBUG_LOOKAHEAD = true;
-//  DEBUG_TOKEN_MANAGER = true;
-    LOOKAHEAD = 1;
-//  CHOICE_AMBIGUITY_CHECK = 3;
-//  OTHER_AMBIGUITY_CHECK = 3;
-    IGNORE_CASE = true;
-}
-PARSER_BEGIN(Parser)
-
-package org.ofbiz.sql;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javolution.util.FastList;
-import javolution.util.FastMap;
-import javolution.util.FastSet;
-
-@SuppressWarnings("all")
-public final class Parser {
-    private boolean deleteSupportsUsing = true;
-    private boolean updateSupportsFrom = true;
-
-    public Parser deleteSupportsUsing(boolean value) {
-        deleteSupportsUsing = value;
-        return this;
-    }
-
-    public Parser updateSupportsFrom(boolean value) {
-        updateSupportsFrom = value;
-        return this;
-    }
-
-    private Condition reduce(List<Condition> conditions, Joiner joiner) {
-        if (conditions.size() == 1) {
-            return conditions.get(0);
-        }
-        return new ConditionList(joiner, conditions);
-    }
-}
-
-PARSER_END(Parser)
-TOKEN_MGR_DECLS: {
-    private final FastList<Integer> stack = new FastList<Integer>();
-
-    void pushState(int newState) {
-        stack.add(curLexState);
-        SwitchTo(newState);
-    }
-
-    void popState() {
-        SwitchTo(stack.removeLast());
-    }
-}
-
-TOKEN: {
-      <OPEN_PAREN: "(">
-    | <CLOSE_PAREN: ")">
-    | <AND: "AND">
-    | <OR: "OR">
-    | <PERIOD: ".">
-    | <JOIN: "JOIN">
-    | <LEFT: "LEFT">
-    | <AS: "AS">
-    | <COUNT: "COUNT">
-    | <MAX: "MAX">
-    | <MIN: "MIN">
-    | <SUM: "SUM">
-    | <AVG: "AVG">
-    | <DISTINCT: "DISTINCT">
-    | <WHERE: "WHERE">
-    | <HAVING: "HAVING">
-    | <GROUP: "GROUP">
-    | <ORDER: "ORDER">
-    | <INTERSECT: "INTERSECT">
-    | <EXCEPT: "EXCEPT">
-    | <UNION: "UNION">
-    | <ALL: "ALL">
-    | <BY: "BY">
-    | <ON: "ON">
-    | <USING: "USING">
-    | <LIMIT: "LIMIT">
-    | <OFFSET: "OFFSET">
-    | <SELECT: "SELECT">
-    | <DELETE: "DELETE">
-    | <UPDATE: "UPDATE">
-    | <INSERT: "INSERT">
-    | <INDEX: "INDEX">
-    | <UNIQUE: "UNIQUE">
-    | <RELATION: "RELATION">
-    | <EXCLUDE: "EXCLUDE">
-    | <TYPE: "TYPE">
-    | <TITLE: "TITLE">
-    | <SET: "SET">
-    | <FROM: "FROM">
-    | <SEMI: ";">
-    | <STAR: "*">
-    | <COMMA: ",">
-    | <PLUS: "+">
-    | <MINUS: "-">
-    | <DESC: "DESC">
-    | <ASC: "ASC">
-    | <EQUALS: "=">
-    | <BETWEEN: "BETWEEN">
-    | <INTO: "INTO">
-    | <VALUES: "VALUES">
-    | <CREATE: "CREATE">
-    | <VIEW: "VIEW">
-    | <IS: "IS">
-    | <NOT: "NOT">
-    | <NULL: "NULL">
-    | <MAP: "MAP">
-    | <NULLS: "NULLS">
-    | <FIRST: "FIRST">
-    | <LAST: "LAST">
-    | <START_DQUOTE: "\""> { pushState(IN_DQUOTE); }
-    | <START_SQUOTE: "'"> { pushState(IN_SQUOTE); }
-    | <INTEGER:
-        "0" (
-            "x" (["0"-"9","a"-"b"])+
-            | (["0"-"7"])+
-        )
-        | ["1"-"9"] (["0"-"9"])*
-    >
-    | <NAME: ["a"-"z"] (["a"-"z","0"-"9","_","-"])*>
-    | <PARAMETER: "?" (["a"-"z"])+>
-//  | <WORD: (~["'", "\"", "/", " ", "\f", "\n", "\r", "\t", "*"])+>
-}
-
-<DEFAULT>
-SKIP: {
-    <SPACE: " " | "\f" | "\n" | "\r" | "\t">
-}
-
-<*>
-MORE: {
-    <COMMENT_START: "/*"> { if (curLexState != IN_COMMENT) pushState(IN_COMMENT); }
-}
-
-<IN_COMMENT>
-MORE: {
-      <(~[])>
-    | <COMMENT_END: "*/"> { popState(); }
-}
-
-<IN_DQUOTE,IN_SQUOTE>
-TOKEN: {
-    <ESCAPED: "\\" ["r", "n", "b", "t", "f"]>
-}
-
-<IN_DQUOTE>
-TOKEN: {
-    <END_DQUOTE: "\""> { popState(); }
-}
-
-<IN_SQUOTE>
-TOKEN: {
-      <ESCAPE_SQUOTE: "''">
-    | <END_SQUOTE: "'"> { popState(); }
-}
-
-<DEFAULT,IN_DQUOTE,IN_SQUOTE>
-TOKEN: {
-    <TEXT: (~[])>
-}
-
-// -------------------
-
-public List<SQLStatement<?>> SQLFile(): {
-    List<SQLStatement<?>> list = FastList.newInstance();
-    SQLStatement<?> statement;
-} {
-    (
-        statement=Statement() ( <SEMI> )?
-        { list.add(statement); }
-    )*
-    <EOF>
-    { return list; }
-}
-
-public SQLStatement StandaloneStatement(): {
-    SQLStatement statement;
-} {
-    statement=Statement() ( <SEMI> )? <EOF>
-    { return statement; }
-}
-
-public SQLView ViewStatement(): {
-    SQLView sqlView;
-} {
-    <CREATE> <VIEW> sqlView=View() ( <SEMI> )? <EOF>
-    { return sqlView; }
-}
-
-public SQLSelect SelectStatement(): {
-    SQLSelect sqlSelect;
-} {
-    sqlSelect=Select() ( <SEMI> )? <EOF> { return sqlSelect; }
-}
-
-public SQLDelete DeleteStatement(): {
-    SQLDelete sqlDelete;
-} {
-    sqlDelete=Delete() ( <SEMI> )? <EOF> { return sqlDelete; }
-}
-
-public SQLUpdate UpdateStatement(): {
-    SQLUpdate sqlUpdate;
-} {
-    sqlUpdate=Update() ( <SEMI> )? <EOF> { return sqlUpdate; }
-}
-
-public SQLInsert InsertStatement(): {
-    SQLInsert sqlInsert;
-} {
-    sqlInsert=Insert() ( <SEMI> )? <EOF> { return sqlInsert; }
-}
-
-public Condition Condition(): {
-    Condition c;
-} {
-    c=ConditionExpression() <EOF> { return c; }
-}
-
-public FieldAll parse_FieldAll(): {
-    FieldAll fieldAll;
-} {
-    fieldAll=FieldAll() <EOF> { return fieldAll; }
-}
-
-public FieldDef parse_FieldDef(): {
-    FieldDef fieldDef;
-} {
-    fieldDef=FieldDef() <EOF> { return fieldDef; }
-}
-
-public OrderByItem parse_OrderByItem(): {
-    OrderByItem item;
-} {
-    item=OrderByItem() <EOF> { return item; }
-}
-
-private SQLStatement Statement(): {
-    SQLStatement statement;
-} {
-    (
-          statement=Select() { return statement; }
-        | statement=Delete() { return statement; }
-        | statement=Update() { return statement; }
-        | statement=Insert() { return statement; }
-        | statement=Creates() { return statement; }
-    )
-}
-
-private SQLStatement Creates(): {
-    SQLStatement statement;
-    boolean isUnique = false;
-} {
-    <CREATE> (
-          <VIEW> statement=View() { return statement; }
-        | ( <UNIQUE> { isUnique = true; } )?
-          <INDEX> statement=Index(isUnique) { return statement; }
-    )
-}
-
-private SQLView View(): {
-    String name;
-    SQLSelect sqlSelect;
-} {
-    name=NamePart() <AS> sqlSelect=Select() { return new SQLView(name, sqlSelect); }
-}
-
-private SelectGroup SelectGroup(): {
-    boolean isDistinct = false;
-    List<String> groupBy = null;
-    Map<String, FieldDef> fieldDefs = FastMap.newInstance();
-    List<FieldAll> fieldAlls = FastList.newInstance();
-    Set<String> fieldAllAliases = FastSet.newInstance();
-    Table table;
-    Condition whereCondition = null, havingCondition = null;
-} {
-    <SELECT> (<DISTINCT> { isDistinct = true; })? (
-        SelectField(fieldDefs, fieldAlls, fieldAllAliases)
-        ( <COMMA> SelectField(fieldDefs, fieldAlls, fieldAllAliases) )*
-    )
-    <FROM> table=Table()
-    ( <WHERE> whereCondition=ConditionExpression() )?
-    ( <HAVING> havingCondition=ConditionExpression() )?
-    ( <GROUP> <BY> groupBy=FieldList() )?
-    { return new SelectGroup(isDistinct, fieldAlls, fieldDefs, table, whereCondition, havingCondition, groupBy); }
-}
-
-private Unioned.Operator UnionOperator(): {
-} {
-      <UNION>
-      ( <ALL> { return Unioned.Operator.UNION_ALL; } )?
-      { return Unioned.Operator.UNION; }
-    | <INTERSECT>
-      ( <ALL> { return Unioned.Operator.INTERSECT_ALL; } )?
-      { return Unioned.Operator.INTERSECT; }
-    | <EXCEPT>
-      ( <ALL> { return Unioned.Operator.EXCEPT_ALL; } )?
-      { return Unioned.Operator.EXCEPT; }
-}
-
-private Unioned Unioned(): {
-    Unioned.Operator operator;
-    SelectGroup selectGroup;
-    Unioned next = null;
-} {
-    operator=UnionOperator() selectGroup=SelectGroup() ( next=Unioned() )?
-    { return new Unioned(operator, selectGroup, next); }
-}
-
-private SQLSelect Select(): {
-    boolean hadEarlyRelations = false;
-    Unioned unioned = null;
-    boolean isDistinct = false;
-    List<OrderByItem> orderBy = null;
-    List<String> groupBy = null;
-    Map<String, FieldDef> fieldDefs = FastMap.newInstance();
-    List<FieldAll> fieldAlls = FastList.newInstance();
-    Set<String> fieldAllAliases = FastSet.newInstance();
-    Table table;
-    Map<String, Relation> relations = FastMap.newInstance();
-    Condition whereCondition = null, havingCondition = null;
-    int offset = -1, limit = -1;
-} {
-    <SELECT> (<DISTINCT> { isDistinct = true; })? (
-        SelectField(fieldDefs, fieldAlls, fieldAllAliases)
-        ( <COMMA> SelectField(fieldDefs, fieldAlls, fieldAllAliases) )*
-    )
-    <FROM> table=Table()
-    ( LOOKAHEAD(1) <RELATION> Relation(relations) { hadEarlyRelations = true; } )*
-    ( <WHERE> whereCondition=ConditionExpression() )?
-    ( <HAVING> havingCondition=ConditionExpression() )?
-    ( <GROUP> <BY> groupBy=FieldList() )?
-    ( unioned=Unioned() )?
-    ( LOOKAHEAD(1, {!hadEarlyRelations}) <RELATION> Relation(relations) )*
-    ( <ORDER> <BY> orderBy=OrderByList() )?
-    ( <OFFSET> offset=Integer() )?
-    ( <LIMIT> limit=Integer() )?
-    { return new SQLSelect(new SelectGroup(isDistinct, fieldAlls, fieldDefs, table, whereCondition, havingCondition, groupBy), unioned, relations, orderBy, offset, limit); }
-}
-
-private void Relation(Map<String, Relation> relations): {
-    String type = null, title = null, entityName;
-    KeyMap keyMap;
-    List<KeyMap> keyMaps = FastList.newInstance();
-} {
-    ( <TYPE> type=NamePart() )?
-    ( <TITLE> title=NamePart() )?
-    <NAME> { entityName = getToken(0).image; }
-    <MAP> keyMap=PlainKeyMap() { keyMaps.add(keyMap); } (
-        <COMMA>
-        keyMap=PlainKeyMap() { keyMaps.add(keyMap); }
-    )*
-    {
-        Relation relation = new Relation(type, title, entityName, keyMaps);
-        if (relations.containsKey(relation.getName())) throw new ParseException("Duplicate relation: " + relation);
-        relations.put(relation.getName(), relation);
-    }
-}
-
-private KeyMap PlainKeyMap(): {
-    String left, right;
-} {
-    left=NamePart() (
-          <EQUALS> right=NamePart() { return new KeyMap(left, right); }
-        | { return new KeyMap(left, left); }
-    )
-}
-
-private SQLUpdate Update(): {
-    TableName tableName;
-    List<Table> tableList = null;
-    Condition whereCondition = null;
-    List<SetField> allSetFields = FastList.newInstance();
-    List<SetField> setFields;
-    Joined joined = null;
-} {
-    <UPDATE> tableName=TableName()
-    <SET>
-    setFields=SetField() { allSetFields.addAll(setFields); }
-    ( <COMMA> setFields=SetField() { allSetFields.addAll(setFields); } )*
-    ( LOOKAHEAD(<FROM>, {updateSupportsFrom}) <FROM> joined=JoinedRest(false, tableName) )?
-    ( <WHERE> whereCondition=ConditionExpression() )?
-    { return new SQLUpdate(new Table(tableName, joined), allSetFields, whereCondition); }
-}
-
-private SQLDelete Delete(): {
-    TableName tableName;
-    List<Table> tableList = null;
-    Condition whereCondition = null;
-    Joined joined = null;
-} {
-    <DELETE> <FROM> tableName=TableName()
-    ( LOOKAHEAD(<USING>, {deleteSupportsUsing}) <USING> joined=JoinedRest(false, tableName) )?
-    ( <WHERE> whereCondition=ConditionExpression() )?
-    { return new SQLDelete(new Table(tableName, joined), whereCondition); }
-}
-
-private SQLIndex Index(boolean isUnique): {
-    String name, table, using = null;
-    ConstantValue value;
-    List<ConstantValue> values = FastList.newInstance();
-} {
-    name=NamePart() <ON> table=NamePart()
-    ( <USING> using=NamePart() )?
-    <OPEN_PAREN>
-    value=ConstantValue() { values.add(value); }
-    ( <COMMA> value=ConstantValue() { values.add(value); } )*
-    <CLOSE_PAREN>
-    { return new SQLIndex(isUnique, name, table, using, values); }
-}
-
-private SQLInsert Insert(): {
-    TableName tableName;
-    List<String> columns = FastList.newInstance();
-    String n;
-    InsertSource source;
-} {
-    <INSERT> <INTO> tableName=TableName() (
-        <OPEN_PAREN>
-        n=NamePart() { columns.add(n); }
-        ( <COMMA> n=NamePart() { columns.add(n); } )*
-        <CLOSE_PAREN>
-    )?
-    ( source=InsertValues() | source=Select() )
-    { return new SQLInsert(tableName, source, columns); }
-}
-
-private InsertValues InsertValues(): {
-    List<InsertRow> list = FastList.newInstance();
-    InsertRow row;
-} {
-    <VALUES>
-    row=InsertRow() { list.add(row); }
-    ( <COMMA> row=InsertRow() { list.add(row); } )*
-    { return new InsertValues(list); }
-}
-
-private InsertRow InsertRow(): {
-    List<Value> list = FastList.newInstance();
-    Value v;
-} {
-    <OPEN_PAREN>
-    v=InsertValue() { list.add(v); }
-    ( <COMMA> v=InsertValue() { list.add(v); } )*
-    <CLOSE_PAREN>
-    { return new InsertRow(list); }
-}
-
-private Value InsertValue(): {
-    Value v;
-    Integer i;
-    String s;
-} {
-      v=ParameterValue() { return v; }
-    | i=Integer() { return new NumberValue<Integer>(i); }
-    | s=SQuoted() { return new StringValue(s); }
-}
-
-private List<SetField> SetField(): {
-    List<SetField> setFields = FastList.newInstance();
-    String n;
-    Value v;
-    List<String> columnList = FastList.newInstance();
-    List<Value> valueList = FastList.newInstance();
-} {
-    (
-          n=NamePart() <EQUALS> (
-              v=Value() { setFields.add(new SetField(n, v)); }
-            | v=MathValue() { setFields.add(new SetField(n, v)); }
-          )
-        | <OPEN_PAREN>
-          n=NamePart() { columnList.add(n); }
-          ( <COMMA> n=NamePart() { columnList.add(n); } )*
-          <CLOSE_PAREN>
-          <EQUALS>
-          <OPEN_PAREN>
-          ( v=Value() | v=MathValue() ) { valueList.add(v); }
-          ( <COMMA> (v=Value()|v=MathValue()) { valueList.add(v); } )*
-          <CLOSE_PAREN> {
-            if (columnList.size() != valueList.size()) throw new ParseException();
-            for (int i = 0; i < columnList.size(); i++) {
-                setFields.add(new SetField(columnList.get(i), valueList.get(i)));
-            }
-          }
-    )
-    { return setFields; }
-}
-
-private Table Table(): {
-    TableName tableName;
-    Joined joined = null;
-} {
-    tableName=TableName()
-    ( joined=Joined(tableName) )?
-    { return new Table(tableName, joined); }
-}
-
-private Joined Joined(TableName leftTableName): {
-    Boolean isOptional;
-    Joined joined = null;
-} {
-    isOptional=Joiner() joined=JoinedRest(isOptional, leftTableName)
-    { return joined; }
-}
-
-private Joined JoinedRest(boolean isOptional, TableName leftTableName): {
-    TableName rightTableName;
-    List<KeyMap> keyMaps;
-    Joined joined = null;
-} {
-    rightTableName=TableName()
-    keyMaps=KeyMaps(leftTableName.getAlias(), rightTableName.getAlias())
-    ( joined=Joined(rightTableName) )?
-    { return new Joined(isOptional, rightTableName, keyMaps, joined); }
-}
-
-private List<KeyMap> KeyMaps(String leftAlias, String rightAlias): {
-    List<KeyMap> keyMaps = FastList.newInstance();
-    String n;
-} {
-    (
-          <ON>
-          KeyMap(keyMaps, leftAlias, rightAlias)
-          ( <AND> KeyMap(keyMaps, leftAlias, rightAlias) )*
-        | <USING>
-          n=NamePart() { keyMaps.add(new KeyMap(n, n)); }
-          ( <COMMA> n=NamePart() { keyMaps.add(new KeyMap(n, n)); } )*
-    )
-    { return keyMaps; }
-}
-
-private void KeyMap(List<KeyMap> keyMaps, String leftAlias, String rightAlias): {
-    String alias1, field1;
-    String alias2, field2;
-} {
-    alias1=NamePart() <PERIOD> field1=NamePart()
-    <EQUALS>
-    alias2=NamePart() <PERIOD> field2=NamePart() {
-        if (alias1.equals(leftAlias)) {
-            if (!alias2.equals(rightAlias)) throw new ParseException("invalid right alias(" + alias2 + "), expected(" + rightAlias + ")");
-            keyMaps.add(new KeyMap(field1, field2));
-        } else if (alias1.equals(rightAlias)) {
-            if (!alias2.equals(leftAlias)) throw new ParseException("invalid left alias(" + alias2 + "), expected(" + leftAlias + ")");
-            keyMaps.add(new KeyMap(field2, field1));
-        } else {
-            throw new ParseException("invalid aliases, expected(" + leftAlias + " or " + rightAlias + ")");
-        }
-    }
-}
-
-private TableName TableName(): {
-    String tableName, alias = null;
-} {
-    tableName=NamePart()
-    ( ( <AS> )? alias=NamePart() )?
-    { return new TableName(tableName, alias); }
-}
-
-private Boolean Joiner(): {
-} {
-      <LEFT> <JOIN> { return Boolean.TRUE; }
-    | <JOIN> { return Boolean.FALSE; }
-}
-
-private void SelectField(Map<String, FieldDef> fieldDefs, List<FieldAll> fieldAlls, Set<String> fieldAllAliases): {
-    FieldAll fieldAll;
-    FieldDef fieldDef;
-} {
-      LOOKAHEAD(3) fieldAll=FieldAll() {
-        if (fieldAllAliases.contains(fieldAll.getAlias())) throw new ParseException("Duplicate aliasAll(" + fieldAll.getAlias() + ")");
-        fieldAlls.add(fieldAll); return;
-      }
-    | fieldDef=FieldDef() {
-        if (fieldDefs.containsKey(fieldDef.getDefaultName())) throw new ParseException("duplicate alias(" + fieldDef.getDefaultName() + ")");
-        fieldDefs.put(fieldDef.getDefaultName(), fieldDef);
-    }
-}
-
-private FieldAll FieldAll(): {
-    String n, exc;
-    Set<String> excludeList = FastSet.newInstance();
-} {
-    n=NamePart() <PERIOD> <STAR> (
-        <EXCLUDE> <OPEN_PAREN>
-        exc=NamePart() { excludeList.add(exc); }
-        ( <COMMA> exc=NamePart() { excludeList.add(exc); } )*
-        <CLOSE_PAREN>
-    )?
-    { return new FieldAll(n, excludeList); }
-}
-
-private StaticValue StaticValue(): {
-    StaticValue v;
-    String n, fieldName;
-} {
-    (
-          n=NamePart() (
-              <PERIOD> fieldName=NamePart() { v = new FieldValue(n, fieldName); }
-            | v=FunctionCallRest(n)
-            | { v = new FieldValue(null, n); }
-          )
-        | v=MathValue()
-        | LOOKAHEAD(5) v=CountAll()
-        | v=AggregateFunction()
-    ) { return v; }
-}
-
-private FieldDef FieldDef(): {
-    StaticValue v;
-    String fieldAlias = null;
-} {
-    v=StaticValue() ( <AS> fieldAlias=NamePart() )? {
-        return new FieldDef(v, fieldAlias);
-    }
-}
-
-private CountAllFunction CountAll(): {
-    String n;
-} {
-    <COUNT> <OPEN_PAREN> (
-          n=NamePart()
-        | { n = null; }
-    ) <PERIOD> <STAR> <CLOSE_PAREN>
-    { return new CountAllFunction(n); }
-}
-
-private StaticValue MathValue(): {
-    ConstantValue v;
-    List<ConstantValue> values = FastList.newInstance();
-    String operator = null, newOperator;
-} {
-    <OPEN_PAREN> v=ConstantValue() { values.add(v); } (
-        newOperator=MathOperator() v=ConstantValue() {
-            if (operator == null) {
-                operator = newOperator;
-            } else if (!newOperator.equals(operator)) {
-                throw new ParseException("Different operators in complex alias(" + operator + ":" + newOperator + ")");
-            }
-            values.add(v);
-        }
-    )*
-    <CLOSE_PAREN> {
-        if (values.size() == 1 && values.get(0) instanceof StaticValue) return (StaticValue) values.get(0);
-        return new MathValue(operator, values);
-    }
-}
-
-private AggregateFunction AggregateFunction(): {
-    StaticValue v;
-    String name, n, fieldName;
-    boolean isDistinct = false;
-} {
-    name=AggregateName() <OPEN_PAREN>
-    ( <DISTINCT> { isDistinct = true; } )? (
-          n=NamePart() (
-              <PERIOD> fieldName=NamePart() { v = new FieldValue(n, fieldName); }
-            | v=FunctionCallRest(n)
-            | { v = new FieldValue(null, n); }
-          )
-        | v=MathValue()
-    ) <CLOSE_PAREN>
-    { return new AggregateFunction(name, isDistinct, v); }
-}
-
-private FunctionCall FunctionCallRest(String name): {
-    Value arg;
-    List<Value> args = FastList.newInstance();
-} {
-    <OPEN_PAREN> (
-        arg=Value() { args.add(arg); }
-        ( <COMMA> arg=Value() { args.add(arg); } )*
-    )?
-    <CLOSE_PAREN>
-    { return new FunctionCall(name, args); }
-}
-
-private ConstantValue ConstantValue(): {
-    String n;
-    ConstantValue v;
-    int i;
-    String s;
-} {
-      n=NamePart() (
-          v=FunctionCallRest(n) { return v; }
-        | v=FieldValue(n) { return v; }
-      )
-    | i=Integer() { return new NumberValue<Integer>(i); }
-    | s=SQuoted() { return new StringValue(s); }
-    | v=MathValue() { return v; }
-}
-
-private String NamePart(): {
-} {
-      <NAME> { return getToken(0).image; }
-    | <TYPE> { return getToken(0).image; }
-}
-
-private String DQuoted(): {
-    StringBuilder sb = new StringBuilder();
-} {
-    <START_DQUOTE> (
-          <TEXT> { sb.append(getToken(0).image); }
-        | <ESCAPED> { sb.append(getToken(0).image); }
-    )* <END_DQUOTE>
-    { return sb.toString(); }
-}
-
-private String SQuoted(): {
-    StringBuilder sb = new StringBuilder();
-} {
-    <START_SQUOTE> (
-          <TEXT> { sb.append(getToken(0).image); }
-        | <ESCAPED> { sb.append(getToken(0).image); }
-        | <ESCAPE_SQUOTE> { sb.append("'"); }
-    )* <END_SQUOTE>
-    { return sb.toString(); }
-}
-
-private String Text(): {
-    StringBuilder sb = new StringBuilder();
-} {
-    ( <TEXT> { sb.append(getToken(0).image); } )+
-    { return sb.toString(); }
-}
-
-private List<String> FieldList(): {
-    List<String> list = FastList.newInstance();
-    String n;
-} {
-    n=NamePart() { list.add(n); }
-    ( <COMMA> n=NamePart() { list.add(n); } )*
-    { return list; }
-}
-
-private FieldValue FieldValue(String fieldName): {
-    String s;
-} {
-    ( <PERIOD> s=NamePart() { return new FieldValue(fieldName, s); } )?
-    { return new FieldValue(fieldName); }
-}
-
-private List<OrderByItem> OrderByList(): {
-    List<OrderByItem> orderBy = FastList.newInstance();
-    OrderByItem obi;
-} {
-    obi=OrderByItem() { orderBy.add(obi); }
-    ( <COMMA> obi=OrderByItem() { orderBy.add(obi); } )*
-    { return orderBy; }
-}
-
-public OrderByItem OrderByItem(): {
-    ConstantValue value;
-    OrderByItem.Order ordering = OrderByItem.Order.DEFAULT;
-    OrderByItem.Nulls nulls = OrderByItem.Nulls.DEFAULT;
-} {
-    (
-          (
-            (
-                  <PLUS> { ordering = OrderByItem.Order.ASCENDING; }
-                | <MINUS> { ordering = OrderByItem.Order.DESCENDING; }
-            )
-            value=ConstantValue()
-          )
-        | value=ConstantValue() (
-              <DESC> { ordering = OrderByItem.Order.DESCENDING; }
-            | <ASC> { ordering = OrderByItem.Order.ASCENDING; }
-          )?
-    )
-    (
-        <NULLS> (
-              <FIRST> { nulls = OrderByItem.Nulls.FIRST; }
-            | <LAST> { nulls = OrderByItem.Nulls.LAST; }
-        )
-    )?
-    { return new OrderByItem(ordering, nulls, value); }
-}
-
-private Integer Integer(): {
-} {
-    <INTEGER> { return Integer.decode(getToken(0).image); }
-}
-
-private Value Value(): {
-    String n;
-    Value v;
-    int i;
-    String s;
-} {
-      n=NamePart() (
-          v=FunctionCallRest(n) { return v; }
-        | v=FieldValue(n) { return v; }
-      )
-    | i=Integer() { return new NumberValue<Integer>(i); }
-    | s=SQuoted() { return new StringValue(s); }
-}
-
-private Condition ConditionExpression(): {
-    Condition c;
-} {
-    c=OrExpression() { return c; }
-}
-
-private Condition AndExpression(): {
-    List<Condition> list = FastList.newInstance();
-    Condition c;
-} {
-    c=BooleanExpression() { list.add(c); }
-    ( <AND> c=BooleanExpression() { list.add(c); } )*
-    { return reduce(list, Joiner.AND); }
-}
-
-private Condition OrExpression(): {
-    List<Condition> list = FastList.newInstance();
-    Condition c;
-} {
-    c=AndExpression() { list.add(c); }
-    ( <OR> c=AndExpression() { list.add(c); } )*
-    { return reduce(list, Joiner.OR); }
-}
-
-private Value RightValue(): {
-    Value v;
-} {
-      v=Value() { return v; }
-    | v=ParameterValue() { return v; }
-}
-
-private ParameterValue ParameterValue(): {
-} {
-    <PARAMETER> { return new ParameterValue(getToken(0).image.substring(1)); }
-}
-
-private Condition BooleanExpression(): {
-    Value v1, v2, v, r1, r2;
-    String op;
-    Condition c;
-    List<Value> list = FastList.newInstance();
-} {
-    v1=Value() (
-          <BETWEEN> r1=RightValue() <AND> r2=RightValue()
-          { return new BetweenCondition(v1, r1, r2); }
-        | <IS> (
-              <NULL> { op = "="; v2 = Value.NULL; }
-            | <NOT> <NULL> { op = "!="; v2 = Value.NULL; }
-        )
-    | op=ComparisonOperator() (
-          v2=RightValue()
-        | <OPEN_PAREN>
-          v=RightValue() { list.add(v); }
-          (
-            <COMMA> v=RightValue() { list.add(v); }
-          )*
-          <CLOSE_PAREN>
-          { return new ListCondition(v1, op, list); }
-        )
-      )
-      { return new BooleanCondition(v1, op, v2); }
-    | <OPEN_PAREN> c=ConditionExpression() <CLOSE_PAREN> { return c; }
-}
-
-private String ComparisonOperator(): {
-    StringBuilder sb = new StringBuilder();
-    String s;
-} {
-      s=Text() { sb.append(s); }
-      (
-        <EQUALS> { sb.append(getToken(0).image); }
-        ( s=Text() { sb.append(s); } )?
-      )*
-      { return sb.toString(); }
-    | <NAME> { return getToken(0).image; }
-    | <EQUALS> { return getToken(0).image; }
-}
-
-private String MathOperator(): {
-    String s;
-} {
-      s=Text() { return s; }
-    | <NAME> { return getToken(0).image; }
-}
-
-private String AggregateName(): {
-} {
-      <COUNT> { return getToken(0).image; }
-    | <MAX> { return getToken(0).image; }
-    | <MIN> { return getToken(0).image; }
-    | <SUM> { return getToken(0).image; }
-    | <AVG> { return getToken(0).image; }
-    | <FIRST> { return getToken(0).image; }
-    | <LAST> { return getToken(0).image; }
-}
diff --git a/framework/sql/src/org/ofbiz/sql/test/SQLTest.java b/framework/sql/src/org/ofbiz/sql/test/SQLTest.java
deleted file mode 100644
index 119d11f..0000000
--- a/framework/sql/src/org/ofbiz/sql/test/SQLTest.java
+++ /dev/null
@@ -1,288 +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.sql.test;
-
-import java.io.StringReader;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import org.ofbiz.base.test.GenericTestCaseBase;
-import org.ofbiz.sql.AggregateFunction;
-import org.ofbiz.sql.BetweenCondition;
-import org.ofbiz.sql.BooleanCondition;
-import org.ofbiz.sql.Condition;
-import org.ofbiz.sql.ConditionList;
-import org.ofbiz.sql.ConstantValue;
-import org.ofbiz.sql.FieldAll;
-import org.ofbiz.sql.FieldDef;
-import org.ofbiz.sql.FieldValue;
-import org.ofbiz.sql.FunctionCall;
-import org.ofbiz.sql.InsertRow;
-import org.ofbiz.sql.InsertValues;
-import org.ofbiz.sql.Joined;
-import org.ofbiz.sql.Joiner;
-import org.ofbiz.sql.KeyMap;
-import org.ofbiz.sql.ListCondition;
-import org.ofbiz.sql.MathValue;
-import org.ofbiz.sql.NumberValue;
-import org.ofbiz.sql.OrderByItem;
-import org.ofbiz.sql.ParameterValue;
-import org.ofbiz.sql.Parser;
-import org.ofbiz.sql.Relation;
-import org.ofbiz.sql.SQLDelete;
-import org.ofbiz.sql.SQLIndex;
-import org.ofbiz.sql.SQLInsert;
-import org.ofbiz.sql.SQLSelect;
-import org.ofbiz.sql.SQLStatement;
-import org.ofbiz.sql.SQLUpdate;
-import org.ofbiz.sql.SQLView;
-import org.ofbiz.sql.SetField;
-import org.ofbiz.sql.StringValue;
-import org.ofbiz.sql.Table;
-import org.ofbiz.sql.TableName;
-import org.ofbiz.sql.Value;
-
-public class SQLTest extends GenericTestCaseBase {
-    public SQLTest(String name) {
-        super(name);
-    }
-
-    private static Parser parser(SQLStatement<?> s) throws Exception {
-        return new Parser(new StringReader(s.toString()));
-    }
-
-    public void testParse() throws Exception {
-        List<SQLStatement<?>> statements = new Parser(getClass().getResourceAsStream("GoodParseAll.sql")).SQLFile();
-        for (SQLStatement<?> statement: statements) {
-            System.err.println(statement);
-        }
-        Iterator<SQLStatement<?>> stmtIt = statements.iterator();
-        assertTrue("has more statements", stmtIt.hasNext());
-
-        {
-            SQLSelect select = new SQLSelect(
-                false,
-                list(
-                    new FieldAll("a", Collections.<String>emptySet()),
-                    new FieldAll("b", set("partyId")),
-                    new FieldAll("c", set("partyId"))
-                ),
-                GenericTestCaseBase.<String, FieldDef>map(
-                    "roleTypeId", new FieldDef(new FieldValue("d", "roleTypeId"), null),
-                    "roleDescription", new FieldDef(new FieldValue("d", "description"), "roleDescription"),
-                    "SUM",  new FieldDef(new AggregateFunction("SUM", false, new FieldValue("a", "partyId")), null),
-                    "baz",  new FieldDef(new FunctionCall("FOO", GenericTestCaseBase.<Value>list(new FieldValue("a", "partyId"), new NumberValue<Integer>(Integer.valueOf(1)))), "baz"),
-                    "one",  new FieldDef(new MathValue("||", list(new FieldValue("a", "partyId"), new StringValue("-"), new FieldValue("a", "partyTypeId"))), "one"),
-                    "cnt1", new FieldDef(new AggregateFunction("COUNT", false, new FieldValue("a", "partyId")), "cnt1"),
-                    "cnt2", new FieldDef(new AggregateFunction("COUNT", false, new FieldValue(null, "partyId")), "cnt2"),
-                    "cnt3", new FieldDef(new AggregateFunction("COUNT", true, new FieldValue("a", "partyId")), "cnt3")
-                ),
-                new Table(
-                    new TableName("Party", "a"),
-                    new Joined(true, new TableName("Person", "b"), list(new KeyMap("partyId", "partyId")),
-                        new Joined(true, new TableName("PartyGroup", "c"), list(new KeyMap("partyId", "partyId")),
-                            new Joined(false, new TableName("PartyRole", "d"), list(new KeyMap("partyId", "partyId"), new KeyMap("partyId", "partyId")))
-                        )
-                    )
-                ),
-                GenericTestCaseBase.<String, Relation>map(
-                    "MainAPerson", new Relation("one", "MainA", "Person", list(new KeyMap("partyId", "partyId"))),
-                    "MainBPerson", new Relation(null, "MainB", "Person", list(new KeyMap("partyId", "partyId"))),
-                    "Person", new Relation("one", null, "Person", list(new KeyMap("partyId", "partyId"))),
-                    "PartyGroup", new Relation(null, null, "PartyGroup", list(new KeyMap("partyId", "partyId")))
-                ),
-                new ConditionList(
-                    Joiner.OR,
-                    GenericTestCaseBase.<Condition>list(
-                        new ConditionList(
-                            Joiner.AND,
-                            list(
-                                new BooleanCondition(new FieldValue("a", "partyTypeId"), "=", new StringValue("PERSON")),
-                                new BooleanCondition(new FieldValue("b", "lastName"), "LIKE", new ParameterValue("lastName")),
-                                new BetweenCondition(new FieldValue("b", "birthDate"), new StringValue("1974-12-01"), new StringValue("1974-12-31"))
-                            )
-                        ),
-                        new ConditionList(
-                            Joiner.AND,
-                            list(
-                                new ListCondition(new FieldValue("b", "partyId"), "IN", GenericTestCaseBase.<Value>list(
-                                    new StringValue("1"),
-                                    new StringValue("2"),
-                                    new StringValue("3"),
-                                    new StringValue("4")
-                                )),
-                                new BooleanCondition(new FieldValue("b", "gender"), "=", new StringValue("M"))
-                            )
-                        )
-                    )
-                ),
-                new BooleanCondition(new FieldValue("b", "firstName"), "LIKE", new StringValue("%foo%")),
-                null,
-                list(
-                    new OrderByItem(OrderByItem.Order.DEFAULT, OrderByItem.Nulls.DEFAULT, new FunctionCall("LOWER", GenericTestCaseBase.<Value>list(new FieldValue(null, "lastName")))),
-                    new OrderByItem(OrderByItem.Order.DEFAULT, OrderByItem.Nulls.DEFAULT, new FieldValue(null, "firstName")),
-                    new OrderByItem(OrderByItem.Order.DESCENDING, OrderByItem.Nulls.DEFAULT, new FieldValue(null, "birthDate"))
-                ),
-                5,
-                10
-            );
-            SQLStatement<?> stmt = stmtIt.next();
-            assertEquals("firstSelect", select, stmt);
-            assertEquals("firstSelect:parse", parser(select).SelectStatement(), parser(stmt).SelectStatement());
-        }
-        {
-            SQLInsert insert = new SQLInsert(
-                new TableName("Party", null),
-                new InsertValues(
-                    list(
-                        new InsertRow(GenericTestCaseBase.<Value>list(new StringValue("a"), new StringValue("PERSON"), new StringValue("PARTY_DISABLED"))),
-                        new InsertRow(list(new NumberValue<Integer>(Integer.valueOf(5)), new StringValue("PARTY_GROUP"), new ParameterValue("name")))
-                    )
-                ),
-                list("partyId", "partyTypeId", "statusId")
-            );
-            SQLStatement<?> stmt = stmtIt.next();
-            assertEquals("firstInsert", insert, stmt);
-            assertEquals("firstInsert:parse", parser(insert).InsertStatement(), parser(stmt).InsertStatement());
-        }
-        {
-            SQLInsert insert = new SQLInsert(
-                new TableName("Person", null),
-                new SQLSelect(
-                    false,
-                    null,
-                    GenericTestCaseBase.<String, FieldDef>map(
-                        "partyId", new FieldDef(new FieldValue(null, "partyId"), null),
-                        "firstName",  new FieldDef(new MathValue("||", list(new FieldValue(null, "partyId"), new StringValue("-auto"))), "firstName")
-                    ),
-                    new Table(new TableName("Party", null), null),
-                    null,
-                    new ListCondition(new FieldValue(null, "partyId"), "IN", GenericTestCaseBase.<Value>list(new StringValue("a"), new StringValue("b"))),
-                    null,
-                    null,
-                    null,
-                    -1,
-                    -1
-                ),
-                list("partyId", "firstName")
-            );
-            SQLStatement<?> stmt = stmtIt.next();
-            assertEquals("secondInsert", insert, stmt);
-            assertEquals("secondInsert:parse", parser(insert).InsertStatement(), parser(stmt).InsertStatement());
-        }
-        {
-            SQLUpdate update = new SQLUpdate(
-                new Table(new TableName("Person", null), null),
-                list(
-                    new SetField("lastName", new MathValue("||", list(new StringValue("auto-"), new FieldValue(null, "partyId"))))
-                ),
-                new ListCondition(new FieldValue(null, "partyId"), "IN", GenericTestCaseBase.<Value>list(new StringValue("a"), new StringValue("b")))
-            );
-            SQLStatement<?> stmt = stmtIt.next();
-            assertEquals("firstUpdate", update, stmt);
-            assertEquals("firstUpdate:parse", parser(update).UpdateStatement(), parser(stmt).UpdateStatement());
-        }
-        {
-            SQLUpdate update = new SQLUpdate(
-                new Table(new TableName("Person", null), null),
-                list(
-                    new SetField("lastName", new MathValue("||", list(new StringValue("auto-"), new FieldValue(null, "partyId")))),
-                    new SetField("height", new NumberValue<Integer>(Integer.valueOf(5))),
-                    new SetField("width", new NumberValue<Integer>(Integer.valueOf(7)))
-                ),
-                new ListCondition(new FieldValue(null, "partyId"), "IN", GenericTestCaseBase.<Value>list(new StringValue("a"), new StringValue("b")))
-            );
-            SQLStatement<?> stmt = stmtIt.next();
-            assertEquals("secondUpdate", update, stmt);
-            assertEquals("secondUpdate:parse", parser(update).UpdateStatement(), parser(stmt).UpdateStatement());
-        }
-        {
-            SQLUpdate update = new SQLUpdate(
-                new Table(new TableName("Person", null), null),
-                list(
-                    new SetField("lastName", new MathValue("||", list(new StringValue("auto-"), new FieldValue(null, "partyId")))),
-                    new SetField("height", new NumberValue<Integer>(Integer.valueOf(6))),
-                    new SetField("width", new NumberValue<Integer>(Integer.valueOf(5))),
-                    new SetField("nickname", new StringValue("a"))
-                ),
-                new ListCondition(new FieldValue(null, "partyId"), "IN", GenericTestCaseBase.<Value>list(new StringValue("a"), new StringValue("b")))
-            );
-            SQLStatement<?> stmt = stmtIt.next();
-            assertEquals("thirdUpdate", update, stmt);
-            assertEquals("thirdUpdate:parse", parser(update).UpdateStatement(), parser(stmt).UpdateStatement());
-        }
-        {
-            SQLDelete delete = new SQLDelete(
-                new Table(new TableName("Person", null), null),
-                new ListCondition(new FieldValue(null, "partyId"), "IN", GenericTestCaseBase.<Value>list(new StringValue("a"), new StringValue("b")))
-            );
-            SQLStatement<?> stmt = stmtIt.next();
-            assertEquals("firstDelete", delete, stmt);
-            assertEquals("firstDelete:parse", parser(delete).DeleteStatement(), parser(stmt).DeleteStatement());
-        }
-        {
-            SQLDelete delete = new SQLDelete(
-                new Table(new TableName("Party", null), null),
-                new ListCondition(new FieldValue(null, "partyId"), "IN", GenericTestCaseBase.<Value>list(new StringValue("a"), new StringValue("b")))
-            );
-            SQLStatement<?> stmt = stmtIt.next();
-            assertEquals("secondDelete", delete, stmt);
-            assertEquals("secondDelete:parse", parser(delete).DeleteStatement(), parser(stmt).DeleteStatement());
-        }
-        {
-            SQLView view = new SQLView(
-                "viewOne",
-                new SQLSelect(
-                    false,
-                    list(new FieldAll("a", Collections.<String>emptySet())),
-                    null,
-                    new Table(new TableName("Party", "a"), null),
-                    null,
-                    null,
-                    null,
-                    null,
-                    null,
-                    -1,
-                    -1
-                )
-            );
-            SQLStatement<?> stmt = stmtIt.next();
-            assertEquals("firstView", view, stmt);
-            assertEquals("firstView:parse", parser(view).ViewStatement(), parser(stmt).ViewStatement());
-        }
-        {
-            SQLIndex index = new SQLIndex(
-                false,
-                "testIndex",
-                "Party",
-                "btree",
-                GenericTestCaseBase.<ConstantValue>list(
-                    new FieldValue(null, "partyId")
-                )
-            );
-            SQLStatement<?> stmt = stmtIt.next();
-            assertEquals("firstIndex", index, stmt);
-        }
-        assertFalse("has no more statements", stmtIt.hasNext());
-    }
-/*
-CREATE VIEW viewOne AS SELECT a.* FROM Party a;
-*/
-}
diff --git a/framework/sql/src/org/ofbiz/sql/test/SelectTest.java b/framework/sql/src/org/ofbiz/sql/test/SelectTest.java
index b269935..f5480b3 100644
--- a/framework/sql/src/org/ofbiz/sql/test/SelectTest.java
+++ b/framework/sql/src/org/ofbiz/sql/test/SelectTest.java
@@ -18,7 +18,6 @@
  */
 package org.ofbiz.sql.test;
 
-import java.io.StringReader;
 import java.util.Collections;
 import java.util.Set;
 
@@ -30,7 +29,6 @@
 import org.ofbiz.sql.FieldValue;
 import org.ofbiz.sql.FunctionCall;
 import org.ofbiz.sql.OrderByItem;
-import org.ofbiz.sql.Parser;
 import org.ofbiz.sql.StaticValue;
 import org.ofbiz.sql.Value;
 
@@ -44,10 +42,6 @@
         super(name);
     }
 
-    private static Parser parser(Object v) {
-        return new Parser(new StringReader(v.toString()));
-    }
-
     private static <V> void basicTest(String label, Class<V> clz, V v, V o, boolean matches) {
         assertNotEquals(label + ":not-equals-this", v, SelectTest.class);
         if (o != null) {
@@ -62,7 +56,6 @@
     private static void fieldAllTest(String label, FieldAll v, String alias, Set<String> exclude, FieldAll o, boolean matches) throws Exception {
         assertEquals(label + ":alias", alias, v.getAlias());
         assertEquals(label + ":exclude", exclude, set(v));
-        assertEquals(label + ":parse", v, parser(v).parse_FieldAll());
         basicTest(label, FieldAll.class, v, o, matches);
     }
 
@@ -83,7 +76,6 @@
         assertEquals(label + ":value", value, v.getValue());
         assertEquals(label + ":alias", alias, v.getAlias());
         assertEquals(label + ":default-name", defaultName, v.getDefaultName());
-        assertEquals(label + ":parse", v, parser(v).parse_FieldDef());
         basicTest(label, FieldDef.class, v, o, matches);
     }
 
@@ -104,7 +96,6 @@
         assertEquals(label + ":order", order, v.getOrder());
         assertEquals(label + ":nulls", nulls, v.getNulls());
         assertEquals(label + ":value", value, v.getValue());
-        assertEquals(label + ":parse", v, parser(v).parse_OrderByItem());
         basicTest(label, OrderByItem.class, v, o, matches);
     }
 
diff --git a/framework/webapp/lib/json-lib-2.2.3-jdk15.jar b/framework/webapp/lib/json-lib-2.2.3-jdk15.jar
deleted file mode 100644
index 8c92fab..0000000
--- a/framework/webapp/lib/json-lib-2.2.3-jdk15.jar
+++ /dev/null
Binary files differ
diff --git a/framework/webapp/src/org/ofbiz/webapp/event/JSONRequestBodyMapHandler.java b/framework/webapp/src/org/ofbiz/webapp/event/JSONRequestBodyMapHandler.java
new file mode 100644
index 0000000..f2318ec
--- /dev/null
+++ b/framework/webapp/src/org/ofbiz/webapp/event/JSONRequestBodyMapHandler.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.webapp.event;
+
+import org.ofbiz.base.lang.JSON;
+import org.ofbiz.base.util.UtilGenerics;
+
+import javax.servlet.ServletRequest;
+import java.io.IOException;
+import java.util.Map;
+
+/** An implementation of <code>RequestBodyMapHandler</code> that can extract a <code>Map<String, Object></code> from the JSON data in the request body */
+public class JSONRequestBodyMapHandler implements RequestBodyMapHandler {
+
+    public Map<String, Object> extractMapFromRequestBody(ServletRequest request) throws IOException {
+        return UtilGenerics.<Map<String, Object>>cast(JSON.from(request.getInputStream()).toObject(Map.class));
+    }
+}
diff --git a/framework/webapp/src/org/ofbiz/webapp/event/RequestBodyMapHandler.java b/framework/webapp/src/org/ofbiz/webapp/event/RequestBodyMapHandler.java
new file mode 100644
index 0000000..cc5cfce
--- /dev/null
+++ b/framework/webapp/src/org/ofbiz/webapp/event/RequestBodyMapHandler.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.webapp.event;
+
+import javax.servlet.ServletRequest;
+import java.io.IOException;
+import java.util.Map;
+
+/** An handler that can extract a Map (typically used as a service input map) from the data in the body of a <code>ServletRequest</code>. */
+public interface RequestBodyMapHandler {
+    /** Extracts from the data in the body of the <code>ServletRequest</code> an instance of <code>Map<String, Object></code>.
+     *
+     * @param request the request with the data in its body
+     * @return an instance of <code>Map<String, Object></code> that represents the data in the request body
+     */
+    public Map<String, Object> extractMapFromRequestBody(ServletRequest request) throws IOException;
+}
diff --git a/framework/webapp/src/org/ofbiz/webapp/event/RequestBodyMapHandlerFactory.java b/framework/webapp/src/org/ofbiz/webapp/event/RequestBodyMapHandlerFactory.java
new file mode 100644
index 0000000..819c081
--- /dev/null
+++ b/framework/webapp/src/org/ofbiz/webapp/event/RequestBodyMapHandlerFactory.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.webapp.event;
+
+import javax.servlet.ServletRequest;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Factory class that provides the proper <code>RequestBodyMapHandler</code> based on the content type of the <code>ServletRequest</code> */
+public class RequestBodyMapHandlerFactory {
+    private final static Map<String, RequestBodyMapHandler> requestBodyMapHandlers = new HashMap<String, RequestBodyMapHandler>();
+    static {
+        requestBodyMapHandlers.put("application/json", new JSONRequestBodyMapHandler());
+    }
+
+    public static RequestBodyMapHandler getRequestBodyMapHandler(ServletRequest request) {
+        return requestBodyMapHandlers.get(request.getContentType());
+    }
+
+    public static Map<String, Object> extractMapFromRequestBody(ServletRequest request) throws IOException {
+        Map<String, Object> outputMap = null;
+        RequestBodyMapHandler handler = getRequestBodyMapHandler(request);
+        if (handler != null) {
+            outputMap = handler.extractMapFromRequestBody(request);
+        }
+        return outputMap;
+    }
+}
diff --git a/framework/webapp/src/org/ofbiz/webapp/event/ServiceEventHandler.java b/framework/webapp/src/org/ofbiz/webapp/event/ServiceEventHandler.java
index b2143d3..5ca27d9 100644
--- a/framework/webapp/src/org/ofbiz/webapp/event/ServiceEventHandler.java
+++ b/framework/webapp/src/org/ofbiz/webapp/event/ServiceEventHandler.java
@@ -21,7 +21,9 @@
 import static org.ofbiz.base.util.UtilGenerics.checkList;
 
 import java.io.File;
+import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -233,6 +235,15 @@
 
         Map<String, Object> rawParametersMap = UtilHttp.getParameterMap(request, null, null);
         Set<String> urlOnlyParameterNames = UtilHttp.getUrlOnlyParameterMap(request).keySet();
+        Map<String, Object> requestBodyMap = null;
+        try {
+            requestBodyMap = RequestBodyMapHandlerFactory.extractMapFromRequestBody(request);
+        } catch (IOException ioe) {
+            Debug.logWarning(ioe, module);
+        }
+        if (requestBodyMap != null) {
+            rawParametersMap.putAll(requestBodyMap);
+        }
 
         // we have a service and the model; build the context
         Map<String, Object> serviceContext = FastMap.newInstance();
diff --git a/lib/build/javacc/javacc.jar b/lib/build/javacc/javacc.jar
deleted file mode 100644
index 2550727..0000000
--- a/lib/build/javacc/javacc.jar
+++ /dev/null
Binary files differ
diff --git a/macros.xml b/macros.xml
index bd7c50e..ab2dfe3 100644
--- a/macros.xml
+++ b/macros.xml
@@ -186,32 +186,6 @@
         <pathelement location="${ofbiz.home.dir}/framework/base/lib/ant/ant-contrib-1.0b3.jar"/>
     </classpath>
   </taskdef>
- <macrodef name="ofbiz-javacc">
-  <attribute name="dir"/>
-  <attribute name="file"/>
-  <attribute name="prefix" default=""/>
-  <sequential>
-   <if>
-     <not>
-      <uptodate
-       srcfile="@{prefix}src/@{dir}/@{file}.jj"
-       targetfile="@{prefix}build/gen-src/javacc/@{dir}/@{file}.java"/>
-     </not>
-     <then>
-       <delete dir="@{prefix}build/gen-src/javacc/@{dir}"/>
-       <mkdir dir="@{prefix}build/gen-src/javacc/@{dir}"/>
-       <javacc target="@{prefix}src/@{dir}/@{file}.jj"
-          javacchome="${ofbiz.home.dir}/lib/build/javacc"
-          outputdirectory="@{prefix}build/gen-src/javacc/@{dir}"/>
-       <replace token="public class" 
-           value='@SuppressWarnings("all") public class' 
-           dir="@{prefix}build/gen-src/javacc/@{dir}"
-           includes="*.java" />
-       <delete dir="@{prefix}build/classes/@{dir}"/>
-     </then>
-   </if>
-  </sequential>
- </macrodef>
 
  <presetdef name="externalsubant">
   <subant inheritall="false">
diff --git a/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayStoreOptions.java b/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayStoreOptions.java
index 21a6839..5f1c909 100644
--- a/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayStoreOptions.java
+++ b/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayStoreOptions.java
@@ -18,10 +18,6 @@
  */
 package org.ofbiz.ebaystore;
 
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -32,7 +28,6 @@
 
 import javolution.util.FastList;
 import javolution.util.FastMap;
-import net.sf.json.JSONObject;
 
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilHttp;
@@ -116,7 +111,7 @@
                                     storeColorSchemeMap.put("storeFontTypeDescColor",storeFontType.getDescColor());
                                     storeColorSchemeMap.put("storeFontTypeFontDescValue",storeFontType.getDescFace().value());
                                     storeColorSchemeMap.put("storeDescSizeValue",storeFontType.getDescSize().value());
-                                    toJsonObject(storeColorSchemeMap,response);
+                                    request.setAttribute("storeColorSchemeMap", storeColorSchemeMap);
 
                                     break;
                                 }
@@ -137,63 +132,31 @@
         } catch (SdkException e) {
             e.printStackTrace();
             return "error";
-        } catch (EventHandlerException e) {
-            e.printStackTrace();
-            return "error";
         }
         return "success";
     }
 
-    public static void toJsonObject(Map<String,Object> attrMap, HttpServletResponse response) throws EventHandlerException {
-        JSONObject json = JSONObject.fromObject(attrMap);
-        String jsonStr = json.toString();
-        if (jsonStr == null) {
-            throw new EventHandlerException("JSON Object was empty; fatal error!");
-        }
-        // set the X-JSON content type
-        response.setContentType("application/json");
-        // jsonStr.length is not reliable for unicode characters
-        try {
-            response.setContentLength(jsonStr.getBytes("UTF8").length);
-        } catch (UnsupportedEncodingException e) {
-            throw new EventHandlerException("Problems with Json encoding", e);
-        }
-        // return the JSON String
-        Writer out;
-        try {
-            out = response.getWriter();
-            out.write(jsonStr);
-            out.flush();
-        } catch (IOException e) {
-            throw new EventHandlerException("Unable to get response writer", e);
-        }
-    }
-
     public static String retrieveItemTemplateByTemplateGroupId(HttpServletRequest request,HttpServletResponse response) {
         Map<String, Object> paramMap = UtilHttp.getCombinedMap(request);
-        try {
-            if (paramMap.get("productStoreId") != null) {
-                String temGroupId = (String)paramMap.get("templateGroupId");
-                Map<String,Object> addItemObj = EbayEvents.getAddItemListingObject(request, EbayEvents.getApiContext(request));
-                if (UtilValidate.isNotEmpty(addItemObj)) {
-                    String refName = "itemCateFacade_".concat((String) paramMap.get("pkCategoryId"));
-                    if (UtilValidate.isNotEmpty(addItemObj.get(refName))) {
-                        EbayStoreCategoryFacade cf = (EbayStoreCategoryFacade) addItemObj.get(refName);
-                        List<Map<String,Object>> theme = cf.getAdItemTemplates(temGroupId);
-                        if (theme.size() > 0) {
-                            toJsonObjectList(theme,response);
-                        }
+        if (paramMap.get("productStoreId") != null) {
+            String temGroupId = (String)paramMap.get("templateGroupId");
+            Map<String,Object> addItemObj = EbayEvents.getAddItemListingObject(request, EbayEvents.getApiContext(request));
+            if (UtilValidate.isNotEmpty(addItemObj)) {
+                String refName = "itemCateFacade_".concat((String) paramMap.get("pkCategoryId"));
+                if (UtilValidate.isNotEmpty(addItemObj.get(refName))) {
+                    EbayStoreCategoryFacade cf = (EbayStoreCategoryFacade) addItemObj.get(refName);
+                    List<Map<String,Object>> theme = cf.getAdItemTemplates(temGroupId);
+                    if (theme.size() > 0) {
+                        request.setAttribute("itemTemplates", theme);
                     }
                 }
             }
-        } catch (EventHandlerException e) {
-            Debug.logError(e.getMessage(), module);
         }
         return "success";
     }
 
     public static String retrieveEbayCategoryByParent(HttpServletRequest request, HttpServletResponse response) {
-        List<CategoryType> results = FastList.newInstance();
+        List<CategoryType> results;
         try {
             Map<String, Object> paramMap = UtilHttp.getCombinedMap(request);
             if (paramMap.get("productStoreId") != null) {
@@ -225,7 +188,7 @@
                         categories.add(context);
                     }
                     if (categories.size() > 0) {
-                        toJsonObjectList(categories,response);
+                        request.setAttribute("categories", categories);
                     }
                 }
             }
@@ -243,43 +206,8 @@
         return "success";
     }
 
-    public static void toJsonObjectList(List<Map<String,Object>> list, HttpServletResponse response) throws EventHandlerException {
-        JSONObject json = null;
-        List<JSONObject> jsonList = new ArrayList<JSONObject>();
-        if (list != null) {
-            for (Map<String,Object> val : list) {
-                json = new JSONObject();
-                for (String rowKey: val.keySet()) {
-                    json.put(rowKey, val.get(rowKey));
-                }
-                jsonList.add(json);
-            }
-            String jsonStr = jsonList.toString();
-            if (jsonStr == null) {
-                throw new EventHandlerException("JSON Object was empty; fatal error!");
-            }
-            // set the X-JSON content type
-            response.setContentType("application/json");
-            // jsonStr.length is not reliable for unicode characters
-            try {
-                response.setContentLength(jsonStr.getBytes("UTF8").length);
-            } catch (UnsupportedEncodingException e) {
-                throw new EventHandlerException("Problems with Json encoding", e);
-            }
-            // return the JSON String
-            Writer out;
-            try {
-                out = response.getWriter();
-                out.write(jsonStr);
-                out.flush();
-            } catch (IOException e) {
-                throw new EventHandlerException("Unable to get response writer", e);
-            } 
-        }
-    }
-    
     public static String retrieveEbayStoreCategoryByParent(HttpServletRequest request, HttpServletResponse response) {
-        List<StoreCustomCategoryType> results = FastList.newInstance();
+        List<StoreCustomCategoryType> results;
         try {
             Map<String, Object> paramMap = UtilHttp.getCombinedMap(request);
             if (paramMap.get("productStoreId") != null) {
@@ -312,12 +240,11 @@
                         } else {
                             isLeaf = "false";
                         }
-                        //String isLeaf = String.valueOf(category.getChildCategory().!= null ? "true" : "false");
                         context.put("IsLeafCategory", isLeaf);
                         categories.add(context);
                     }
                     if (categories.size() > 0) {
-                        toJsonObjectList(categories,response);
+                        request.setAttribute("categories", categories);
                     }
                 }
             }
diff --git a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/controller.xml b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/controller.xml
index 128cf0b..0c1ecce 100644
--- a/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/controller.xml
+++ b/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/controller.xml
@@ -92,8 +92,8 @@
     <request-map uri="retrieveThemeColorSchemeByThemeId">
         <security https="true" auth="true"/>
         <event type="java" path="org.ofbiz.ebaystore.EbayStoreOptions" invoke="retrieveThemeColorSchemeByThemeId"/>
-        <response name="success" type="view" value="ebayStoreDetail"/>
-        <response name="error" type="view" value="ebayStoreDetail"/>
+        <response name="success" type="request" value="json"/>
+        <response name="error" type="request" value="json"/>
     </request-map>
     <!-- Feedback -->
     <request-map uri="Feedback">
@@ -290,6 +290,7 @@
         <security https="true" auth="true"/>
         <event type="java" path="org.ofbiz.ebaystore.EbayStoreOptions" invoke="retrieveEbayCategoryByParent"/>
         <response name="success" type="request" value="json"/>
+        <response name="error" type="request" value="json"/>
     </request-map>
     <request-map uri="retrieveEbayStoreCategoryByParent">
         <security https="true" auth="true"/>
@@ -305,7 +306,8 @@
     <request-map uri="ebayAdItemTemplate">
         <security https="true" auth="true"/>
         <event type="java" path="org.ofbiz.ebaystore.EbayStoreOptions" invoke="retrieveItemTemplateByTemplateGroupId"/>
-        <response name="success" type="view" value="main"/>
+        <response name="success" type="request" value="json"/>
+        <response name="error" type="request" value="json"/>
     </request-map>
     <request-map uri="updateProductExportDetail">
         <security https="true" auth="true"/>
diff --git a/specialpurpose/ebaystore/webapp/ebaystore/store/StoreSetting.ftl b/specialpurpose/ebaystore/webapp/ebaystore/store/StoreSetting.ftl
index 2f66fe1..389c657 100644
--- a/specialpurpose/ebaystore/webapp/ebaystore/store/StoreSetting.ftl
+++ b/specialpurpose/ebaystore/webapp/ebaystore/store/StoreSetting.ftl
@@ -34,8 +34,8 @@
          data: pars,
          beforeStart: function() {document.getElementById('loading').innerHTML = ' ${uiLabelMap.CommonPleaseWait}';},
              success: function(data) {
-                if (data != null){
-                    var resp = eval("("+data+")");
+                if (data != null && data.storeColorSchemeMap){
+                    var resp = eval("("+data.storeColorSchemeMap+")");
                     if (resp.storeColorPrimary!=null) document.getElementById('storePrimaryColor').value =  resp.storeColorPrimary;
                     if (resp.storeColorAccent!=null) document.getElementById('storeSecondaryColor').value = resp.storeColorAccent;
                     if (resp.storeColorSecondary!=null) document.getElementById('storeAccentColor').value = resp.storeColorSecondary;
diff --git a/specialpurpose/ebaystore/webapp/ebaystore/store/productsearchExport.ftl b/specialpurpose/ebaystore/webapp/ebaystore/store/productsearchExport.ftl
index 28f1fce..1c456f1 100644
--- a/specialpurpose/ebaystore/webapp/ebaystore/store/productsearchExport.ftl
+++ b/specialpurpose/ebaystore/webapp/ebaystore/store/productsearchExport.ftl
@@ -81,9 +81,9 @@
             },
             success: function(data) {
                 document.getElementById('loading').innerHTML = '';
-                if (data) {
+                if (data && data.categories) {
                     removeOptions(id);
-                    var resp = eval(data);
+                    var resp = eval(data.categories);
                     var leng = resp.length;
                      if (leng) {
                         for (i=0;i<leng;i++) {
@@ -112,8 +112,8 @@
             success: function(data){
                 removeOptions('theme');
                 previewPic(":http://pics.ebay.com/aw/pics/vit/None2_sample_100x120.gif");
-                if(data!=null){
-                    var resp = eval(data);
+                if(data!=null && data.itemTemplates!=null){
+                    var resp = eval(data.itemTemplates);
                     var leng = resp.length;
                     var j = 0;
                     for (i=0;i<leng;i++) {