/// <summary>
        /// Creates the graph associated to this expression, when the given parameter ranges over the X axis
        /// </summary>
        /// <param name="context">The interpretation context</param>
        /// <param name="parameter">The parameters of *the enclosing function* for which the graph should be created</param>
        /// <returns></returns>
        public override Functions.Graph createGraph(InterpretationContext context, Parameter parameter)
        {
            Functions.Graph retVal = base.createGraph(context, parameter);

            Functions.PredefinedFunctions.Cast cast = Called.Ref as Functions.PredefinedFunctions.Cast;
            if (cast != null)
            {
                // In case of cast, just take the graph of the enclosed expression
                Parameter param = (Parameter)cast.FormalParameters[0];
                retVal = cast.createGraphForParameter(context, param);
            }

            Function calledFunction = Called.Ref as Function;
            Dictionary <Parameter, Expression> parameterAssociation = null;

            if (calledFunction == null)
            {
                calledFunction       = Called.GetValue(context) as Function;
                parameterAssociation = createParameterAssociation(calledFunction);
            }
            else
            {
                parameterAssociation = ParameterAssociation;
            }

            Parameter Xaxis = null;

            foreach (KeyValuePair <Parameter, Expression> pair in parameterAssociation)
            {
                if (pair.Value.Ref == parameter)
                {
                    if (Xaxis == null)
                    {
                        Xaxis = pair.Key;
                    }
                    else
                    {
                        Root.AddError("Cannot evaluate graph for function call " + ToString() + " which has more than 1 parameter used as X axis");
                        Xaxis = null;
                        break;
                    }
                }
            }

            int token = context.LocalScope.PushContext();

            calledFunction.AssignParameters(context, AssignParameterValues(context, calledFunction, false));
            if (Xaxis != null)
            {
                retVal = calledFunction.createGraphForParameter(context, Xaxis);
            }
            else
            {
                retVal = Function.createGraphForValue(GetValue(context));
            }
            context.LocalScope.PopContext(token);

            return(retVal);
        }
        /// <summary>
        /// Provides the surface of this function if it has been statically defined
        /// </summary>
        /// <param name="context">the context used to create the surface</param>
        /// <param name="xParam">The X axis of this surface</param>
        /// <param name="yParam">The Y axis of this surface</param>
        /// <returns>The surface which corresponds to this expression</returns>
        public override Functions.Surface createSurface(Interpreter.InterpretationContext context, Parameter xParam, Parameter yParam)
        {
            Functions.Surface retVal = base.createSurface(context, xParam, yParam);

            Functions.Function function             = getFunction(context);
            Functions.PredefinedFunctions.Cast cast = Called.Ref as Functions.PredefinedFunctions.Cast;
            if (cast != null)
            {
                // In case of cast, just take the surface of the enclosed expression
                Expression actual = (Expression)ActualParameters[0];
                retVal = actual.createSurface(context, xParam, yParam);
            }
            else
            {
                Parameter Xaxis = null;
                Parameter Yaxis = null;

                if (function == null)
                {
                    function = Called.getCalled(context) as Function;
                }

                SelectXandYAxis(context, xParam, yParam, function, out Xaxis, out Yaxis);
                if (Xaxis != null || Yaxis != null)
                {
                    int token = context.LocalScope.PushContext();
                    function.AssignParameters(context, AssignParameterValues(context, function, true));
                    retVal = function.createSurfaceForParameters(context, Xaxis, Yaxis);
                    context.LocalScope.PopContext(token);
                }
                else
                {
                    Values.IValue value = GetValue(context);
                    if (value != null)
                    {
                        retVal = Functions.Surface.createSurface(value, xParam, yParam);
                    }
                    else
                    {
                        throw new Exception("Cannot create surface for expression");
                    }
                }
            }
            retVal.XParameter = xParam;
            retVal.YParameter = yParam;

            return(retVal);
        }