int origin = mymatch.index;  int numRepeats = 0;
    boolean match(CharIndexed input, REMatch mymatch) {	int origin = mymatch.index;	// number of times we've matched so far	int numRepeats = 0; 		// Possible positions for the next repeat to match at	REMatch newMatch = mymatch;	REMatch last = null;	REMatch current;	// Add the '0-repeats' index	// positions.elementAt(z) == position [] in input after <<z>> matches	Vector positions = new Vector();	positions.addElement(newMatch);		// Declare variables used in loop	REMatch doables;	REMatch doablesLast;	REMatch recurrent;	int lastIndex = mymatch.index;	do {	    // Check for stingy match for each possibility.	    if ((stingy && (numRepeats >= min)) || alwaysEmpty) {		REMatch result = matchRest(input, newMatch);		if (result != null) {		    mymatch.assignFrom(result);		    mymatch.empty = (mymatch.index == origin);		    return true;		}		else {	    	// Special case of {0}. It must always match an empty string.		    if (alwaysEmpty) return false;		}	    }	    doables = null;	    doablesLast = null;	    // try next repeat at all possible positions	    for (current = newMatch; current != null; current = current.next) {		recurrent = (REMatch) current.clone();		if (token.match(input, recurrent)) {		    // add all items in current to doables array		    if (doables == null) {			doables = recurrent;			doablesLast = recurrent;		    } else {			// Order these from longest to shortest			// Start by assuming longest (more repeats)			doablesLast.next = recurrent;		    }		    // Find new doablesLast		    while (doablesLast.next != null) {			doablesLast = doablesLast.next;		    }		}	    }	    // if none of the possibilities worked out, break out of do/while	    if (doables == null) break;	    	    // reassign where the next repeat can match	    newMatch = doables;	    	    // increment how many repeats we've successfully found	    ++numRepeats;	    	    positions.addElement(newMatch);	    // doables.index == lastIndex occurs either	    //   (1) when an empty string was the longest	    //       that matched this token.	    //       And this case occurs either	    //         (1-1) when this token is always empty,	    //               for example "()" or "(())".	    //         (1-2) when this token is not always empty	    //               but can match an empty string, for example,	    //               "a*", "(a|)".	    // or	    //   (2) when the same string matches this token many times.	    //       For example, "acbab" itself matches "a.*b" and	    //       its substrings "acb" and "ab" also match.	    if (doables.index == lastIndex) {	        if (doables.empty) {	    	    // Case (1): We break here, otherwise we will fall	    	    //          into an endless loop.		    if (numRepeats < min) numRepeats = min;		    break;		}	        else {		    // Case (2): We cannot break here because, for example,		    // "acbacb" matches "a.*b" up to 2 times but		    // not 3 times.  So we have to check numRepeats >= min.		    // But we do not have to go further until numRepeats == max		    // because the more numRepeats grows, the shorter the		    // substring matching this token becomes. 		    if (numRepeats > min) {			// This means the previous match was successful,			// and that must be the best match.  This match			// resulted in shortening the matched substring.			numRepeats--;	    		positions.remove(positions.size() - 1);			break;		    }		    if (numRepeats == min) break;		}	    }			    lastIndex = doables.index;	} while (numRepeats < max);		// If there aren't enough repeats, then fail	if (numRepeats < min) return false;		// We're greedy, but ease off until a true match is found 	int posIndex = positions.size();		// At this point we've either got too many or just the right amount.	// See if this numRepeats works with the rest of the regexp.	REMatch allResults = null;	REMatch allResultsLast = null;	REMatch results = null;	int indexCount = posIndex - min;	if (indexCount <= 0) {	    // This case occurs when we exited the previous do loop before	    // numRepeats >= min because an empty string matched the token.	    // In this case, an empty string can match as many times as	    // desired.	    indexCount = 1;	}	while (indexCount-- > 0) {	    --posIndex;	    newMatch = (REMatch) positions.elementAt(posIndex);	    results = matchRest(input, newMatch);	    if (results != null) {		if (allResults == null) {		    allResults = results;		    allResultsLast = results;		} else {		    // Order these from longest to shortest		    // Start by assuming longest (more repeats)		    allResultsLast.next = results;		}		// Find new doablesLast		while (allResultsLast.next != null) {		    allResultsLast = allResultsLast.next;		}	    }	    // else did not match rest of the tokens, try again on smaller sample	    // or break out when performing possessive matching	    if (possessive) break;	}	if (allResults != null) {	    mymatch.assignFrom(allResults); // does this get all?	    mymatch.empty = (mymatch.index == origin);	    return true;	}	// If we fall out, no matches.	return false;    }