# File lib/ftw/server.rb, line 27
  def initialize(addresses)
    addresses = [addresses] if !addresses.is_a?(Array)
    dns = FTW::DNS.singleton

    @control_lock = Mutex.new
    @sockets = {}

    failures = []
    # address format is assumed to be 'host:port'
    # TODO(sissel): The split on ":" breaks ipv6 addresses, yo.
    addresses.each do |address|
      m = ADDRESS_RE.match(address)
      if !m
        raise InvalidAddress.new("Invalid address #{address.inspect}, spected string with format 'host:port'")
      end
      host, port = m[1..2] # first capture is host, second capture is port

      # Permit address being simply ':PORT'
      host = "0.0.0.0" if host.nil?

      # resolve each hostname, use the first one that successfully binds.
      local_failures = []
      dns.resolve(host).each do |ip|
        #family = ip.include?(":") ? Socket::AF_INET6 : Socket::AF_INET
        #socket = Socket.new(family, Socket::SOCK_STREAM, 0)
        #sockaddr = Socket.pack_sockaddr_in(port, ip)
        socket = TCPServer.new(ip, port)
        #begin
          #socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
          #socket.bind(sockaddr)
          # If we get here, bind was successful
        #rescue Errno::EADDRNOTAVAIL => e
          # TODO(sissel): Record this failure.
          #local_failures << "Could not bind to #{ip}:#{port}, address not available on this system."
          #next
        #rescue Errno::EACCES
          # TODO(sissel): Record this failure.
          #local_failures << "No permission to bind to #{ip}:#{port}: #{e.inspect}"
          #next
        #end

        begin
          socket.listen(100)
        rescue Errno::EADDRINUSE
          local_failures << "Address in use, #{ip}:#{port}, cannot listen."
          next
        end

        # Break when successfully listened
        #p :accept? => socket.respond_to?(:accept)
        @sockets["#{host}(#{ip}):#{port}"] = socket
        local_failures.clear
        break
      end
      failures += local_failures
    end

    # This allows us to interrupt the #each_connection's select() later
    # when anyone calls stop()
    @stopper = IO.pipe

    # Abort if there were failures
    raise ServerSetupFailure.new(failures) if failures.any?
  end