private List<String> findArgumentNames(List<List<JoinedArgs>> joinedArgs,
                                           List<List<String>> explicitParameterValues,
                                           List<String> explicitParameterNames) {
        List<String> argumentNames = Lists.newArrayListWithExpectedSize(joinedArgs.get(0).size());
        Multiset<String> paramNames = TreeMultiset.create();

        arguments:
        for (int argumentCounter = 0; argumentCounter < joinedArgs.get(0).size(); argumentCounter++) {
            parameters:
            for (int paramCounter = 0; paramCounter < explicitParameterNames.size(); paramCounter++) {
                String paramName = explicitParameterNames.get(paramCounter);

                boolean formattedValueMatches = true;
                boolean valueMatches = true;
                for (int caseCounter = 0; caseCounter < joinedArgs.size(); caseCounter++) {
                    JoinedArgs args = joinedArgs.get(caseCounter).get(argumentCounter);

                    String parameterValue = explicitParameterValues.get(caseCounter).get(paramCounter);

                    String formattedValue = args.words.get(0).getFormattedValue();
                    if (!formattedValue.equals(parameterValue)) {
                        formattedValueMatches = false;
                    }

                    String value = args.words.get(0).getValue();
                    if (!value.equals(parameterValue)) {
                        valueMatches = false;
                    }

                    if (!formattedValueMatches && !valueMatches) {
                        continue parameters;
                    }
                }

                // on this point either all formatted values match or all values match (or both)
                argumentNames.add(paramName);
                paramNames.add(paramName);
                continue arguments;
            }

            argumentNames.add(null);
        }

        Set<String> usedNames = Sets.newHashSet();
        for (int argumentCounter = 0; argumentCounter < joinedArgs.get(0).size(); argumentCounter++) {
            String name = argumentNames.get(argumentCounter);
            if (name == null || paramNames.count(name) > 1) {
                String origName = getArgumentName(joinedArgs, argumentCounter);
                name = findFreeName(usedNames, origName);
                argumentNames.set(argumentCounter, name);
            }
            usedNames.add(name);

        }

        return argumentNames;
    }
Finds for each JoinedArgs set the best fitting name.
<p>
First it is tried to find a name from the explicitParameterNames list, by comparing the argument values
with the explicit case argument values. If no matching value can be found, the name of the argument is taken.
jgiven-core/src/main/java/com/tngtech/jgiven/report/analysis/CaseArgumentAnalyser.java