@NonNull
    private static Set<Geocache> loadCachesFromGeocodes(final Set<String> geocodes, final EnumSet<LoadFlag> loadFlags) {

        if (CollectionUtils.isEmpty(geocodes)) {
            return Collections.emptySet();
        }

        try (ContextLogger cLog = new ContextLogger(Log.LogLevel.DEBUG, "DataStore.loadCachesFromGeoCodes(#%d)", geocodes.size())) {
            cLog.add("flags:%s", loadFlags);

            // do not log the entire collection of geo codes to the debug log. This can be more than 100 kB of text for large lists!
            cLog.add("gc" + cLog.toStringLimited(geocodes, 10));

            init();

            final StringBuilder query = new StringBuilder(QUERY_CACHE_DATA);
            if (loadFlags.contains(LoadFlag.OFFLINE_LOG)) {
                query.append(',').append(dbTableLogsOffline).append(".log");
            }

            query.append(" FROM ").append(dbTableCaches);
            if (loadFlags.contains(LoadFlag.OFFLINE_LOG)) {
                query.append(" LEFT OUTER JOIN ").append(dbTableLogsOffline).append(" ON ( ").append(dbTableCaches).append(".geocode == ").append(dbTableLogsOffline).append(".geocode) ");
            }

            query.append(" WHERE ").append(dbTableCaches).append('.');
            query.append(whereGeocodeIn(geocodes));

            try (Cursor cursor = database.rawQuery(query.toString(), null)) {
                final Set<Geocache> caches = new HashSet<>();
                int logIndex = -1;

                while (cursor.moveToNext()) {
                    final Geocache cache = createCacheFromDatabaseContent(cursor);

                    if (loadFlags.contains(LoadFlag.ATTRIBUTES)) {
                        cache.setAttributes(loadAttributes(cache.getGeocode()));
                    }

                    if (loadFlags.contains(LoadFlag.WAYPOINTS)) {
                        final List<Waypoint> waypoints = loadWaypoints(cache.getGeocode());
                        if (CollectionUtils.isNotEmpty(waypoints)) {
                            cache.setWaypoints(waypoints, false);
                        }
                    }

                    if (loadFlags.contains(LoadFlag.SPOILERS)) {
                        final List<Image> spoilers = loadSpoilers(cache.getGeocode());
                        cache.setSpoilers(spoilers);
                    }

                    if (loadFlags.contains(LoadFlag.LOGS)) {
                        final Map<LogType, Integer> logCounts = loadLogCounts(cache.getGeocode());
                        if (MapUtils.isNotEmpty(logCounts)) {
                            cache.getLogCounts().clear();
                            cache.getLogCounts().putAll(logCounts);
                        }
                    }

                    if (loadFlags.contains(LoadFlag.INVENTORY)) {
                        final List<Trackable> inventory = loadInventory(cache.getGeocode());
                        if (CollectionUtils.isNotEmpty(inventory)) {
                            cache.setInventory(inventory);
                        }
                    }

                    if (loadFlags.contains(LoadFlag.CATEGORIES)) {
                        final List<Category> categories = loadCategories(cache.getGeocode());
                        if (CollectionUtils.isNotEmpty(categories)) {
                            cache.setCategories(categories);
                        }
                    }

                    if (loadFlags.contains(LoadFlag.OFFLINE_LOG)) {
                        if (logIndex < 0) {
                            logIndex = cursor.getColumnIndex("log");
                        }
                        if (logIndex >= 0) {
                            cache.setHasLogOffline(!cursor.isNull(logIndex));
                        }
                    }
                    cache.addStorageLocation(StorageLocation.DATABASE);
                    cacheCache.putCacheInCache(cache);

                    caches.add(cache);
                }

                final Map<String, Set<Integer>> cacheLists = loadLists(geocodes);
                for (final Geocache geocache : caches) {
                    final Set<Integer> listIds = cacheLists.get(geocache.getGeocode());
                    if (listIds != null) {
                        geocache.setLists(listIds);
                    }
                }
                cLog.addReturnValue("#" + caches.size());
                return caches;
            }
        }
    }
Load caches.

@return Set of loaded caches. Never null.
main/src/main/java/cgeo/geocaching/storage/DataStore.java