# File lib/core/container.rb, line 108
    def initialize(*args)
      case args.size
      when 2 then @handler, @id = args
      when 1 then
        @id = String.try_convert(args[0]) || (args[0].to_s if args[0].is_a? Symbol)
        @handler = args[0] unless @id
      else raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0..2"
      end
      # Use an empty messaging adapter to give default behaviour if there's no global handler.
      @adapter = Handler::Adapter.adapt(@handler) || Handler::MessagingAdapter.new(nil)
      @id = (@id || SecureRandom.uuid).freeze

      # Implementation note:
      #
      # - #run threads take work from @work
      # - Each driver and the Container itself is processed by at most one #run thread at a time
      # - The Container thread does IO.select
      # - nil on the @work queue makes a #run thread exit

      @work = Queue.new
      @work << :start
      @work << self             # Issue start and start start selecting
      @wake = IO.pipe           # Wakes #run thread in IO.select
      @auto_stop = true         # Stop when @active drops to 0

      # Following instance variables protected by lock
      @lock = Mutex.new
      @active = 0               # All active tasks, in @selectable, @work or being processed
      @selectable = Set.new     # Tasks ready to block in IO.select
      @running = 0              # Count of #run threads
      @stopped = false          # #stop called
      @stop_err = nil           # Optional error to pass to tasks, from #stop
    end