@SuppressWarnings("checkstyle:ModifiedControlVariable")
    public List<VoiceHint> postProcess(final List<VoiceHint> inputs, final double catchingRange, final double minRange) {
        final List<VoiceHint> results = new ArrayList<>();
        VoiceHint inputLast = null;
        VoiceHint inputLastSaved = null;
        for (int hintIdx = 0; hintIdx < inputs.size(); hintIdx++) {
            final VoiceHint input = inputs.get(hintIdx);
            VoiceHint nextInput = null;
            if (hintIdx + 1 < inputs.size()) {
                nextInput = inputs.get(hintIdx + 1);
            }

            if (nextInput == null) {
                if (input.cmd == VoiceHint.C && !input.goodWay.isLinktType()) {
                    if (input.goodWay.getPrio() < input.maxBadPrio && (inputLastSaved != null && inputLastSaved.distanceToNext > catchingRange)) {
                        results.add(input);
                    } else {
                        if (inputLast != null) { // when drop add distance to last
                            inputLast.distanceToNext += input.distanceToNext;
                        }
                        continue;
                    }
                } else {
                    results.add(input);
                }
            } else {
                if ((inputLastSaved != null && inputLastSaved.distanceToNext > catchingRange) || input.distanceToNext > catchingRange) {
                    if (input.cmd == VoiceHint.C && !input.goodWay.isLinktType()) {
                        if (input.goodWay.getPrio() < input.maxBadPrio
                                && (inputLastSaved != null && inputLastSaved.distanceToNext > minRange)
                                && (input.distanceToNext > minRange)) {
                            // add only on prio
                            results.add(input);
                            inputLastSaved = input;
                        } else {
                            if (inputLastSaved != null) { // when drop add distance to last
                                inputLastSaved.distanceToNext += input.distanceToNext;
                            }
                        }
                    } else {
                        // add all others
                        // ignore motorway / primary continue
                        if (((input.goodWay.getPrio() != 28) &&
                                (input.goodWay.getPrio() != 30) &&
                                (input.goodWay.getPrio() != 26))
                                || input.isRoundabout()
                                || Math.abs(input.angle) > 21.f) {
                            results.add(input);
                            inputLastSaved = input;
                        } else {
                            if (inputLastSaved != null) { // when drop add distance to last
                                inputLastSaved.distanceToNext += input.distanceToNext;
                            }
                        }
                    }
                } else if (input.distanceToNext < catchingRange) {
                    double dist = input.distanceToNext;
                    float angles = input.angle;
                    final int i = 1;
                    boolean save = false;

                    dist += nextInput.distanceToNext;
                    angles += nextInput.angle;

                    if (input.cmd == VoiceHint.C && !input.goodWay.isLinktType()) {
                        if (input.goodWay.getPrio() < input.maxBadPrio) {
                            if (inputLastSaved != null && inputLastSaved.cmd != VoiceHint.C
                                    && (inputLastSaved.distanceToNext > minRange)
                                    && transportMode != VoiceHintList.TRANS_MODE_CAR) {
                                // add when straight and not linktype
                                // and last vh not straight
                                save = true;
                                // remove when next straight and not linktype
                                if (nextInput != null &&
                                        nextInput.cmd == VoiceHint.C &&
                                        !nextInput.goodWay.isLinktType()) {
                                    input.distanceToNext += nextInput.distanceToNext;
                                    hintIdx++;
                                }
                            }

                        } else {
                            if (inputLastSaved != null) { // when drop add distance to last
                                inputLastSaved.distanceToNext += input.distanceToNext;
                            }
                        }
                    } else if (VoiceHint.is180DegAngle(input.angle)) {
                        // add u-turn, 180 degree
                        save = true;
                    } else if (transportMode == VoiceHintList.TRANS_MODE_CAR && Math.abs(angles) > 180 - SIGNIFICANT_ANGLE) {
                        // add when inc car mode and u-turn, collects e.g. two left turns in range
                        input.angle = angles;
                        input.calcCommand();
                        input.distanceToNext += nextInput.distanceToNext;
                        save = true;
                        hintIdx++;
                    } else if (Math.abs(angles) < SIGNIFICANT_ANGLE && input.distanceToNext < minRange) {
                        input.angle = angles;
                        input.calcCommand();
                        input.distanceToNext += nextInput.distanceToNext;
                        save = true;
                        hintIdx++;
                    } else if (Math.abs(input.angle) > SIGNIFICANT_ANGLE) {
                        // add when angle above 22.5 deg
                        save = true;
                    } else if (Math.abs(input.angle) < SIGNIFICANT_ANGLE) {
                        // add when angle below 22.5 deg ???
                        // save = true;
                    } else {
                        // otherwise ignore but add distance to next
                        if (nextInput != null) { // when drop add distance to last
                            nextInput.distanceToNext += input.distanceToNext;
                        }
                        save = false;
                    }

                    if (save) {
                        results.add(input); // add when last
                        inputLastSaved = input;
                    }
                } else {
                    results.add(input);
                    inputLastSaved = input;
                }
            }
            inputLast = input;
        }

        return results;
    }
process voice hints. Uses VoiceHint objects
for both input and output. Input is in reverse
order (from target to start), but output is
returned in travel-direction and only for
those nodes that trigger a voice hint.
<p>
Input objects are expected for every segment
of the track, also for those without a junction
<p>
VoiceHint objects in the output list are enriched
by the voice-command, the total angle and the distance
to the next hint

@param inputs tracknodes, un reverse order
@return voice hints, in forward order
main/src/main/java/cgeo/geocaching/brouter/core/VoiceHintProcessor.java