public double Evaluate()
        {
            Stack result = new Stack();
            double oper1 = 0.0;
            double oper2 = 0.0;
            Token token = new Token();

            foreach (object obj in output)
            {
                token = (Token)obj;

                switch (token.Type)
                {
                    case TokenType.Number:
                        result.Push(double.Parse(token.Value));
                        break;
                    case TokenType.Plus:
                        if (result.Count >= 2)
                        {
                            oper2 = (double)result.Pop();
                            oper1 = (double)result.Pop();
                            result.Push(oper1 + oper2);
                        }
                        else
                        {
                            throw new Exception("Evaluation error!");
                        }
                        break;
                    case TokenType.Minus:
                        if (result.Count >= 2)
                        {
                            oper2 = (double)result.Pop();
                            oper1 = (double)result.Pop();
                            result.Push(oper1 - oper2);
                        }
                        else
                        {
                            throw new Exception("Evaluation error!");
                        }
                        break;
                    case TokenType.Multiply:
                        if (result.Count >= 2)
                        {
                            oper2 = (double)result.Pop();
                            oper1 = (double)result.Pop();
                            result.Push(oper1 * oper2);
                        }
                        else
                        {
                            throw new Exception("Evaluation error!");
                        }
                        break;
                    case TokenType.Divide:
                        if (result.Count >= 2)
                        {
                            oper2 = (double)result.Pop();
                            oper1 = (double)result.Pop();
                            result.Push(oper1 / oper2);
                        }
                        else
                        {
                            throw new Exception("Evaluation error!");
                        }
                        break;
                    case TokenType.Exponent:
                        if (result.Count >= 2)
                        {
                            oper2 = (double)result.Pop();
                            oper1 = (double)result.Pop();
                            result.Push(Math.Pow(oper1, oper2));
                        }
                        else
                        {
                            throw new Exception("Evaluation error!");
                        }
                        break;
                    case TokenType.UnaryMinus:
                        if (result.Count >= 2)
                        {
                            oper1 = (double)result.Pop();
                            result.Push(-oper1);
                        }
                        else
                        {
                            throw new Exception("Evaluation error!");
                        }
                        break;
                    case TokenType.Ln:
                        if(result.Count >= 1)
                        {
                            oper1 = (double) result.Pop();
                            result.Push(Math.Log(oper1));
                        }
                        else
                        {
                            throw new Exception("Evaluation error!");
                        }
                        break;
                    case TokenType.Sqrt:
                        if(result.Count >= 1)
                        {
                            oper1 = (double) result.Pop();
                            result.Push(Math.Sqrt(oper1));
                        }
                        else
                        {
                            throw new Exception("Evaluation error!");
                        }
                        break;
                    case TokenType.Pow:
                        if(result.Count >= 1)
                        {
                            oper2 = (double) result.Pop();
                            oper1 = (double) result.Pop();
                            result.Push(Math.Pow(oper1, oper2));
                        }
                        else
                        {
                            throw new Exception("Evaluation error!");
                        }
                        break;
                }
            }

            if (result.Count == 1)
            {
                return (double)result.Pop();
            }
            else
            {
                throw new Exception("Evaluation error");
            }
        }
        public void Parse(string expression)
        {
            string buffer = expression.ToLower();
            buffer = Regex.Replace(buffer, @"(?<number>\d+(\.\d+)?)", " ${number} ");
            buffer = Regex.Replace(buffer, @"(?<ops>[+\-*/^()])", " ${ops} ");
            buffer = Regex.Replace(buffer, @"\s+", " ").Trim();

            buffer = Regex.Replace(buffer, "-", "MINUS");
            buffer = Regex.Replace(buffer, @"(?<number>((\d+(\.\d+)?)))\s+MINUS", "${number} -");
            buffer = buffer.Replace(") MINUS", ") -");
            buffer = Regex.Replace(buffer, "(?<alpha>(ln|sqrt|pow))", " ${alpha} ");
            buffer = Regex.Replace(buffer, "MINUS", "~");  //~ as unary '-' operator
            buffer = Regex.Replace(buffer, ",", " ");

            //tokenise
            string[] parsed = buffer.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
            int i = 0;
            double tokenValue;
            Token token, opsToken = new Token();
            for (i = 0; i < parsed.Length; ++i)
            {
                token = new Token();
                token.Value = parsed[i];
                token.Type = TokenType.None;

                try
                {
                    tokenValue = double.Parse(parsed[i]);
                    token.Type = TokenType.Number;
                    output.Enqueue(token);
                }
                catch (Exception)
                {
                    switch (parsed[i])
                    {
                        case "+":
                            token.Type = TokenType.Plus;
                            if (ops.Count > 0)
                            {
                                opsToken = (Token)ops.Peek();

                                while (IsOperatorToken(opsToken.Type))
                                {
                                    output.Enqueue(ops.Pop());
                                    if (ops.Count > 0)
                                    {
                                        opsToken = (Token)ops.Peek();
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }

                            ops.Push(token);
                            break;

                        case "-":
                            token.Type = TokenType.Minus;
                            if (ops.Count > 0)
                            {
                                opsToken = (Token)ops.Peek();

                                while (IsOperatorToken(opsToken.Type))
                                {
                                    output.Enqueue(ops.Pop());
                                    if (ops.Count > 0)
                                    {
                                        opsToken = (Token)ops.Peek();
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }

                            ops.Push(token);
                            break;

                        case "*":
                            token.Type = TokenType.Multiply;
                            if (ops.Count > 0)
                            {
                                opsToken = (Token)ops.Peek();

                                while (IsOperatorToken(opsToken.Type))
                                {
                                    if (opsToken.Type == TokenType.Plus || opsToken.Type == TokenType.Minus)
                                    {
                                        break;
                                    }
                                    else
                                    {
                                        output.Enqueue(ops.Pop());
                                        if (ops.Count > 0)
                                        {
                                            opsToken = (Token)ops.Peek();
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                }
                            }

                            ops.Push(token);
                            break;
                        case "/":
                            token.Type = TokenType.Divide;
                            if (ops.Count > 0)
                            {
                                opsToken = (Token)ops.Peek();

                                while (IsOperatorToken(opsToken.Type))
                                {
                                    if (opsToken.Type == TokenType.Plus || opsToken.Type == TokenType.Minus)
                                    {
                                        break;
                                    }
                                    else
                                    {
                                        output.Enqueue(ops.Pop());
                                        if (ops.Count > 0)
                                        {
                                            opsToken = (Token)ops.Peek();
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                }
                            }

                            ops.Push(token);
                            break;
                        case "^":
                            token.Type = TokenType.Exponent;
                            ops.Push(token);
                            break;
                        case "~":
                            token.Type = TokenType.UnaryMinus;
                            ops.Push(token);
                            break;
                        case "(":
                            token.Type = TokenType.LeftParenthesis;
                            ops.Push(token);
                            break;
                        case ")":
                            token.Type = TokenType.RightParenthesis;
                            if (ops.Count > 0)
                            {
                                opsToken = (Token)ops.Peek();

                                while (opsToken.Type != TokenType.LeftParenthesis)
                                {
                                    output.Enqueue(ops.Pop());
                                    if (ops.Count > 0)
                                    {
                                        opsToken = (Token)ops.Peek();
                                    }
                                    else
                                    {
                                        throw new Exception("Wrong number of parenthesis");
                                    }
                                }

                                ops.Pop();
                            }

                            if (ops.Count > 0)
                            {
                                opsToken = (Token)ops.Peek();

                                if (IsFunctionToken(opsToken.Type))
                                {
                                    output.Enqueue(ops.Pop());
                                }
                            }

                            break;
                        case "ln":
                            token.Type = TokenType.Ln;
                            ops.Push(token);
                            break;
                        case "sqrt":
                            token.Type = TokenType.Sqrt;
                            ops.Push(token);
                            break;
                        case "pow":
                            token.Type = TokenType.Pow;
                            ops.Push(token);
                            break;
                    }
                }
            }

            while (ops.Count != 0)
            {
                opsToken = (Token)ops.Pop();
                if (opsToken.Type == TokenType.LeftParenthesis)
                {
                    throw new Exception("Wrong number of parenthesis");
                }
                else
                {
                    output.Enqueue(opsToken);
                }
            }

            this.postfixExpression = string.Empty;
            foreach (object obj in output)
            {
                opsToken = (Token)obj;
                this.postfixExpression += string.Format("{0}", opsToken.Value);
            }
        }