private object EvaluateInvocationExpression(Expression expression, List <object> argumentValues, CodeContext codeContext)
        {
            string invocation = expression.ToString();


            object lastObject = codeContext.ContainerInstance;

            if (invocation == "System.Math.Max" ||
                invocation == "Math.Max")
            {
                return(PrimitiveOperationManager.Self.MaxObjects(argumentValues[0], argumentValues[1]));
            }
            else if (invocation == "GetFile" && argumentValues.Count == 1)
            {
                ElementRuntime elementRuntime = null;
                // We're going to have to assume the user means to call GetFile from the current element
                if (codeContext.ContainerInstance != null)
                {
                    if (codeContext.ContainerInstance is ElementRuntime)
                    {
                        elementRuntime = codeContext.ContainerInstance as ElementRuntime;
                    }
                }

                if (elementRuntime != null)
                {
                    return(elementRuntime.GetReferencedFileSaveRuntime(argumentValues[0] as string));
                }
                else
                {
                    return(null);
                }
            }
            else if (invocation == "System.Math.Min" ||
                     invocation == "Math.Min")
            {
                return(PrimitiveOperationManager.Self.MinObjects(argumentValues[0], argumentValues[1]));
            }
            else if (invocation == "InterpolateBetween" || invocation == "this.InterpolateBetween")
            {
                MethodCallParser.InterpolateBetween(lastObject as ElementRuntime, argumentValues[0], argumentValues[1], argumentValues[2]);
                return(null);
            }
            else
            {
                object caller = GetCaller(expression, codeContext);

                MethodInfo methodInfo;

                object toReturn = null;

                Type[] argumentTypes = new Type[argumentValues.Count];

                for (int i = 0; i < argumentValues.Count; i++)
                {
                    if (argumentValues[i] != null)
                    {
                        argumentTypes[i] = argumentValues[i].GetType();
                    }
                }

                if (TryHandleSpecialCase(expression, argumentValues, argumentTypes, codeContext, invocation, caller, out toReturn))
                {
                    // do nothing, toReturn is set
                }
                else
                {
                    GetMethodInfo(expression, argumentValues, argumentTypes, codeContext, invocation, caller, out methodInfo);

                    if (methodInfo != null)
                    {
                        toReturn = methodInfo.Invoke(caller, argumentValues.ToArray());
                    }
                }
                return(toReturn);
            }
            //else
            //{
            //    throw new NotImplementedException();
            //}
        }
        private static void GetObjectFromContainerAndNameEvaluate(object container, string memberName, CodeContext codeContext, ref object foundValue, ref bool wasFound)
        {
            if (container is CsvEntry)
            {
                foundValue = (container as CsvEntry).GetValue(memberName);
            }

            if (codeContext.VariableStack.Count == 0)
            {
                throw new Exception("codeContext doesn't have any entries.  It needs to have at least one");
            }

            int index = -1;

            codeContext.GetVariableInformation(memberName, out index);

            if (index != -1)
            {
                foundValue = codeContext.VariableStack[index][memberName];
                wasFound   = true;
            }

            if (wasFound == false && foundValue == null && container != null)
            {
                object instance = container;
                Type   type     = container.GetType();
                if (container is Type)
                {
                    instance = null;
                    type     = container as Type;
                }

                // First let's do reflection
                if (container is ElementRuntime && (container as ElementRuntime).DirectObjectReference != null)
                {
                    ElementRuntime containerElementRuntime = container as ElementRuntime;

                    if (LateBinder.GetInstance(containerElementRuntime.DirectObjectReference.GetType()).TryGetValue(containerElementRuntime.DirectObjectReference, memberName, out foundValue))
                    {
                        // do nothing.
                        wasFound = true;
                    }
                }
                else
                {
                    if (LateBinder.GetInstance(type).TryGetValue(instance, memberName, out foundValue))
                    {
                        // do nothing.
                        wasFound = true;
                    }
                }

                if (foundValue == null && container is ElementRuntime)
                {
                    ElementRuntime containerElementRuntime = container as ElementRuntime;

                    IElement containerElement = (container as ElementRuntime).AssociatedIElement;


                    foundValue = TryToGetStateCategoryFromElement(memberName, containerElement);

                    if (foundValue == null)
                    {
                        foundValue = containerElementRuntime.GetContainedElementRuntime(memberName);
                    }

                    if (foundValue == null)
                    {
                        foundValue = containerElementRuntime.GetReferencedFileSaveRuntime(memberName);
                    }

                    if (foundValue == null && containerElement != null)
                    {
                        // Some values like X or Y are stored inside the element runtime
                        // (because it actually stores those values locally).  However, if
                        // a value doesn't have an underlying value,
                        CustomVariable variable = containerElementRuntime.GetCustomVariable(memberName, VariableGetType.AsExistsAtRuntime);
                        //CustomVariable variable = containerElement.GetCustomVariableRecursively(memberName);
                        if (variable != null)
                        {
                            if (variable.GetIsCsv())
                            {
                                string rfsToLookFor = FileManager.RemoveExtension(variable.Type);
                                foundValue = containerElementRuntime.GetReferencedFileSaveRuntime(rfsToLookFor);
                                // if it's null, maybe it's a global file
                                if (foundValue == null)
                                {
                                    ReferencedFileSave rfs = ObjectFinder.Self.GetReferencedFileSaveFromFile(variable.Type);
                                    if (rfs != null)
                                    {
                                        foundValue = GluxManager.GlobalContentFilesRuntime.LoadReferencedFileSave(rfs, true, containerElement);
                                    }
                                }

                                if (foundValue != null)
                                {
                                    foundValue = GetCsvEntryByRequiredKey(variable.DefaultValue as string, foundValue as RuntimeCsvRepresentation);
                                    // We have a RFS, so let's get values out of it
                                }
                            }
                            else
                            {
                                foundValue = variable.DefaultValue;
                                wasFound   = true;
                            }
                        }
                    }
                    wasFound = foundValue != null;
                }
                else if (container is StateSaveCategory)
                {
                    foundValue = (container as StateSaveCategory).States.FirstOrDefault(state => state.Name == memberName);
                    wasFound   = foundValue != null;
                }
                else if (container is IElement)
                {
                    foundValue = TryToGetStateCategoryFromElement(memberName, container as IElement);
                }
            }
            if (wasFound == false && foundValue == null)
            {
                foundValue = ObjectFinder.Self.GetElementUnqualified(memberName);
                wasFound   = foundValue != null;
            }
            if (wasFound == false && foundValue == null)
            {
                foundValue = TypeManager.GetTypeFromString(memberName);

                wasFound = foundValue != null;
            }
        }