install_hook (Extlib::Hook::ClassMethods)

    # File lib/extlib/hook.rb, line 308
          def install_hook(type, target_method, method_sym, scope, &block)
            assert_kind_of 'target_method', target_method, Symbol
            assert_kind_of 'method_sym',    method_sym,    Symbol unless method_sym.nil?
            assert_kind_of 'scope',         scope,         Symbol

            if !block_given? and method_sym.nil?
              raise ArgumentError, "You need to pass 2 arguments to \"#{type}\"."
            end

            if method_sym.to_s[-1,1] == '='
              raise ArgumentError, "Methods ending in = cannot be hooks"
            end

            unless [ :class, :instance ].include?(scope)
              raise ArgumentError, 'You need to pass :class or :instance as scope'
            end

            if registered_as_hook?(target_method, scope)
              hooks = hooks_with_scope(scope)

              #if this hook is previously declared in a sibling or cousin we must move the :in class
              #to the common ancestor to get both hooks to run.
              if !(hooks[target_method][:in] <=> self)
                before_hook_name = hook_method_name(target_method, 'execute_before', 'hook_stack')
                after_hook_name  = hook_method_name(target_method, 'execute_after',  'hook_stack')

                hooks[target_method][:in].class_eval "remove_method :\#{before_hook_name} if instance_methods(false).any? { |m| m.to_sym == :\#{before_hook_name} }\ndef \#{before_hook_name}(*args)\nsuper\nend\n\nremove_method :\#{after_hook_name} if instance_methods(false).any? { |m| m.to_sym == :\#{before_hook_name} }\ndef \#{after_hook_name}(*args)\nsuper\nend\n", __FILE__, __LINE__ + 1

                while !(hooks[target_method][:in] <=> self) do
                  hooks[target_method][:in] = hooks[target_method][:in].superclass
                end

                define_hook_stack_execution_methods(target_method, scope)
                hooks[target_method][:in].class_eval{define_advised_method(target_method, scope)}
              end
            else
              register_hook(target_method, scope)
              hooks = hooks_with_scope(scope)
            end

            #if  we were passed a block, create a method out of it.
            if block
              method_sym = "__hooks_#{type}_#{quote_method(target_method)}_#{hooks[target_method][type].length}".to_sym
              if scope == :class
                meta_class.instance_eval do
                  define_method(method_sym, &block)
                end
              else
                define_method(method_sym, &block)
              end
            end

            # Adds method to the stack an redefines the hook invocation method
            hooks[target_method][type] << { :name => method_sym, :from => self }
            define_hook_stack_execution_methods(target_method, scope)
          end