/// <summary>
        /// Checks if a variable object is a reference to a variable registered in the AinFile, and returns the original variable from the AinFile if it exists, otherwise returns null.
        /// </summary>
        /// <param name="variable">The variable to find</param>
        /// <param name="ainFile">The AinFile to find the variable in.</param>
        /// <returns>returns the original variable from the AinFile if it exists, otherwise returns null</returns>
        public static IVariable Canonicalize(this IVariable variable, AinFile ainFile)
        {
            int index       = variable.Index;
            int parentIndex = -1;

            if (variable == null || ainFile == null)
            {
                return(null);
            }
            var root = variable.Root;

            var parent = variable.Parent;

            if (parent != null)
            {
                parentIndex = parent.Index;
            }

            if (root == ainFile || root == null)
            {
                if (parent is Function)
                {
                    if (parent.Name.StartsWith("system."))
                    {
                        return(AinFile.GetSystemCallParameter(parentIndex, index));
                    }
                    return(ainFile.GetFunctionParameter(parentIndex, index));
                }
                if (parent is Struct)
                {
                    return(ainFile.GetStructMember(parentIndex, index));
                }
                if (variable is Global)
                {
                    return(ainFile.GetGlobal(index));
                }
                if (parent is FunctionType)
                {
                    return(ainFile.GetFuncTypeParameter(parentIndex, index));
                }
                if (parent is HllFunction)
                {
                    if (parent.Parent != null)
                    {
                        return(ainFile.GetLibraryFunctionParameter(parent.Parent.Index, parentIndex, index));
                    }
                    else
                    {
                        return(null);
                    }
                }
                if (variable is Function)
                {
                    if (variable.Name.StartsWith("system."))
                    {
                        return(AinFile.GetSystemCall(index));
                    }
                    return(ainFile.GetFunction(index));
                }
                if (variable is Struct)
                {
                    return(ainFile.GetStruct(index));
                }
                if (variable is HllFunction)
                {
                    return(ainFile.GetLibraryFunction(parentIndex, index));
                }
                if (variable is FunctionType)
                {
                    return(ainFile.GetFuncType(index));
                }
            }
            else
            {
                if (parent is Function)
                {
                    if (parent.Name.StartsWith("system."))
                    {
                        return(AinFile.GetSystemCallParameter(parentIndex, index));
                    }
                    return(ainFile.GetFunctionParameter(parent.Name, variable.Name));
                }
                if (variable is Global)
                {
                    return(ainFile.GetGlobal(variable.Name));
                }
                if (parent is Struct)
                {
                    return(ainFile.GetStructMember(parent.Name, variable.Name));
                }
                if (parent is FunctionType)
                {
                    return(ainFile.GetFuncTypeParameter(parent.Name, variable.Index));
                }
                if (parent is HllFunction)
                {
                    if (parent.Parent != null)
                    {
                        return(ainFile.GetLibraryFunctionParameter(parent.Parent.Name, parent.Name, index));
                    }
                    else
                    {
                        return(null);
                    }
                }
                if (variable is Function)
                {
                    if (variable.Name.StartsWith("system."))
                    {
                        return(AinFile.GetSystemCall(index));
                    }
                    return(ainFile.GetFunction(variable.Name));
                }
                if (variable is Struct)
                {
                    return(ainFile.GetStruct(variable.Name));
                }
                if (variable is HllFunction)
                {
                    return(ainFile.GetLibraryFunction(parent.Name, variable.Name));
                }
                if (variable is FunctionType)
                {
                    return(ainFile.GetFuncType(variable.Name));
                }
            }
            return(null);
        }