JoinMatcher: refactor

.match() is only in JoinMatcher now; add two abstract methods which
implementations use to tell whether the number of cycles matched is enough and
whether we should continue running cycles.