// This unbinds all methods marked with this attribute
        private void UnbindMethods(object obj, Type type)
        {
            if (obj == null)
            {
                General.WriteLogLine("Unbinding static action methods for class " + type.Name + "...");
            }
            else
            {
                General.WriteLogLine("Unbinding action methods for " + type.Name + " object...");
            }

            // Go for all methods on obj
            MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
            //foreach (MethodInfo m in methods)
            int methodsCount = methods.Length;

            for (int i = 0; i < methodsCount; i++)
            {
                MethodInfo m = methods[i];
                // Check if the method has this attribute
                ActionAttribute[] attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(BeginActionAttribute), true);

                // Go for all attributes
                //foreach (ActionAttribute a in attrs)
                int attrsCount = attrs.Length;
                for (int j = 0; j < attrsCount; j++)
                {
                    ActionAttribute a = attrs[j];
                    // Create a delegate for this method
                    ActionDelegate del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m);

                    // Make proper name
                    string actionname = a.GetFullActionName(type.Assembly);

                    // Unbind method from action
                    actions[actionname].UnbindBegin(del);
                }

                // Check if the method has this attribute
                attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(EndActionAttribute), true);

                // Go for all attributes
                //foreach (ActionAttribute a in attrs)
                attrsCount = attrs.Length;
                for (int j = 0; j < attrsCount; j++)
                {
                    ActionAttribute a = attrs[j];
                    // Create a delegate for this method
                    ActionDelegate del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m);

                    // Make proper name
                    string actionname = a.GetFullActionName(type.Assembly);

                    // Unbind method from action
                    actions[actionname].UnbindEnd(del);
                }
            }
        }
        // This binds all methods marked with this attribute
        private void BindMethods(object obj, Type type)
        {
            if (obj == null)
            {
                General.WriteLogLine("Binding static action methods for class " + type.Name + "...");
            }
            else
            {
                General.WriteLogLine("Binding action methods for " + type.Name + " object...");
            }

            // Go for all methods on obj
            MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
            //foreach(MethodInfo m in methods)
            int methodsCount = methods.Length;

            for (int i = 0; i < methodsCount; i++)
            {
                MethodInfo m = methods[i];
                // Check if the method has this attribute
                ActionAttribute[] attrs = (ActionAttribute[])methods[i].GetCustomAttributes(typeof(BeginActionAttribute), true);

                int attrsCount = attrs.Length;
                // Go for all attributes
                //foreach(ActionAttribute a in attrs)
                for (int j = 0; j < attrsCount; j++)
                {
                    ActionAttribute a = attrs[j];

                    // Create a delegate for this method
                    ActionDelegate del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m);

                    // Make proper name
                    string actionname = a.GetFullActionName(type.Assembly);

                    // Bind method to action
                    if (Exists(actionname))
                    {
                        actions[actionname].BindBegin(del);
                    }
                    else
                    {
                        throw new ArgumentException("Could not bind " + m.ReflectedType.Name + "." + m.Name + " to action \"" + actionname + "\", that action does not exist! Refer to, or edit Actions.cfg for all available application actions.");
                    }
                }

                // Check if the method has this attribute
                attrs      = (ActionAttribute[])m.GetCustomAttributes(typeof(EndActionAttribute), true);
                attrsCount = attrs.Length;
                // Go for all attributes
                //foreach (ActionAttribute a in attrs)
                for (int j = 0; j < attrsCount; j++)
                {
                    ActionAttribute a = attrs[j];

                    // Create a delegate for this method
                    ActionDelegate del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m);

                    // Make proper name
                    string actionname = a.GetFullActionName(type.Assembly);

                    // Bind method to action
                    if (Exists(actionname))
                    {
                        actions[actionname].BindEnd(del);
                    }
                    else
                    {
                        throw new ArgumentException("Could not bind " + m.ReflectedType.Name + "." + m.Name + " to action \"" + actionname + "\", that action does not exist. Refer to, or edit Actions.cfg for all available application actions.");
                    }
                }
            }
        }