/// <summary>
        /// Makes expression tree from string
        /// </summary>
        /// <param name="ex"></param>
        /// <returns></returns>
        private Node MakeTree(string ex)
        {
            SolverUtilities.RemoveExternalBracets(ref ex);
            Node res = new Node();

            if (SolverUtilities.CheckNumber(ex))
            {
                res.Operation = ex;
                res.Type = ExpressionType.Number;
                res.Left = null;
                res.Right = null;
            }

            if (SolverUtilities.CheckVariable(ex))
            {
                res.Operation = ex;
                res.Type = ExpressionType.Variable;
                res.Left = null;
                res.Right = null;
            }

            if (SolverUtilities.CheckFunction(ex))
            {
                int openBracet, closeBracet;

                openBracet = ex.IndexOf("(");
                closeBracet = ex.LastIndexOf(")");
                res.Operation = ex.Substring(0, openBracet);
                string FunctionParam = ex.Substring(openBracet+1, closeBracet-openBracet-1);
                // If function takes one argument then make one child node.
                // If it takes two argumetns then make two children nodes;
                if (SolverUtilities.NumberOfFunctionArguments(FunctionParam) == 1)
                {
                    res.Type = ExpressionType.OneArgumentFunction;
                    res.Left = MakeTree(FunctionParam);
                    res.Right = null;
                }
                else
                {
                    int comma = FunctionParam.IndexOf(",");
                    res.Type = ExpressionType.TwoArgumentFunction;
                    res.Left = MakeTree(FunctionParam.Substring(0, comma));
                    res.Right = MakeTree(FunctionParam.Substring(comma+1, FunctionParam.Length-comma-1));
                }
            }

            // We should pay attention to operations' priorities
            int signIndex = SolverUtilities.FindOperationSign(ex, new string[] {"-", "+"});
            if (signIndex == -1)
                signIndex = SolverUtilities.FindOperationSign(ex, new string[] {"/", "*"});
            if (signIndex == -1)
                signIndex = SolverUtilities.FindOperationSign(ex, new string[] { "^" });
            if (signIndex != -1)
            {
                res.Operation = ex[signIndex].ToString();
                res.Type = ExpressionType.Expression;
                res.Left = MakeTree(ex.Substring(0, signIndex));
                res.Right = MakeTree(ex.Substring(signIndex+1, ex.Length-signIndex-1));
            }

            return res;
        }
        /// <summary>
        /// Figures out a value of given expression tree node
        /// </summary>
        /// <param name="tree"></param>
        public void ExecuteTree(Node tree)
        {
            if (tree == null)
                return;

            ExecuteTree(tree.Left);
            ExecuteTree(tree.Right);

            switch (tree.Type)
            {
                case ExpressionType.Number:
                    tree.Value = double.Parse(tree.Operation);
                    break;
                case ExpressionType.Variable:
                    if (!m_Variables.ContainsKey(tree.Operation))
                        return;
                    tree.Value = m_Variables[tree.Operation];
                    break;
                case ExpressionType.Expression:
                    tree.Value = SolverUtilities.ExecuteExpression(tree.Operation, tree.Left.Value, tree.Right.Value);
                    break;
                case ExpressionType.OneArgumentFunction:
                    tree.Value = SolverUtilities.ExecuteFunction(tree.Operation, tree.Left.Value);
                    break;
                case ExpressionType.TwoArgumentFunction:
                    tree.Value = SolverUtilities.ExecuteFunction(tree.Operation, tree.Left.Value, tree.Right.Value);
                    break;
            }
        }
        /// <summary>
        /// Parsing string expression into expression tree
        /// </summary>
        public void Prepare()
        {
            // Check bracet balance
            if (!SolverUtilities.CheckBracets(m_Expression))
                return;

            // Removing all spaces and make all characters low
            m_Expression = m_Expression.ToLower().Replace(" ", string.Empty);

            // Building an expression tree
            ExpressionTree = MakeTree(m_Expression);

            m_IsCompiled = true;
        }