    # 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