def event(*names, &block)
      options = names.last.is_a?(Hash) ? names.pop : {}
      options.assert_valid_keys(:human_name)

      # Store the context so that it can be used for / matched against any event
      # that gets added
      @events.context(names, &block) if block_given?

      if names.first.is_a?(Matcher)
        # Add any events referenced in the matcher.  When matchers are used,
        # events are not allowed to be configured.
        raise ArgumentError, "Cannot configure events when using matchers (using #{options.inspect})" if options.any?
        events = add_events(names.first.values)
      else
        events = add_events(names)

        # Update the configuration for the event(s)
        events.each do |event|
          event.human_name = options[:human_name] if options.include?(:human_name)

          # Add any states that may have been referenced within the event
          add_states(event.known_states)
        end
      end

      events.length == 1 ? events.first : events
    end
def event(*names, &block)
      options = names.last.is_a?(Hash) ? names.pop : {}
      options.assert_valid_keys(:human_name)

      # Store the context so that it can be used for / matched against any event
      # that gets added
      @events.context(names, &block) if block_given?

      if names.first.is_a?(Matcher)
        # Add any events referenced in the matcher.  When matchers are used,
        # events are not allowed to be configured.
        raise ArgumentError, "Cannot configure events when using matchers (using #{options.inspect})" if options.any?
        events = add_events(names.first.values)
      else
        events = add_events(names)

        # Update the configuration for the event(s)
        events.each do |event|
          event.human_name = options[:human_name] if options.include?(:human_name)

          # Add any states that may have been referenced within the event
          add_states(event.known_states)
        end
      end

      events.length == 1 ? events.first : events
    end
Defines one or more events for the machine and the transitions that can
 be performed when those events are run.

 This method is also aliased as +on+ for improved compatibility with
 using a domain-specific language.

 Configuration options:
 * <tt>:human_name</tt> - The human-readable version of this event's name.
   By default, this is either defined by the integration or stringifies the
   name and converts underscores to spaces.

 == Instance methods

 The following instance methods are generated when a new event is defined
 (the "park" event is used as an example):
 * <tt>park(..., run_action = true)</tt> - Fires the "park" event,
   transitioning from the current state to the next valid state.  If the
   last argument is a boolean, it will control whether the machine's action
   gets run.
 * <tt>park!(..., run_action = true)</tt> - Fires the "park" event,
   transitioning from the current state to the next valid state.  If the
   transition fails, then a StateMachines::InvalidTransition error will be
   raised.  If the last argument is a boolean, it will control whether the
   machine's action gets run.
 * <tt>can_park?(requirements = {})</tt> - Checks whether the "park" event
   can be fired given the current state of the object.  This will *not* run
   validations or callbacks in ORM integrations.  It will only determine if
   the state machine defines a valid transition for the event.  To check
   whether an event can fire *and* passes validations, use event attributes
   (e.g. state_event) as described in the "Events" documentation of each
   ORM integration.
 * <tt>park_transition(requirements = {})</tt> -  Gets the next transition
   that would be performed if the "park" event were to be fired now on the
   object or nil if no transitions can be performed.  Like <tt>can_park?</tt>
   this will also *not* run validations or callbacks.  It will only
   determine if the state machine defines a valid transition for the event.

 With a namespace of "car", the above names map to the following methods:
 * <tt>can_park_car?</tt>
 * <tt>park_car_transition</tt>
 * <tt>park_car</tt>
 * <tt>park_car!</tt>

 The <tt>can_park?</tt> and <tt>park_transition</tt> helpers both take an
 optional set of requirements for determining what transitions are available
 for the current object.  These requirements include:
 * <tt>:from</tt> - One or more states to transition from.  If none are
   specified, then this will be the object's current state.
 * <tt>:to</tt> - One or more states to transition to.  If none are
   specified, then this will match any to state.
 * <tt>:guard</tt> - Whether to guard transitions with the if/unless
   conditionals defined for each one.  Default is true.

 == Defining transitions

 +event+ requires a block which allows you to define the possible
 transitions that can happen as a result of that event.  For example,

   event :park, :stop do
     transition :idling => :parked
   end

   event :first_gear do
     transition :parked => :first_gear, :if => :seatbelt_on?
     transition :parked => same # Allow to loopback if seatbelt is off
   end

 See StateMachines::Event#transition for more information on
 the possible options that can be passed in.

 *Note* that this block is executed within the context of the actual event
 object.  As a result, you will not be able to reference any class methods
 on the model without referencing the class itself.  For example,

   class Vehicle
     def self.safe_states
       [:parked, :idling, :stalled]
     end

     state_machine do
       event :park do
         transition Vehicle.safe_states => :parked
       end
     end
   end

 == Overriding the event method

 By default, this will define an instance method (with the same name as the
 event) that will fire the next possible transition for that.  Although the
 +before_transition+, +after_transition+, and +around_transition+ hooks
 allow you to define behavior that gets executed as a result of the event's
 transition, you can also override the event method in order to have a
 little more fine-grained control.

 For example:

   class Vehicle
     state_machine do
       event :park do
         ...
       end
     end

     def park(*)
       take_deep_breath  # Executes before the transition (and before_transition hooks) even if no transition is possible
       if result = super # Runs the transition and all before/after/around hooks
         applaud         # Executes after the transition (and after_transition hooks)
       end
       result
     end
   end

 There are a few important things to note here.  First, the method
 signature is defined with an unlimited argument list in order to allow
 callers to continue passing arguments that are expected by state_machine.
 For example, it will still allow calls to +park+ with a single parameter
 for skipping the configured action.

 Second, the overridden event method must call +super+ in order to run the
 logic for running the next possible transition.  In order to remain
 consistent with other events, the result of +super+ is returned.

 Third, any behavior defined in this method will *not* get executed if
 you're taking advantage of attribute-based event transitions.  For example:

   vehicle = Vehicle.new
   vehicle.state_event = 'park'
   vehicle.save

 In this case, the +park+ event will run the before/after/around transition
 hooks and transition the state, but the behavior defined in the overriden
 +park+ method will *not* be executed.

 == Defining additional arguments

 Additional arguments can be passed into events and accessed by transition
 hooks like so:

   class Vehicle
     state_machine do
       after_transition :on => :park do |vehicle, transition|
         kind = *transition.args # :parallel
         ...
       end
       after_transition :on => :park, :do => :take_deep_breath

       event :park do
         ...
       end

       def take_deep_breath(transition)
         kind = *transition.args # :parallel
         ...
       end
     end
   end

   vehicle = Vehicle.new
   vehicle.park(:parallel)

 *Remember* that if the last argument is a boolean, it will be used as the
 +run_action+ parameter to the event action.  Using the +park+ action
 example from above, you can might call it like so:

   vehicle.park                    # => Uses default args and runs machine action
   vehicle.park(:parallel)         # => Specifies the +kind+ argument and runs the machine action
   vehicle.park(:parallel, false)  # => Specifies the +kind+ argument and *skips* the machine action

 If you decide to override the +park+ event method *and* define additional
 arguments, you can do so as shown below:

   class Vehicle
     state_machine do
       event :park do
         ...
       end
     end

     def park(kind = :parallel, *args)
       take_deep_breath if kind == :parallel
       super
     end
   end

 Note that +super+ is called instead of <tt>super(*args)</tt>.  This allow
 the entire arguments list to be accessed by transition callbacks through
 StateMachines::Transition#args.

 === Using matchers

 The +all+ / +any+ matchers can be used to easily execute blocks for a
 group of events.  Note, however, that you cannot use these matchers to
 set configurations for events.  Blocks using these matchers can be
 defined at any point in the state machine and will always get applied to
 the proper events.

 For example:

   state_machine :initial => :parked do
     ...

     event all - [:crash] do
       transition :stalled => :parked
     end
   end

 == Example

   class Vehicle
     state_machine do
       # The park, stop, and halt events will all share the given transitions
       event :park, :stop, :halt do
         transition [:idling, :backing_up] => :parked
       end

       event :stop do
         transition :first_gear => :idling
       end

       event :ignite do
         transition :parked => :idling
         transition :idling => same # Allow ignite while still idling
       end
     end
   end