return output.toString();
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private void foreach(boolean inheritedSkip) {
ForEachToken feToken = (ForEachToken) tokenStream.currentToken();
Iterable iterable = (Iterable) feToken.evaluate(context);
// begin a fresh iteration with a reset index
feToken.setIterator(iterable.iterator());
feToken.resetIndex();
tokenStream.consume();
context.model.enterScope();
context.push(feToken);
try {
// in case we do not want to evaluate the body, we just do a quick
// scan until the matching end
if (inheritedSkip || !feToken.iterator().hasNext()) {
Token contentToken;
while ((contentToken = tokenStream.currentToken()) != null
&& !(contentToken instanceof EndToken)) {
content(true);
}
if (contentToken == null) {
engine.getErrorHandler().error("missing-end", feToken);
} else {
tokenStream.consume();
context.notifyProcessListener(contentToken, Action.END);
}
} else {
while (feToken.iterator().hasNext()) {
context.model.put(feToken.getVarName(), feToken.advance());
addSpecialVariables(feToken, context.model);
// for each iteration we need to rewind to the beginning
// of the for loop
tokenStream.rewind(feToken);
Token contentToken;
while ((contentToken = tokenStream.currentToken()) != null
&& !(contentToken instanceof EndToken)) {
content(false);
}
if (contentToken == null) {
engine.getErrorHandler().error("missing-end", feToken);
} else {
tokenStream.consume();
context.notifyProcessListener(contentToken, Action.END);
}
if (!feToken.isLast()) {
output.append(feToken.getSeparator());
}
}
}
} finally {