public static Map<String, List<String>> parseGrouped(final String featureDir,
                                                         final List<Pair<Pattern, BiFunction<String, String, String>>> parameterMatchers) throws IOException {
        final Map<String, List<String>> gremlins = new LinkedHashMap<>();
        Files.find(Paths.get(featureDir),
                   Integer.MAX_VALUE,
                (filePath, fileAttr) -> fileAttr.isRegularFile() && filePath.toString().endsWith(".feature")).
                sorted().
                forEach(f -> {
                    String currentGremlin = "";
                    boolean openTriples = false;
                    boolean skipIgnored = false;
                    String scenarioName = "";
                    Map<String,String> parameters = new HashMap<>();

                    try {
                        final List<String> lines = Files.readAllLines(f, StandardCharsets.UTF_8);
                        for (String line : lines) {
                            String cleanLine = line.trim();
                            if (cleanLine.startsWith("Scenario:")) {
                                scenarioName = cleanLine.split(":")[1].trim();
                                skipIgnored = false;
                                parameters.clear();
                            } else if (!parameterMatchers.isEmpty() && cleanLine.startsWith("And using the parameter")) {
                                final Matcher m = generalParameterPattern.matcher(cleanLine);
                                if (m.matches()) {
                                    parameters.put(m.group(1), matchAndTransform(m.group(1), StringEscapeUtils.unescapeJava(m.group(3)), parameterMatchers));
                                } else {
                                    throw new IllegalStateException(String.format("Could not read parameters at: %s", cleanLine));
                                }
                            } else if (cleanLine.contains("nothing should happen because") || cleanLine.contains("the result should be a tree with a structure of")) {
                                skipIgnored = true;
                            } else if (cleanLine.startsWith("And the graph should return")) {
                                gremlins.computeIfAbsent(scenarioName, k -> new ArrayList<>()).add(applyParametersToGremlin(StringEscapeUtils.unescapeJava(cleanLine.substring(cleanLine.indexOf("\"") + 1, cleanLine.lastIndexOf("\""))), parameters));
                            } else if (cleanLine.startsWith("\"\"\"")) {
                                openTriples = !openTriples;
                                if (!skipIgnored && !openTriples) {
                                    currentGremlin = applyParametersToGremlin(currentGremlin, parameters);
                                    gremlins.computeIfAbsent(scenarioName, k -> new ArrayList<>()).add(currentGremlin);
                                    currentGremlin = "";
                                }
                            } else if (openTriples && !skipIgnored) {
                                currentGremlin += cleanLine;
                            }
                        }
                    } catch (IOException ioe) {
                        throw new RuntimeException(ioe);
                    }
                });

        return gremlins;
    }
Parses features to a {@code Map} structure of the test name as the key with a {@code List} of Gremlin strings
for the value.

@param featureDir The root directory where feature files can be found including subdirectories
@param parameterMatchers list of pattern/functions that will transform a parameter from its Gherkin form to
                         another format triggering that new formatted string to be inserted into the Gremlin
                         itself
gremlin-language/src/main/java/org/apache/tinkerpop/gremlin/language/corpus/FeatureReader.java