@SuppressWarnings({"PMD.NPathComplexity", "PMD.ExcessiveMethodLength"})
    public boolean gatherMissingFrom(@Nullable final Geocache other) {
        if (other == null) {
            return false;
        }
        if (other == this) {
            return true;
        }

        updated = System.currentTimeMillis();
        //storageLocation.addAll(other.getStorageLocation()); // seems correct but has side effects / failing tests

        // if parsed cache is not yet detailed and stored is, the information of
        // the parsed cache will be overwritten
        if (!detailed && other.detailed) {
            detailed = true;
            detailedUpdate = other.detailedUpdate;
            // boolean values must be enumerated here. Other types are assigned outside this if-statement
            finalDefined = other.finalDefined;

            if (StringUtils.isBlank(getHint())) {
                hint = other.getHint();
            }
            if (StringUtils.isBlank(getShortDescription())) {
                shortdesc = other.getShortDescription();
            }
            if (attributes.isEmpty() && other.attributes != null) {
                attributes.addAll(other.attributes);
            }
        }

        if (premiumMembersOnly == null) {
            premiumMembersOnly = other.premiumMembersOnly;
        }
        if (found == null) {
            found = other.found;
        }
        if (didNotFound == null) {
            didNotFound = other.didNotFound;
        }
        if (disabled == null) {
            disabled = other.disabled;
        }
        if (favorite == null) {
            favorite = other.favorite;
        }
        if (archived == null) {
            archived = other.archived;
        }
        if (onWatchlist == null) {
            onWatchlist = other.onWatchlist;
        }
        if (hasLogOffline == null) {
            hasLogOffline = other.hasLogOffline;
        }
        if (visitedDate == 0) {
            visitedDate = other.visitedDate;
        }
        if (lists.isEmpty()) {
            lists.addAll(other.lists);
        }
        if (StringUtils.isBlank(geocode)) {
            geocode = other.geocode;
        }
        if (StringUtils.isBlank(cacheId)) {
            cacheId = other.cacheId;
        }
        if (StringUtils.isBlank(guid)) {
            guid = other.guid;
        }
        if (cacheType == CacheType.UNKNOWN) {
            cacheType = other.cacheType;
        }
        if (StringUtils.isBlank(name)) {
            name = other.name;
        }
        if (StringUtils.isBlank(ownerDisplayName)) {
            ownerDisplayName = other.ownerDisplayName;
        }
        if (StringUtils.isBlank(ownerUserId)) {
            ownerUserId = other.ownerUserId;
        }
        if (hidden == null) {
            hidden = other.hidden;
        }
        if (lastFound == null) {
            lastFound = other.lastFound;
        }
        if (size == CacheSize.UNKNOWN) {
            size = other.size;
        }
        if (difficulty == 0) {
            difficulty = other.difficulty;
        }
        if (terrain == 0) {
            terrain = other.terrain;
        }
        if (direction == null) {
            direction = other.direction;
        }
        if (distance == null) {
            distance = other.distance;
        }
        if (StringUtils.isBlank(getLocation())) {
            location = other.getLocation();
        }

        personalNote.gatherMissingDataFrom(other.personalNote);

        if (StringUtils.isBlank(getDescription())) {
            description = other.getDescription();
        }
        if (favoritePoints == -1) {
            favoritePoints = other.favoritePoints;
        }
        if (rating == 0) {
            rating = other.rating;
        }
        if (votes == 0) {
            votes = other.votes;
        }
        if (myVote == 0) {
            myVote = other.myVote;
        }
        if (tier == null || Tier.NONE == tier) {
            tier = other.tier;
        }
        if (categories.isEmpty()) {
            setCategories(other.getCategories());
        }

        mergeWaypoints(other.waypoints, false);

        if (spoilers == null) {
            spoilers = other.spoilers;
        }
        if (inventory == null) {
            // If inventoryItems is 0, it can mean both
            // "don't know" or "0 items". Since we cannot distinguish
            // them here, only populate inventoryItems from
            // old data when we have to do it for inventory.
            setInventory(other.inventory);
        }
        if (logCounts.isEmpty()) {
            logCounts = other.logCounts;
        }


        final boolean takeOverUserModCoords = !hasUserModifiedCoords();
        if (userModifiedCoords == null) {
            userModifiedCoords = other.userModifiedCoords;
        }

        if (takeOverUserModCoords && other.hasUserModifiedCoords()) {
            final Waypoint original = other.getOriginalWaypoint();
            if (original != null) {
                original.setCoords(getCoords());
            }
            setCoords(other.getCoords());
        } else {
            if (coords == null) {
                coords = other.coords;
            }
        }
        // if cache has ORIGINAL type waypoint ... it is considered that it has modified coordinates, otherwise not
        if (getOriginalWaypoint() != null) {
            userModifiedCoords = true;
        }

        if (!preventWaypointsFromNote) {
            preventWaypointsFromNote = other.preventWaypointsFromNote;
        }

        if (assignedEmoji == 0) {
            assignedEmoji = other.assignedEmoji;
        }

        if (searchCacheData == null) {
            searchCacheData = other.searchCacheData;
        }

        this.eventTimesInMin.reset(); // will be recalculated if/when necessary
        return isEqualTo(other);
    }
Gather missing information for new Geocache object from the stored Geocache object.
This is called in the new Geocache parsed from website to set information not yet
parsed.

@param other the other version, or null if non-existent
@return true if this cache is "equal" to the other version
main/src/main/java/cgeo/geocaching/models/Geocache.java