@NonNull
    private static Geocache parseCache(final ObjectNode response) {
        final Geocache cache = new Geocache();
        try {

            parseCoreCache(response, cache);

            // not used: url
            // not used: req_password
            // Prepend gc-link to description if available
            final StringBuilder description = new StringBuilder(500);
            if (response.hasNonNull("gc_code")) {
                final String gccode = response.get("gc_code").asText();
                description.append(Geocache.getAlternativeListingText(gccode));
            }
            description.append(response.get(CACHE_DESCRIPTION).asText());
            cache.setDescription(description.toString());

            if (response.has(CACHE_SHORT_DESCRIPTION)) {
                final String shortDescription = StringUtils.trim(response.get(CACHE_SHORT_DESCRIPTION).asText());
                if (StringUtils.isNotEmpty(shortDescription)) {
                    cache.setShortDescription(shortDescription);
                }
            }

            // currently the hint is delivered as HTML (contrary to OKAPI documentation), so we can store it directly
            cache.setHint(response.get(CACHE_HINT).asText());
            // not used: hints

            //set images
            final List<Image> cacheImages = new ArrayList<>();
            final ArrayNode images = (ArrayNode) response.get(CACHE_IMAGES);
            if (images != null) {
                for (final JsonNode imageResponse : images) {
                    final String title = imageResponse.get(CACHE_IMAGE_CAPTION).asText();
                    final String url = absoluteUrl(imageResponse.get(CACHE_IMAGE_URL).asText(), cache.getGeocode());
                    cacheImages.add(new Image.Builder().setUrl(url).setTitle(title).build());
                }
            }
            // all images are added as spoiler images, although OKAPI has spoiler and non spoiler images
            cache.setSpoilers(cacheImages);

            //TODO: Store license per cache
            //cache.setLicense(response.getString("attribution_note"));

            cache.mergeWaypoints(parseWaypoints((ArrayNode) response.path(CACHE_WPTS)), true);

            cache.mergeInventory(parseTrackables((ArrayNode) response.path(CACHE_TRACKABLES)), EnumSet.of(TrackableBrand.GEOKRETY));

            if (response.has(CACHE_IS_WATCHED)) {
                cache.setOnWatchlist(response.get(CACHE_IS_WATCHED).asBoolean());
            }
            if (response.hasNonNull(CACHE_MY_NOTES)) {
                cache.setPersonalNote(response.get(CACHE_MY_NOTES).asText(), true);
            }
            cache.setLogPasswordRequired(response.get(CACHE_REQ_PASSWORD).asBoolean());

            cache.setDetailedUpdatedNow();
            if (cache.isFound()) {
                cache.setVisitedDate(getCacheFoundDate(cache.getGeocode()));
            }
            // save full detailed caches
            DataStore.saveCache(cache, EnumSet.of(SaveFlag.DB));
            DataStore.saveLogs(cache.getGeocode(), parseLogs((ArrayNode) response.path(CACHE_LATEST_LOGS), cache.getGeocode()), true);
        } catch (ClassCastException | NullPointerException e) {
            Log.e("OkapiClient.parseCache", e);
        }
        return cache;
    }
returns list of parsed geocaches (left) and a floag indicating whether there are more results on serer (right)
main/src/main/java/cgeo/geocaching/connector/oc/OkapiClient.java