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);
                         }
                     }
                 }
             }
         }
     }
 }
 //Get a table with all expressions.
 public Expression[] GetExpressions()
 {
     Expression[] expressions = new Expression[m_expressions.Count];
     m_expressions.Values.CopyTo(expressions, 0);
     return expressions;
 }
 //Computes the value and puts the result to property.
 public void Assign(string key, string expression)
 {
     string name = key.Substring(0, key.LastIndexOf(PROPERTY_CHAR));
     string prop = key.Substring(key.LastIndexOf(PROPERTY_CHAR) + 1);
     IVariable var = base.Variable(name);
     try
     {
         System.Reflection.PropertyInfo propertyInfo = var.GetType().GetProperty(prop);
         Type type = propertyInfo.PropertyType;
         object calcValue = this.Compute(expression, var);
         if (object.ReferenceEquals(type, typeof(float)))
         {
             calcValue = Convert.ToSingle(calcValue);
         }
         else if (object.ReferenceEquals(type, typeof(int)))
         {
             calcValue = Convert.ToInt32(calcValue);
         }
         else if (!object.ReferenceEquals(type, typeof(string)) && calcValue is string)
         {
             calcValue = Convert.ToString(calcValue);
         }
         var.GetType().InvokeMember(prop, System.Reflection.BindingFlags.SetProperty, null, var, new object[] {calcValue});
     }
     catch (Exception ex)
     {
         //Collection exceptions.
         if (ex is ExpressionException)
         {
             m_exceptions.AddException((ExpressionException)ex);
         }
         else if (ex is MissingMemberException)
         {
             //Incompatible datatype between property and expression.
             ExpressionException expressionException = new ExpressionException("Expression result is not compatible with property", 0, expression.Length);
             Expression exp = new Expression();
             exp.SetExpression(key, expression, this);
             expressionException.Expression = exp;
             m_exceptions.AddException(expressionException);
         }
     }
 }
 //Add a new expression.
 public void AddExpression(string key, string expression)
 {
     Expression expr = new Expression();
     expr.SetExpression(key, expression, this);
     this.m_expressions.Add(key, expr);
 }
 public Expression[] GetExpressions()
 {
     //(16.10.2006 09:02)
     //Make thread safe.
     lock (this)
     {
         //Create a list with indirect expressions last.
         int directCount = m_direct.Count;
         Expression[] exps = new Expression[directCount];
         m_direct.CopyTo(exps, 0);
         return exps;
     }
 }
 public void Add(string key, Expression exp)
 {
     //(16.10.2006 09:02)
     //Make thread safe.
     lock (this)
     {
         if (!m_computing.Contains(key))
         {
             m_computing.Add(key, key);
             m_direct.Enqueue(exp);
             //Reset the buffer before computing.
             exp.ResetBuffer();
         }
     }
 }
        //Copies the optimize info to another optimize manager so
        //optimzing is not necessary. Expressions should be exactly the same.
        public void CopyInfoTo(OptimizeManager optimizeManager)
        {
            //Set the expressions that is not optimizable.
            Expression[] notOptimizables = new Expression[this.m_notOptimizables.Length];
            Calculator calc = optimizeManager.Calculator;
            for (int i = 0; i < this.m_notOptimizables.Length; i++)
            {
                notOptimizables[i] = calc.GetExpressionObject(this.m_notOptimizables[i].Key);
            }
            optimizeManager.m_notOptimizables = notOptimizables;

            optimizeManager.m_eventGraph = new Hashtable();
            foreach (DictionaryEntry entry in this.m_eventGraph)
            {
                ArrayList events = (ArrayList)entry.Value;
                ArrayList newEvents = new ArrayList();
                foreach (Expression exp in events)
                    newEvents.Add(calc.GetExpressionObject(exp.Key));
                optimizeManager.m_eventGraph[entry.Key] = newEvents;
            }

            //Set the object map.
            IVariable[] variables = optimizeManager.Calculator.GetVariables();
            foreach (IVariable variable in variables)
            {
                if (variable is IOptimizable)
                    ((IOptimizable)variable).PropertyChanged += new PropertyChangedEventHandler(optimizeManager.PropertyChanged);
            }

            //Copy object references.
            optimizeManager.m_objectReferences = new ArrayList();
            foreach (string objectReference in this.m_objectReferences)
                optimizeManager.m_objectReferences.Add(objectReference);

            //Clone compute list.
            //Shares indirection info, which makes computation faster in the start.
            // optimizeManager.m_computeList = this.m_computeList.Clone();
            optimizeManager.m_computeList = new ComputeList();
        }