public static cgCache getCache(final String geoCode) {
    final Parameters params = new Parameters("cache_code", geoCode, "fields", SERVICE_CACHE_FIELDS);
    final JSONObject data = request(ConnectorFactory.getConnector(geoCode), SERVICE_CACHE, params);

    if (data == null) {
      return null;
    }

    final cgCache cache = parseCache(data);

    long time = new Date().getTime();
    cache.setUpdated(time);
    cache.setDetailedUpdate(time);

    return cache;
  }
  private static cgCache parseCache(final JSONObject response) {
    final cgCache cache = new cgCache();
    cache.setReliableLatLon(true);
    try {
      cache.setGeocode(response.getString(CACHE_CODE));
      cache.setName(response.getString(CACHE_NAME));
      // not used: names
      setLocation(cache, response.getString(CACHE_LOCATION));
      cache.setType(getCacheType(response.getString(CACHE_TYPE)));

      final String status = response.getString(CACHE_STATUS);
      cache.setDisabled(status.equalsIgnoreCase("Temporarily unavailable"));
      cache.setArchived(status.equalsIgnoreCase("Archived"));

      // not used: url
      final JSONObject owner = response.getJSONObject(CACHE_OWNER);
      cache.setOwner(parseUser(owner));

      cache.getLogCounts().put(LogType.FOUND_IT, response.getInt(CACHE_FOUNDS));
      cache.getLogCounts().put(LogType.DIDNT_FIND_IT, response.getInt(CACHE_NOTFOUNDS));
      cache.setSize(getCacheSize(response));
      cache.setDifficulty((float) response.getDouble(CACHE_DIFFICULTY));
      cache.setTerrain((float) response.getDouble(CACHE_TERRAIN));
      if (!response.isNull(CACHE_RATING)) {
        cache.setRating((float) response.getDouble(CACHE_RATING));
      }
      cache.setVotes(response.getInt(CACHE_VOTES));

      cache.setFavoritePoints(response.getInt(CACHE_RECOMMENDATIONS));
      // not used: req_password
      cache.setDescription(response.getString(CACHE_DESCRIPTION));
      cache.setHint(Html.fromHtml(response.getString(CACHE_HINT)).toString());
      // not used: hints

      final JSONArray images = response.getJSONArray(CACHE_IMAGES);
      if (images != null) {
        JSONObject imageResponse;
        for (int i = 0; i < images.length(); i++) {
          imageResponse = images.getJSONObject(i);
          if (imageResponse.getBoolean(CACHE_IMAGE_IS_SPOILER)) {
            final String title = imageResponse.getString(CACHE_IMAGE_CAPTION);
            final String url =
                absoluteUrl(imageResponse.getString(CACHE_IMAGE_URL), cache.getGeocode());
            final cgImage image = new cgImage(url, title);
            if (cache.getSpoilers() == null) {
              cache.setSpoilers(new ArrayList<cgImage>());
            }
            cache.getSpoilers().add(image);
          }
        }
      }

      // not used: attrnames
      cache.setLogs(parseLogs(response.getJSONArray(CACHE_LATEST_LOGS)));
      cache.setHidden(parseDate(response.getString(CACHE_HIDDEN)));

      cache.setUpdated(System.currentTimeMillis());
      cache.setDetailedUpdate(cache.getUpdated());
      cache.setDetailed(true);

      // save full detailed caches
      cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB));
    } catch (JSONException e) {
      Log.e("OkapiClient.parseCache", e);
    }
    return cache;
  }