def run_callbacks(kind)
      callbacks = __callbacks[kind.to_sym]

      if callbacks.empty?
        yield if block_given?
      else
        env = Filters::Environment.new(self, false, nil)
        next_sequence = callbacks.compile

        invoke_sequence = Proc.new do
          skipped = nil
          while true
            current = next_sequence
            current.invoke_before(env)
            if current.final?
              env.value = !env.halted && (!block_given? || yield)
            elsif current.skip?(env)
              (skipped ||= []) << current
              next_sequence = next_sequence.nested
              next
            else
              next_sequence = next_sequence.nested
              begin
                target, block, method, *arguments = current.expand_call_template(env, invoke_sequence)
                target.send(method, *arguments, &block)
              ensure
                next_sequence = current
              end
            end
            current.invoke_after(env)
            skipped.pop.invoke_after(env) while skipped && skipped.first
            break env.value
          end
        end

        # Common case: no 'around' callbacks defined
        if next_sequence.final?
          next_sequence.invoke_before(env)
          env.value = !env.halted && (!block_given? || yield)
          next_sequence.invoke_after(env)
          env.value
        else
          invoke_sequence.call
        end
      end
    end
def run_callbacks(kind)
      callbacks = __callbacks[kind.to_sym]

      if callbacks.empty?
        yield if block_given?
      else
        env = Filters::Environment.new(self, false, nil)
        next_sequence = callbacks.compile

        invoke_sequence = Proc.new do
          skipped = nil
          while true
            current = next_sequence
            current.invoke_before(env)
            if current.final?
              env.value = !env.halted && (!block_given? || yield)
            elsif current.skip?(env)
              (skipped ||= []) << current
              next_sequence = next_sequence.nested
              next
            else
              next_sequence = next_sequence.nested
              begin
                target, block, method, *arguments = current.expand_call_template(env, invoke_sequence)
                target.send(method, *arguments, &block)
              ensure
                next_sequence = current
              end
            end
            current.invoke_after(env)
            skipped.pop.invoke_after(env) while skipped && skipped.first
            break env.value
          end
        end

        # Common case: no 'around' callbacks defined
        if next_sequence.final?
          next_sequence.invoke_before(env)
          env.value = !env.halted && (!block_given? || yield)
          next_sequence.invoke_after(env)
          env.value
        else
          invoke_sequence.call
        end
      end
    end
Runs the callbacks for the given event.

 Calls the before and around callbacks in the order they were set, yields
 the block (if given one), and then runs the after callbacks in reverse
 order.

 If the callback chain was halted, returns +false+. Otherwise returns the
 result of the block, +nil+ if no callbacks have been set, or +true+
 if callbacks have been set but no block is given.

   run_callbacks :save do
     save
   end

--

 As this method is used in many places, and often wraps large portions of
 user code, it has an additional design goal of minimizing its impact on
 the visible call stack. An exception from inside a :before or :after
 callback can be as noisy as it likes -- but when control has passed
 smoothly through and into the supplied block, we want as little evidence
 as possible that we were here.