public SubExpressionUpdate(ICalculator calculator, IFunction callFunction, string val, int propIndex, IVariable relative)
 {
     if (propIndex == -1 && callFunction is IVariableReferencePropertyUsage)
     {
         if (val != relative.Name)
         {
             // Compute dependicy properties before returning the variable
             // in order to receive correct values.
             object var = calculator.ComputeVariable(val, null);
             string[] props = ((IVariableReferencePropertyUsage)callFunction).GetDependices(var.GetType());
             if (props != null)
             {
                 foreach (string prop in props)
                 {
                     Expression exp = calculator.GetExpressionObject(val + "." + prop);
                     if (exp != null)
                         m_expressionList.Add(exp);
                 }
             }
         }
     }
     else if (propIndex > 0)
     {
         // Compute property dependices before this.
         string name = val.Substring(0, propIndex);
         if (name != relative.Name)
         {
             object var = calculator.ComputeVariable(name, null);
             if (var is IOptimizable)
             {
                 IOptimizable opt = (IOptimizable)var;
                 PropertyDependicy[] deps = opt.PropertyDependices;
                 string prop = val.Substring(propIndex + 1);
                 if (deps != null)
                 {
                     Expression[] exps = new Expression[1];
                     foreach (PropertyDependicy dep in deps)
                     {
                         if (dep.ParentProperty == prop)
                         {
                             Expression exp = calculator.GetExpressionObject(name + "." + dep.ChildProperty);
                             if (exp != null)
                                 m_expressionList.Add(exp);
                         }
                     }
                 }
             }
         }
     }
 }
        //Calculates the value by expression tree.
        //Calculator - The object that contains functions, variables and expressions.
        //Relative - The relative variable.
        public object Calc(ICalculator calculator, IVariable relative, IFunction callFunction)
        {
            try
            {
                if (m_type == NODE_TYPE.FUNCTION || m_type == NODE_TYPE.OPERATOR)
                {
                    //Run function.
                    IFunction func;
                    //(14.11.2006 11:50)
                    //Point directly to the function to increase speed.
                    if (m_function != null)
                    {
                        func = m_function;
                    }
                    else
                    {
                        string val = (string)m_value;
                        FunctionSet functions = calculator.Functions;
                        if (functions.Contains(val))
                        {
                            func = functions.Item(val);
                            m_function = func;
                        }
                        else
                        {
                            throw new Exception("Unknown function :" + val);
                        }
                    }

                    if (func is IIntelligenceFunction)
                    {
                        return ((IIntelligenceFunction)func).Run(m_subNodes, calculator, relative);
                    }

                    object[] @params = new object[this.m_subNodes.Length];
                    //The argument position.
                    int i = 0;
                    while (i < @params.Length)
                    {
                        object obj = m_subNodes[i].Calc(calculator, relative, func);
                        @params[i] = obj;
                        i += 1;
                    }

                    return func.Run(@params);
                }
                else if (m_type == NODE_TYPE.TEXT)
                    return m_value;
                else if (m_type == NODE_TYPE.NUMBER)
                    return (float)m_value;
                else if (m_type == NODE_TYPE.VARIABLE)
                {
                    string val = (string)m_value;
                    int propIndex = val.IndexOf('.');

                    #region "Sub Expression Updating"
                    // Update sub expressions before calculating the value to make sure
                    // the computation will be correct.
                    if (calculator.RunExpressions && relative != null)
                    {
                        if (this.m_subExpressionUpdate == null)
                            this.m_subExpressionUpdate = new SubExpressionUpdate(calculator, callFunction, val, propIndex, relative);
                        this.m_subExpressionUpdate.UpdateSubExpressions(calculator);
                        if (propIndex == 0)
                            return relative.GetType().InvokeMember(val.Substring(propIndex + 1), System.Reflection.BindingFlags.GetProperty, null, relative, new object[] {});
                        else
                            return calculator.ComputeVariable(val, null);
                    }
                    #endregion

                    // Don't use relative if there is none.
                    if (relative == null || propIndex != 0 && (propIndex == -1 || val.Substring(0, propIndex) != relative.Name))
                    {
                        return calculator.ComputeVariable(val, relative);
                    }
                    // Get value directly from variable if relative is the variable.
                    return relative.GetType().InvokeMember(val.Substring(propIndex + 1), System.Reflection.BindingFlags.GetProperty, null, relative, new object[] {});
                }

            }
            catch (Exception ex)
            {
                if (!(ex is ExpressionException))
                {
                    throw new ExpressionException(ex.Message, m_column, m_length);
                }
                else
                {
                    throw ex;
                }
            }
            return null;
        }