public static void saveCaches(final Collection<Geocache> caches, final Set<LoadFlags.SaveFlag> saveFlags) {
        if (CollectionUtils.isEmpty(caches)) {
            return;
        }

        withAccessLock(() -> {

            try (ContextLogger cLog = new ContextLogger("DataStore.saveCaches(#%d,flags:%s)", caches.size(), saveFlags)) {

                cLog.add("gc" + cLog.toStringLimited(caches, 10, c -> c == null ? "-" : c.getGeocode()));

                final List<String> cachesFromDatabase = new ArrayList<>();
                final Map<String, Geocache> existingCaches = new HashMap<>();

                // first check which caches are in the memory cache
                for (final Geocache cache : caches) {
                    final String geocode = cache.getGeocode();
                    final Geocache cacheFromCache = cacheCache.getCacheFromCache(geocode);
                    if (cacheFromCache == null) {
                        cachesFromDatabase.add(geocode);
                    } else {
                        existingCaches.put(geocode, cacheFromCache);
                    }
                }

                // then load all remaining caches from the database in one step
                for (final Geocache cacheFromDatabase : loadCaches(cachesFromDatabase, LoadFlags.LOAD_ALL_DB_ONLY)) {
                    existingCaches.put(cacheFromDatabase.getGeocode(), cacheFromDatabase);
                }

                final List<Geocache> toBeStored = new ArrayList<>();
                final List<Geocache> toBeUpdated = new ArrayList<>();
                // Merge with the data already stored in the CacheCache or in the database if
                // the cache had not been loaded before, and update the CacheCache.
                // Also, a DB update is required if the merge data comes from the CacheCache
                // (as it may be more recent than the version in the database), or if the
                // version coming from the database is different than the version we are entering
                // into the cache (that includes absence from the database).
                for (final Geocache cache : caches) {
                    final String geocode = cache.getGeocode();
                    final Geocache existingCache = existingCaches.get(geocode);
                    final boolean isOffline = isOffline(geocode, cache.getGuid());
                    boolean dbUpdateRequired = !isOffline || (cacheCache.getCacheFromCache(geocode) != null);
                    if (isOffline) {
                        dbUpdateRequired |= !cache.gatherMissingFrom(existingCache);
                    }
                    // parse the note AFTER merging the local information in
                    dbUpdateRequired |= cache.addCacheArtefactsFromNotes();
                    cache.addStorageLocation(StorageLocation.CACHE);
                    cacheCache.putCacheInCache(cache);

                    // Only save the cache in the database if it is requested by the caller and
                    // the cache contains detailed information.
                    if (saveFlags.contains(SaveFlag.DB) && dbUpdateRequired) {
                        toBeStored.add(cache);
                    } else if (existingCache != null && existingCache.isDisabled() != cache.isDisabled()) {
                        // Update the disabled status in the database if it changed
                        toBeUpdated.add(cache);
                    }
                }

                for (final Geocache geocache : toBeStored) {
                    storeIntoDatabase(geocache);
                }

                for (final Geocache geocache : toBeUpdated) {
                    updateDisabledStatus(geocache);
                }
            }
        });

    }
Save/store a cache to the CacheCache

@param caches the caches to save in the CacheCache/DB
main/src/main/java/cgeo/geocaching/storage/DataStore.java