private ExpressionResultPair GetTail(string tailName)
        {
            Utility.AssertNotNull(tailName, "name");
            ExpressionResultPair pair = null;

            MyNameNodeMap.TryGetValue(tailName, out pair);
            return(pair);
        }
        // Called by an expression when it references another expression in the engine
        internal void AddDependency(string tailName, ExpressionContext context)
        {
            ExpressionResultPair actualTail = this.GetTail(tailName);
            string headName = context.CalcEngineExpressionName;
            ExpressionResultPair actualHead = this.GetTail(headName);

            // An expression could depend on the same reference more than once (ie: "a + a * a")
            MyDependencies.AddDepedency(actualTail, actualHead);
        }
        /// <include file='Resources/DocComments.xml' path='DocComments/Member[@name="CalculationEngine.GetPrecedents"]/*' />
        public string[] GetPrecedents(string name)
        {
            ExpressionResultPair        pair       = this.GetTail(name);
            List <ExpressionResultPair> dependents = new List <ExpressionResultPair>();

            if ((pair != null))
            {
                MyDependencies.GetDirectPrecedents(pair, dependents);
            }

            return(this.GetNames(dependents));
        }
        private ExpressionResultPair GetTailWithValidate(string tailName)
        {
            Utility.AssertNotNull(tailName, "name");
            ExpressionResultPair pair = this.GetTail(tailName);

            if (pair == null)
            {
                throw new ArgumentException(string.Format("No expression is associated with the name '{0}'", tailName));
            }
            else
            {
                return(pair);
            }
        }
        /// <include file='Resources/DocComments.xml' path='DocComments/Member[@name="CalculationEngine.GetResult"]/*' />
        public T GetResult <T>(string name)
        {
            ExpressionResultPair tail = this.GetTailWithValidate(name);

            if ((!object.ReferenceEquals(typeof(T), tail.ResultType)))
            {
                string msg = string.Format("The result type of '{0}' ('{1}') does not match the supplied type argument ('{2}')", name, tail.ResultType.Name, typeof(T).Name);
                throw new ArgumentException(msg);
            }

            GenericExpressionResultPair <T> actualTail = tail as GenericExpressionResultPair <T>;

            return(actualTail.Result);
        }
        private ExpressionResultPair[] GetRootTails(string[] roots)
        {
            // No roots supplied so get everything
            if (roots.Length == 0)
            {
                return(MyDependencies.GetTails());
            }

            // Get the tail for each name
            ExpressionResultPair[] arr = new ExpressionResultPair[roots.Length];

            for (int i = 0; i <= arr.Length - 1; i++)
            {
                arr[i] = this.GetTailWithValidate(roots[i]);
            }

            return(arr);
        }
        /// <include file='Resources/DocComments.xml' path='DocComments/Member[@name="CalculationEngine.Remove"]/*' />
        public bool Remove(string name)
        {
            ExpressionResultPair tail = this.GetTail(name);

            if (tail == null)
            {
                return(false);
            }

            ExpressionResultPair[] dependents = MyDependencies.GetDependents(tail);
            MyDependencies.Remove(dependents);

            foreach (ExpressionResultPair pair in dependents)
            {
                MyNameNodeMap.Remove(pair.Name);
            }

            return(true);
        }
        internal void FixTemporaryHead(IDynamicExpression expression, ExpressionContext context, Type resultType)
        {
            Type pairType = typeof(GenericExpressionResultPair <>);

            pairType = pairType.MakeGenericType(resultType);

            ExpressionResultPair pair = Activator.CreateInstance(pairType) as ExpressionResultPair;
            string headName           = context.CalcEngineExpressionName;

            pair.SetName(headName);
            pair.SetExpression(expression);

            ExpressionResultPair oldPair = MyNameNodeMap[headName];

            MyDependencies.ReplaceDependency(oldPair, pair);
            MyNameNodeMap[headName] = pair;

            // Let the pair store the result of its expression
            pair.Recalculate();
        }
        /// <include file='Resources/DocComments.xml' path='DocComments/Member[@name="CalculationEngine.HasPrecedents"]/*' />
        public bool HasPrecedents(string name)
        {
            ExpressionResultPair pair = this.GetTail(name);

            return((pair != null) && MyDependencies.HasPrecedents(pair));
        }
        /// <include file='Resources/DocComments.xml' path='DocComments/Member[@name="CalculationEngine.GetExpression"]/*' />
        public IExpression GetExpression(string name)
        {
            ExpressionResultPair tail = this.GetTailWithValidate(name);

            return(tail.Expression);
        }
        /// <include file='Resources/DocComments.xml' path='DocComments/Member[@name="CalculationEngine.GetResult2"]/*' />
        public object GetResult(string name)
        {
            ExpressionResultPair tail = this.GetTailWithValidate(name);

            return(tail.ResultAsObject);
        }
        internal Type ResolveTailType(string tailName)
        {
            ExpressionResultPair actualTail = this.GetTail(tailName);

            return(actualTail.ResultType);
        }