### Question:
JSONUtil { private static void applyFunctorToJsonRecursively(Object jsonElem, String jsonElemKey, Functor functor) { try { if (jsonElem == null) return; if (jsonElem instanceof JSONArray) { JSONArray jsonArray = (JSONArray) jsonElem; for (int j = 0; j < jsonArray.length(); ++j) { Object elem = jsonArray.get(j); if (elem instanceof JSONObject) applyFunctorToJsonRecursively(elem, null, functor); else if (elem instanceof JSONArray) applyFunctorToJsonRecursively(elem, jsonElemKey, functor); else { Object procVal = functor.call(jsonElemKey, elem.toString()); if (procVal != null) jsonArray.put(j, procVal); } } } else if (jsonElem instanceof JSONObject) { JSONObject jsonObject = (JSONObject) jsonElem; for (Iterator<String> iter = jsonObject.keys(); iter.hasNext(); ) { String childElemKey = iter.next(); Object childElemVal = jsonObject.get(childElemKey); if (childElemVal instanceof JSONObject || childElemVal instanceof JSONArray) applyFunctorToJsonRecursively(childElemVal, childElemKey, functor); else { Object procVal = functor.call(childElemKey, childElemVal.toString()); if (procVal != null) ((JSONObject) jsonElem).put(childElemKey, procVal); } } } else return; } catch (JSONException je) { throw new RuntimeException("Exception during applying functor to JSON.", je); } } private  JSONUtil(); static void applyFunctorToJson(Object jsonElem, Functor functor); static JSONObject getJSONObject(String maybeJsonStr); static JSONArray getJSONArray(String maybeJsonStr); static String toJSON(Object obj); static String toJSON(Collection col);  }### Answer:
@Test public void testApplyFunctorToJsonRecursively() throws Exception { String testJsonStr = "{\"test\": [{\"Misha\": \"Ch\", \"Andrew\": \"SF\", \"Norm\": \"SF\"}, {\"SF\": [\"Norm\", \"Andrew\", \"Chaim\"], \"Ch\": \"Misha\"}]}"; JSONObject testJson = new JSONObject(testJsonStr); String expectedPostProcJsonStr = "{\"test\": [{\"Misha\": \"Ch\", \"Andrew\": \"SF\", \"Norm\": \"SF\"}, {\"SF\": [\"NORM\", \"ANDREW\", \"CHAIM\"], \"Ch\": \"Misha\"}]}"; JSONObject expectedPostProcJson = new JSONObject(expectedPostProcJsonStr); expectedPostProcJsonStr = expectedPostProcJson.toString(); Assert.assertFalse("Before processing the json strings should not be equal.", expectedPostProcJsonStr.equals(testJson.toString())); JSONUtil.applyFunctorToJson(testJson, new JSONUtil.Functor() { public String call(String jsonKey, String jsonValue) { if (jsonKey.equalsIgnoreCase("SF")) return jsonValue.toUpperCase(); return jsonValue; } }); Assert.assertEquals("Processing did not make the json's equal like it should have", expectedPostProcJsonStr, testJson.toString()); }