# File lib/autumn/stem.rb, line 290
    def initialize(server, newnick, opts)
      raise ArgumentError, "Please specify at least one channel" unless opts[:channel] or opts[:channels]
      
      @nick = newnick
      @server = server
      @port = opts[:port]
      @port ||= 6667
      @local_ip = opts[:local_ip]
      @options = opts
      @listeners = Set.new
      @listeners << self
      @logger = @options[:logger]
      @nick_generator = Proc.new do |oldnick|
        if options[:ghost_without_password] then
          message "GHOST #{oldnick}", 'NickServ'
          nil
        elsif options[:dont_ghost] or options[:password].nil? then
          "#{oldnick}_"
        else
          message "GHOST #{oldnick} #{options[:password]}", 'NickServ'
          nil
        end
      end
      @server_type = Daemon[opts[:server_type]]
      @server_type ||= Daemon.default
      @throttle_rate = opts[:throttle_rate]
      @throttle_rate ||= 1
      @throttle_threshold = opts[:throttle_threshold]
      @throttle_threshold ||= 5
      
      @nick_regex = (opts[:nick_regex] ? opts[:nick_regex] : NICK_REGEX)
      
      @channels = Set.new
      @channels.merge opts[:channels] if opts[:channels]
      @channels << opts[:channel] if opts[:channel]
      @channels.map! do |chan|
        if chan.kind_of? Hash then
          { normalized_channel_name(chan.keys.only) => chan.values.only }
        else
          normalized_channel_name chan
        end
      end
      # Make a hash of channels to their passwords
      @channel_passwords = @channels.select { |ch| ch.kind_of? Hash }.mash { |pair| pair }
      # Strip the passwords from @channels, making it an array of channel names only
      @channels.map! { |chan| chan.kind_of?(Hash) ? chan.keys.only : chan }
      @channel_members = Hash.new
      @updating_channel_members = Hash.new # stores the NAMES list as its being built
      
      if @throttle = opts[:throttle] then
        @messages_queue = Queue.new
        @messages_thread = Thread.new do
          throttled = false
          loop do
            args = @messages_queue.pop
            throttled = true if not throttled and @messages_queue.length >= @throttle_threshold
            throttled = false if throttled and @messages_queue.empty?
            sleep @throttle_rate if throttled
            privmsg *args
          end
        end
      end
      
      @chan_mutex = Mutex.new
      @join_mutex = Mutex.new
      @socket_mutex = Mutex.new
    end