void frame(int offset, boolean useModelNumber) throws ScriptException {
		useModelNumber = true;
		// for now -- as before -- remove to implement
		// frame/model difference
		if (statementLength <= offset)
			badArgumentCount();
		if (statement[offset].tok == Token.hyphen) {
			++offset;
			checkStatementLength(offset + 1);
			if (statement[offset].tok != Token.integer || statement[offset].intValue != 1)
				invalidArgument();
			viewer.setAnimationPrevious();
			return;
		}
		int frameNumber = -1;
		int frameNumber2 = -1;
		boolean isPlay = false;
		boolean isRange = false;
		boolean isAll = false;
		while (offset < statementLength) {
			Token cmd = statement[offset];
			int tok = cmd.tok;
			switch (tok) {
			case Token.all:
				isAll = true;
			case Token.asterisk:
				break;
			case Token.none:
				break;
			case Token.integer:
				if (frameNumber == -1) {
					frameNumber = cmd.intValue;
				}
				else {
					frameNumber2 = cmd.intValue;
				}
				break;
			case Token.play:
				isPlay = true;
				break;
			case Token.range:
				isRange = true;
				break;
			default:
				frameControl(cmd, false);
				return;
			}

			if (offset == statementLength - 1) {
				if (isAll) {
					viewer.setAnimationRange(-1, -1);
					viewer.setDisplayModelIndex(-1);
					return;
				}
				int modelIndex = (useModelNumber ? viewer.getModelNumberIndex(frameNumber) : frameNumber - 1);
				if (!isPlay && !isRange || modelIndex >= 0) {
					viewer.setDisplayModelIndex(modelIndex);
				}
				if (isPlay || isRange) {
					if (isRange || frameNumber2 >= 0) {
						int modelIndex2 = (useModelNumber ? viewer.getModelNumberIndex(frameNumber2) : frameNumber2 - 1);
						viewer.setAnimationDirection(1);
						viewer.setAnimationRange(modelIndex, modelIndex2);
					}
					if (isPlay)
						viewer.resumeAnimation();
				}
			}
			offset++;
		}
	}