private void extractOperator(Class<? extends IOperatorToken> operatorClass) {

		Stack<Integer> positions = new Stack<Integer>();

		// find operator positions
		for (int i = size() - 1; i >= 0; i--) {
			if (operatorClass.isInstance(get(i))) {
				positions.push(i);
			}
		}

		// offset, used when positions are updated while replacing tokens
		int offset = 0;

		while (!positions.isEmpty()) {

			// get position of the next token
			int pos = positions.pop() + offset;

			IToken operatorToken = get(pos);

			if (operatorToken instanceof TokenBinaryOperator) {

				TokenBinaryOperator opToken = (TokenBinaryOperator) operatorToken;

				// get operands
				TokenList leftArg = get(pos - 1).wrapInTokenList();
				TokenList rightArg = get(pos + 1).wrapInTokenList();

				// build an operation
				Operation op = opToken.toOperation(leftArg, rightArg);

				// discard used tokens
				subList(pos - 1, pos + 2).clear();
				// put back the operation
				add(pos - 1, op);
				// shift offset
				offset -= 2;

			} else if (operatorToken instanceof TokenUnaryOperatorLeft) {

				TokenUnaryOperatorLeft opToken = (TokenUnaryOperatorLeft) operatorToken;

				// get operand
				TokenList leftArg = get(pos - 1).wrapInTokenList();

				// build an operation
				Operation op = opToken.toOperation(leftArg);

				// discard used tokens
				subList(pos - 1, pos + 1).clear();
				// put back the operation
				add(pos - 1, op);
				// shift offset
				offset -= 1;

			} else if (operatorToken instanceof TokenUnaryOperatorRight) {

				TokenUnaryOperatorRight opToken = (TokenUnaryOperatorRight) operatorToken;

				// variable for left operand
				TokenList rightArg = get(pos + 1).wrapInTokenList();

				// build an operation
				Operation op = opToken.toOperation(rightArg);

				// discard used tokens
				subList(pos, pos + 2).clear();
				// put back the operation
				add(pos, op);
				// shift offset
				offset -= 1;
			}
		}
	}