@SuppressWarnings({"PMD.NPathComplexity", "PMD.ExcessiveMethodLength"}) //splitting would not help readability
    private Waypoint parseSingleWaypoint(final GeopointWrapper match, final int counter) {
        final Geopoint point = match.getGeopoint();
        final int start = match.getStart();
        final int end = match.getEnd();
        final String text = match.getText();
        final String matchedText = text.substring(start, end);

        final String textBeforeIndex = TextUtils.getTextBeforeIndexUntil(text, start, "\n");
        final String[] wordsBefore = TextUtils.getWords(textBeforeIndex);
        final String lastWordBefore = wordsBefore.length == 0 ? "" : wordsBefore[wordsBefore.length - 1];

        //try to get a waypointType
        final WaypointType wpType = parseWaypointType(text.substring(Math.max(0, start - 20), start), lastWordBefore);

        //try to get a name and a prefix
        final ImmutablePair<String, String> parsedNameAndPrefix = parseNameAndPrefix(wordsBefore, wpType);
        String name = parsedNameAndPrefix.getLeft();
        final String prefix = parsedNameAndPrefix.getRight();
        if (StringUtils.isBlank(name)) {
            name = namePrefix + " " + counter;
        }

        //try to get visited-flag
        final boolean isVisited = textBeforeIndex.contains(PARSING_VISITED_FLAG);

        //create the waypoint
        final Waypoint waypoint = new Waypoint(name, wpType, true);
        waypoint.setPreprojectedCoords(point);
        waypoint.setPrefix(prefix);
        waypoint.setVisited(isVisited);

        String afterCoords = TextUtils.getTextAfterIndexUntil(text, end - 1, null);

        //parse calculated coordinates
        if (PARSING_CALCULATED_COORD.equals(matchedText)) {
            final String configAndMore = text.substring(start);
            final CalculatedCoordinate cc = new CalculatedCoordinate();
            final int parseEnd = cc.setFromConfig(configAndMore);
            if (parseEnd < 0 || parseEnd > configAndMore.length() ||
                    configAndMore.charAt(parseEnd - 1) != '}' || !cc.isFilled()) {
                return null;
            }
            waypoint.setCalcStateConfig(cc.toConfig());
            afterCoords = configAndMore.substring(parseEnd);
        }

        //try to get a projection
        final int pidx = waypoint.setProjectionFromConfig(afterCoords, 0);
        if (pidx > 0) {
            afterCoords = afterCoords.substring(pidx);
        } else {
            waypoint.setCoords(point);
        }

        //recalculate waypoint coord if necessary / possible
        if (this.cache != null && this.cache.getVariables() != null) {
            waypoint.recalculateVariableDependentValues(this.cache.getVariables());
        }
        // parse calculated coordinates in legacy format
        if (LEGACY_PARSING_COORD_FORMULA.equals(matchedText)) {

            final List<Pair<String, String>> coords = FormulaUtils.scanForCoordinates(Collections.singleton(afterCoords), null);
            if (!coords.isEmpty()) {
                final CalculatedCoordinate cc = new CalculatedCoordinate();
                String lonString = coords.get(0).second;
                if (lonString.endsWith("\"")) {
                    lonString = lonString.substring(0, lonString.length() - 1);
                }
                cc.setLatitudePattern(coords.get(0).first);
                cc.setLongitudePattern(lonString);
                waypoint.setCalcStateConfig(cc.toConfig());
                // try to evaluate valid coordinates
                if (this.cache != null && this.cache.getVariables() != null) {
                    waypoint.setCoordsPure(cc.calculateGeopoint(this.cache.getVariables()::getValue));
                }
                int idx = afterCoords.indexOf(lonString);
                if (idx > 0) {
                    idx += lonString.length();
                    while (true) {
                        final int sepIdx = afterCoords.indexOf("|", idx);
                        if (sepIdx < 0 || sepIdx - idx > 25) {
                            break;
                        }
                        final int equalIdx = afterCoords.indexOf("=", idx);
                        if (equalIdx >= 0 && equalIdx < sepIdx) {
                            final String var = afterCoords.substring(idx, equalIdx).trim();
                            final String value = afterCoords.substring(equalIdx + 1, sepIdx).trim();
                            if (!StringUtils.isBlank(var)) {
                                addVariable(var, value, false);
                            }
                        }
                        idx = sepIdx + 1;
                    }
                    afterCoords = afterCoords.substring(idx);
                }
            }
        }

        //try to get a user note
        final String userNote = parseUserNote(afterCoords, 0);
        if (!StringUtils.isBlank(userNote)) {
            waypoint.setUserNote(userNote.trim());
        }

        return waypoint;
    }
returns waypoints previously parsed using {@link #parse(String)}
main/src/main/java/cgeo/geocaching/models/CacheArtefactParser.java