/// <summary>
        /// Output the <see cref="HelpDisplayAttribute"/> attribute elements for the supplied types
        /// </summary>
        /// <typeparam name="T">The type of object that is to be displayed for help information</typeparam>
        /// <param name="log">The output method that is being used to log the messages to the output</param>
        public static void Log <T>(LogMessageLineDel log = null)
        {
            //Check there is an output location
            if (log == null)
            {
                log = Console.WriteLine;
            }

            //Store the type that is going to be used for the operation
            Type type = typeof(T);

            //Retrieve all of the values to check for output
            var fields  = RetrieveFields(type);
            var props   = RetrieveProperties(type);
            var methods = RetrieveMethods(type);

            //Output the fields with help information
            if (fields.Count() > 0)
            {
                foreach (var field in fields)
                {
                    //Output the basic information
                    OutputHelpMessage(field, log);

                    //Output a blank line for the next section
                    log(string.Empty);
                }
            }

            //Output the properties with help information
            if (props.Count() > 0)
            {
                foreach (var prop in props)
                {
                    //Output the basic information
                    OutputHelpMessage(prop, log);

                    //Output a blank line for the next section
                    log(string.Empty);
                }
            }

            //Output the methods with help information
            if (methods.Count() > 0)
            {
                foreach (var method in methods)
                {
                    //Output the basic information
                    OutputHelpMessage(method, log);

                    //Output a blank line for the next section
                    log(string.Empty);
                }
            }
        }
        /// <summary>
        /// Output the Help Display information that is attached to the supplied member object
        /// </summary>
        /// <param name="member">The member object that is to be processed</param>
        /// <param name="log">The output method that is being used to log the messages to the output</param>
        private static void OutputHelpMessage(MemberInfo member, LogMessageLineDel log, Action onComplete = null)
        {
            //Retrieve the HelpDisplay attributes from the member object
            IEnumerable <ACallableAttribute> helpers = member.GetCustomAttributes <ACallableAttribute>(false);

            //Iterate through the list of options
            foreach (ACallableAttribute att in helpers)
            {
                //Output the values of the object
                log($"Identifier: {att.Identifier}");
                log($"\t|-> Description: {att.Desciption}");
                log($"\t|-> Example: {att.Example}");

                //Handle the on complete behaviour
                onComplete?.Invoke();
            }
        }
        //PUBLIC

        /// <summary>
        /// Output the <see cref="HelpDisplayAttribute"/> attribute elements for the supplied object with their current values
        /// </summary>
        /// <param name="obj">The object that is to have the HelpDisplayElements extracted from it</param>
        /// <param name="log">The output method that is being used to log the messages to the output. Will use <see cref="Console.WriteLine"/> by default</param>
        public static void Log(object obj, LogMessageLineDel log = null)
        {
            //Check there is an output location
            if (log == null)
            {
                log = Console.WriteLine;
            }

            //Store the type that is going to be used for the operation
            Type type = obj.GetType();

            //Retrieve all of the values to check for output
            var fields  = RetrieveFields(type);
            var props   = RetrieveProperties(type);
            var methods = RetrieveMethods(type);

            //Output the fields with help information
            if (fields.Count() > 0)
            {
                foreach (var field in fields)
                {
                    //Output the basic information
                    OutputHelpMessage(field, log, () => {
                        log($"\t|-> Value: {field.GetValue(obj).ToString()}");
                    });

                    //Output a blank line for the next section
                    log(string.Empty);
                }
            }

            //Output the properties with help information
            if (props.Count() > 0)
            {
                foreach (var prop in props)
                {
                    //Output the basic information
                    OutputHelpMessage(prop, log, () => {
                        //Check if the property can be read
                        if (prop.CanRead)
                        {
                            log($"\t|-> Value: {prop.GetValue(obj)}");
                        }
                    });

                    //Output a blank line for the next section
                    log(string.Empty);
                }
            }

            //Output the methods with help information
            if (methods.Count() > 0)
            {
                foreach (var method in methods)
                {
                    //Output the basic information
                    OutputHelpMessage(method, log);

                    //Output a blank line for the next section
                    log(string.Empty);
                }
            }
        }