protected virtual Expression <T> Unary(IEnumerator <Token> tokens, IDictionary <string, VariableExpression <T> > variables)
        {
            tokens.MoveNext();

            switch (tokens.Current.TokenType)
            {
            case TokenType.Scalar:
                ScalarExpression <T> subExpr = ParseScalarValue(tokens.Current.Value);
                tokens.MoveNext();
                return(subExpr);

            case TokenType.Identifier:
                string identifierName = tokens.Current.Value;
                tokens.MoveNext();

                ConstantExpression <T> consExpr = ConstantFactory.CreateConstant(identifierName);
                if (consExpr != null)
                {
                    return(consExpr);
                }

                VariableExpression <T> varExpr = null;
                if (!variables.TryGetValue(identifierName, out varExpr))
                {
                    varExpr = new VariableExpression <T>(identifierName);
                    variables.Add(identifierName, varExpr);
                }
                return(varExpr);

            case TokenType.Operator:
                Func <IEnumerator <Token>, IDictionary <string, VariableExpression <T> >, Expression <T> > func;
                if (UnaryOperatorHandlers.TryGetValue(tokens.Current.Value, out func))
                {
                    return(func(tokens, variables));
                }
                else
                {
                    throw new SyntaxException(String.Format("Incorrect operator \"{0}\".", tokens.Current.Value));
                }

            case TokenType.Function:
                string funcName = tokens.Current.Value;
                IList <Expression <T> > args = new List <Expression <T> >();

                tokens.MoveNext();
                if (tokens.Current.Value != "(")
                {
                    throw ThrowExpectedException("(");
                }

                args.Add(AddSub(tokens, variables));
                while (tokens.Current.Value != ")" && tokens.Current.Value == ",")
                {
                    args.Add(AddSub(tokens, variables));
                }

                if (tokens.Current.Value != ")")
                {
                    throw ThrowExpectedException(")");
                }

                tokens.MoveNext();
                return(FunctionFactory.CreateFunction(funcName, args.ToArray()));

            default:
                throw new SyntaxException();
            }
        }