src/main/java/com/github/fge/grappa/matchers/join/JoinMatcher.java
@Override
    public final <V> boolean match(final MatcherContext<V> context)
    {
        /*
         * TODO! Check logic
         *
         * At this point, if we have enough cycles, we can't determined whether
         * our joining rule would match empty... Which is illegal.
         */
        int cycles = 0;
        if (!joined.getSubContext(context).runMatcher())
            return enoughCycles(cycles);

        cycles++;

        Object snapshot = context.getValueStack().takeSnapshot();
        int beforeCycle = context.getCurrentIndex();

        while (runAgain(cycles) && matchCycle(context, beforeCycle)) {
            beforeCycle = context.getCurrentIndex();
            snapshot = context.getValueStack().takeSnapshot();
            cycles++;
        }

        context.getValueStack().restoreSnapshot(snapshot);
        context.setCurrentIndex(beforeCycle);

        return enoughCycles(cycles);
    }
@Override
    public final <V> boolean match(final MatcherContext<V> context)
    {
        /*
         * TODO! Check logic
         *
         * At this point, if we have enough cycles, we can't determined whether
         * our joining rule would match empty... Which is illegal.
         */
        int cycles = 0;
        if (!joined.getSubContext(context).runMatcher())
            return enoughCycles(cycles);

        cycles++;

        Object snapshot = context.getValueStack().takeSnapshot();
        int beforeCycle = context.getCurrentIndex();

        while (runAgain(cycles) && matchCycle(context, beforeCycle)) {
            beforeCycle = context.getCurrentIndex();
            snapshot = context.getValueStack().takeSnapshot();
            cycles++;
        }

        context.getValueStack().restoreSnapshot(snapshot);
        context.setCurrentIndex(beforeCycle);

        return enoughCycles(cycles);
    }
Tries a match on the given MatcherContext.

@param context the MatcherContext
@return true if the match was successful