# File lib/rbot/messagemapper.rb, line 528
    def recognize(m)

      debug "Testing #{m.message.inspect} against #{self.inspect}"

      # Early out
      return nil, "template #{@template} is not configured for private messages" if @options.has_key?(:private) && !@options[:private] && m.private?
      return nil, "template #{@template} is not configured for public messages" if @options.has_key?(:public) && !@options[:public] && !m.private?

      options = {}

      matching = @regexp.match(m.message)
      return nil, "#{m.message.inspect} doesn't match #{@template} (#{@regexp})" unless matching
      return nil, "#{m.message.inspect} only matches #{@template} (#{@regexp}) partially: #{matching[0].inspect}" unless matching[0] == m.message

      debug_match = matching[1..-1].collect{ |d| d.inspect}.join(', ')
      debug "#{m.message.inspect} matched #{@regexp} with #{debug_match}"
      debug "Associating #{debug_match} with dyn items #{@dyn_items.join(', ')}"

      @dyn_items.each_with_index { |it, i|
        next if i == 0
        item = it.name
        debug "dyn item #{item} (multi-word: #{it.multi?.inspect})"
        if it.multi?
          if matching[i].nil?
            default = it.default
            case default
            when Array
              value = default.clone
            when String
              value = default.strip.split
            when nil, false, []
              value = []
            else
              warning "Unmanageable default #{default} detected for :*#{item.to_s}, using []"
              value = []
            end
            case default
            when String
              value.instance_variable_set(:@string_value, default)
            else
              value.instance_variable_set(:@string_value, value.join(' '))
            end
          else
            value = matching[i].split
            value.instance_variable_set(:@string_value, matching[i])
          end
          def value.to_s
            @string_value
          end
        else
          if matching[i].nil?
            warning "No default value for option #{item.inspect} specified" unless @defaults.has_key?(item)
            value = it.default
          else
            value = it.collect(matching[i])
          end
        end
        options[item] = value
        debug "set #{item} to #{options[item].inspect}"
      }

      options.delete_if {|k, v| v.nil?} # Remove nil values.
      return options, nil
    end