protected void compareJSONArrayOfSimpleValues(
     String key, JSONArray expected, JSONArray actual, JSONCompareResult result)
     throws JSONException {
   Map<Object, Integer> expectedCount =
       JSONCompareUtil.getCardinalityMap(jsonArrayToList(expected));
   Map<Object, Integer> actualCount = JSONCompareUtil.getCardinalityMap(jsonArrayToList(actual));
   for (Object o : expectedCount.keySet()) {
     if (!actualCount.containsKey(o)) {
       result.missing(key + "[]", o);
     } else if (!actualCount.get(o).equals(expectedCount.get(o))) {
       result.fail(
           key
               + "[]: Expected "
               + expectedCount.get(o)
               + " occurrence(s) of "
               + o
               + " but got "
               + actualCount.get(o)
               + " occurrence(s)");
     }
   }
   for (Object o : actualCount.keySet()) {
     if (!expectedCount.containsKey(o)) {
       result.unexpected(key + "[]", o);
     }
   }
 }
 // This is expensive (O(n^2) -- yuck), but may be the only resort for some cases with loose array
 // ordering, and no
 // easy way to uniquely identify each element.
 // This is expensive (O(n^2) -- yuck), but may be the only resort for some cases with loose array
 // ordering, and no
 // easy way to uniquely identify each element.
 protected void recursivelyCompareJSONArray(
     String key, JSONArray expected, JSONArray actual, JSONCompareResult result)
     throws JSONException {
   Set<Integer> matched = new HashSet<Integer>();
   for (int i = 0; i < expected.length(); ++i) {
     Object expectedElement = expected.get(i);
     boolean matchFound = false;
     for (int j = 0; j < actual.length(); ++j) {
       Object actualElement = actual.get(j);
       if (matched.contains(j) || !actualElement.getClass().equals(expectedElement.getClass())) {
         continue;
       }
       if (expectedElement instanceof JSONObject) {
         if (compareJSON((JSONObject) expectedElement, (JSONObject) actualElement).passed()) {
           matched.add(j);
           matchFound = true;
           break;
         }
       } else if (expectedElement instanceof JSONArray) {
         if (compareJSON((JSONArray) expectedElement, (JSONArray) actualElement).passed()) {
           matched.add(j);
           matchFound = true;
           break;
         }
       } else if (expectedElement.equals(actualElement)) {
         matched.add(j);
         matchFound = true;
         break;
       }
     }
     if (!matchFound) {
       result.fail(key + "[" + i + "] Could not find match for element " + expectedElement);
       return;
     }
   }
 }