/// <summary>
        /// Retrieve the PersistentMethod description for the callback described by the callback
        /// </summary>
        /// <param name="callback">The callback object containing the information for the method to be raised</param>
        /// <returns>Returns the Persistent Method definition for the callback or null if not found</returns>
        public static PersistentMethod GetPersistentMethodFromCallback(PersistentCallback callback)
        {
            //Check that the callback is valid
            if (!callback.IsValid)
            {
                return(null);
            }

            //Get the type of the target object
            Type key = callback.Target.GetType();

            //If the type hasn't been processed, get to it
            if (!objectMethods.ContainsKey(key))
            {
                ProcessObjectType(key);
            }

            //Create a hashable list for lookup
            List <object> hashable = new List <object>(callback.ParameterInfo.Length + 1);

            hashable.Add(callback.MethodName);

            //Add the parameter signature to the list
            foreach (var param in callback.ParameterInfo)
            {
                hashable.Add(param.ParameterType);
            }

            //Generate the hash key for this entry
            MethodHash hashKey = HashUtitlity.GetCombinedHash(hashable.ToArray());

            //Return the corresponding element if it exists
            return(objectMethods[key].ContainsKey(hashKey) ?
                   objectMethods[key][hashKey] :
                   null
                   );
        }
        /// <summary>
        /// Process the supplied type to establish the usable methods that are contained for it
        /// </summary>
        /// <param name="key">The type that is to be processed to identify usable methods</param>
        private static void ProcessObjectType(Type key)
        {
            //Find all the methods that belong to the type with the specified flags
            List <MethodInfo> baseMethods = new List <MethodInfo>(key.GetMethods(PersistentCallbackUtility.SEARCH_FLAGS));

            //Remove any method that is not valid
            baseMethods.RemoveAll(method => {
                //If this contains generic parameters, not gonna use it
                if (method.ContainsGenericParameters)
                {
                    return(true);
                }

                //If this is a property (With a special name) only allow setters
                if (method.IsSpecialName && !method.Name.StartsWith(SETTER_PROPERTY_PREFIX))
                {
                    return(true);
                }

                //Check if there is an exclusion attribute
                if (method.GetFirstCustomAttributeOf <OmitRuntimeEventAttribute>() != null)
                {
                    return(true);
                }

                //Retrieve the parameters of the object
                ParameterInfo[] parameters = method.GetParameters();

                //Check that each of the parameter types has a supported type
                foreach (ParameterInfo parm in parameters)
                {
                    if (!GenericSerialisation.CanProcess(parm.ParameterType))
                    {
                        return(true);
                    }
                }

                //If gotten this far, not going to be used
                return(false);
            });

            //Process each of the stored entries for inclusion in the lookup
            Dictionary <MethodHash, PersistentMethod> typeLookup = new Dictionary <MethodHash, PersistentMethod>(baseMethods.Count);

            //Process all of the stored methods
            foreach (MethodInfo method in baseMethods)
            {
                //Get all of the parameters belonging to this method that needs to processed
                ParameterInfo[] parameters = method.GetParameters();

                //Create an array for all of the parameters within this method
                PersistentParameter[] paramsInfo = new PersistentParameter[parameters.Length];

                //Store the type signature for this method
                Type[] signature = new Type[parameters.Length];

                //Store the collection of objects that will be used to create this Methods Hash
                List <object> hashable = new List <object>(parameters.Length + 1);
                hashable.Add(method.Name);

                //Process each of the parameter signature values
                for (int i = 0; i < parameters.Length; i++)
                {
                    //Store the type for the entry
                    signature[i] = parameters[i].ParameterType;

                    //Add the type to the hashable list
                    hashable.Add(parameters[i].ParameterType);

                    //Look for a description attribute that is attached to this parameter
                    DescriptionAttribute paramDesc = parameters[i].GetFirstCustomAttributeOf <DescriptionAttribute>();

                    //Create the information object for this parameter
                    paramsInfo[i] = new PersistentParameter(
                        new GUIContent(
                            ObjectNames.NicifyVariableName(parameters[i].Name),
                            paramDesc != null ? paramDesc.Description : string.Empty
                            ),
                        parameters[i].GetFirstCustomAttributeOf <ParameterAttribute>(),
                        parameters[i].DefaultValue
                        );
                }

                //Look for a description attribute that is attached to this method
                DescriptionAttribute methodDesc = method.GetFirstCustomAttributeOf <DescriptionAttribute>();

                //Create the information object for this method
                PersistentMethod persistentMethod = new PersistentMethod(
                    new GUIContent(
                        GenerateLabelFromSignature(
                            (method.IsSpecialName ?
                             method.Name.Substring(SETTER_PROPERTY_PREFIX.Length) :
                             method.Name
                            ),
                            signature
                            ),
                        methodDesc != null ? methodDesc.Description : string.Empty
                        ),
                    method.Name,
                    signature,
                    paramsInfo,
                    method.IsSpecialName
                    );

                //Get the hash key for this method
                MethodHash hashKey = HashUtitlity.GetCombinedHash(hashable.ToArray());

                //Warn on a key conflict (Ideally, shouldn't happen ever)
                if (typeLookup.ContainsKey(hashKey))
                {
                    Debug.LogWarningFormat("Generated hash key for the method '{0}' (For Type: {1}) is identical to the method '{2}'. This method will overrite the previous", persistentMethod.DisplayLabel.text, key.FullName, typeLookup[hashKey].DisplayLabel.text);
                }

                //Add the method to the lookup
                typeLookup[hashKey] = persistentMethod;
            }

            //Stash the values in the general lookup
            objectMethods[key] = typeLookup;
        }