public int compareTo(Object o) throws ClassCastException {
   if (!(o instanceof SearchResult)) {
     throw new ClassCastException(
         "Error in SearchResult.compareTo(): expected SearchResult object.");
   }
   SearchResult sr = (SearchResult) o;
   return label.compareToIgnoreCase(sr.getLabel());
 }
  private JSONObject runSearch(HashMap<String, JSONObject> currMap) throws ServletException {
    JSONObject qJson = new JSONObject();

    try {

      for (Map.Entry<String, JSONObject> entry : currMap.entrySet()) {
        JSONObject resultAllJson = new JSONObject();
        String key = entry.getKey();
        JSONObject json = (JSONObject) entry.getValue();
        String queryVal = json.getString("query");

        // System.out.println("query: " + json.toString());

        // continue with properties list
        String searchType = null;
        int limit = 10; // default
        String typeStrict = "should"; // default
        ArrayList<String[]> propertiesList = new ArrayList<String[]>();

        if (json.has("type")) {
          searchType = json.getString("type");
        }
        if (json.has("limit")) {
          limit = json.getInt("limit");
        }
        if (json.has("type_strict")) { // Not sure what this variable
          // represents. Skip for now.
          typeStrict = json.getString("type_strict");
        }
        if (json.has("properties")) {
          JSONArray properties = json.getJSONArray("properties");
          for (int i = 0; i < properties.length(); i++) {
            String[] pvPair = new String[2];
            JSONObject jsonProperty = properties.getJSONObject(i);
            String pid = jsonProperty.getString("pid");
            String v = jsonProperty.getString("v");
            if (pid != null && v != null) {
              pvPair[0] = pid;
              pvPair[1] = v;
              propertiesList.add(pvPair);
            }
          }
        }

        // begin search
        JSONArray resultJsonArr = new JSONArray();

        // Solr
        SolrQuery query = getQuery(queryVal, searchType, limit, propertiesList);
        QueryResponse queryResponse = null;
        if (query != null) {
          SolrServer solr = SolrSetup.getSolrServer(getServletContext());
          queryResponse = solr.query(query);
        } else {
          log.error("Query for a search was null");
        }

        SolrDocumentList docs = null;
        if (queryResponse != null) {
          docs = queryResponse.getResults();
        } else {
          log.error("Query response for a search was null");
        }

        if (docs != null) {

          List<SearchResult> results = new ArrayList<SearchResult>();
          for (SolrDocument doc : docs) {
            try {
              String uri = doc.get(VitroSearchTermNames.URI).toString();
              // RY 7/1/2011
              // Comment was: VitroSearchTermNames.NAME_RAW is a multivalued field, so doc.get()
              // returns a list.
              // Changed to: VitroSearchTermNames.NAME_RAW is a multivalued field, so doc.get()
              // could return a list
              // But in fact: I'm no longer seeing any lists returned for individuals with multiple
              // labels. Not sure
              // if this is new behavior or what. ???
              Object nameRaw = doc.get(VitroSearchTermNames.NAME_RAW);
              String name = null;
              if (nameRaw instanceof List<?>) {
                @SuppressWarnings("unchecked")
                List<String> nameRawList = (List<String>) nameRaw;
                name = nameRawList.get(0);
              } else {
                name = (String) nameRaw;
              }

              SearchResult result = new SearchResult(name, uri);

              // populate result for Google Refine
              JSONObject resultJson = new JSONObject();
              resultJson.put("score", doc.getFieldValue("score"));
              String modUri = result.getUri().replace("#", "%23");
              resultJson.put("id", modUri);
              resultJson.put("name", result.getLabel());

              Collection<Object> rdfTypes = doc.getFieldValues(VitroSearchTermNames.RDFTYPE);
              JSONArray typesJsonArr = new JSONArray();
              if (rdfTypes != null) {

                for (Object rdfType : rdfTypes) {

                  // e.g.
                  // http://aims.fao.org/aos/geopolitical.owl#area
                  String type = (String) rdfType;
                  int lastIndex2 = type.lastIndexOf('/') + 1;
                  String typeName = type.substring(lastIndex2);
                  typeName = typeName.replace("#", ":");
                  JSONObject typesJson = new JSONObject();
                  typesJson.put("id", type);
                  typesJson.put("name", typeName);
                  typesJsonArr.put(typesJson);
                }
              }

              resultJson.put("type", typesJsonArr);
              resultJson.put("match", "false");
              resultJsonArr.put(resultJson);

            } catch (Exception e) {
              log.error(
                  "problem getting usable individuals from search " + "hits" + e.getMessage());
            }
          }
        } else {
          log.error("Docs for a search was null");
        }
        resultAllJson.put("result", resultJsonArr);
        qJson.put(key, resultAllJson);
        // System.out.println("results: " + qJson.toString());
      }

    } catch (JSONException ex) {
      log.error("JSONException: " + ex);
      throw new ServletException("JSONReconcileServlet JSONException: " + ex);
    } catch (SolrServerException ex) {
      log.error("JSONException: " + ex);
      throw new ServletException("JSONReconcileServlet SolrServerException: " + ex);
    }

    return qJson;
  }