# File lib/rubyipmi.rb, line 76
  def self.connect(user, pass, host, provider='any', opts={:driver => 'lan20', :timeout => 'default'})
    # use this variable to reduce cmd calls
    installed = false

    # if the user supplied nil, we want to fix this automatically
    opts = {:driver => 'lan20', :timeout => 'default'} if opts.nil?

    # convert all keys to symbols for opts, we can't assume the user will use symbols
    opts.keys.each do |key|
      opts[(key.to_sym rescue key) || key] = opts.delete(key)
    end

    # allow the user to specify an options hash instead of the provider
    # in the future I would stop using the provider and use the opts hash instead to get the provider
    # This allows us to be a little more flexible if the user is doesn't supply us what we need.
    if provider.is_a?(Hash)
      opts = provider
      provider = opts[:provider] ||= 'any'
    end

    # Verify options just in case user passed in a incomplete hash
    opts[:driver]  ||= 'lan20'
    opts[:timeout] ||= 'default'

    if opts[:privilege] and not supported_privilege_type?(opts[:privilege])
      logger.error("Invalid privilege type :#{opts[:privilege]}, must be one of: #{PRIV_TYPES.join("\n")}") if logger
      raise "Invalid privilege type :#{opts[:privilege]}, must be one of: #{PRIV_TYPES.join("\n")}"
    end

    # use the first available provider
    if provider == 'any'
      if is_provider_installed?("freeipmi")
        provider = "freeipmi"
        installed = true
      elsif is_provider_installed?("ipmitool")
        provider = "ipmitool"
        installed = true
      else
        logger.error("No IPMI provider is installed, please install freeipmi or ipmitool")
        raise "No IPMI provider is installed, please install freeipmi or ipmitool"
      end
    end

    # Support multiple drivers
    # Note: these are just generic names of drivers that need to be specified for each provider
    unless valid_drivers.include?(opts[:driver])
      logger.debug("You must specify a valid driver: #{valid_drivers.join(',')}") if logger
      raise "You must specify a valid driver: #{valid_drivers.join(',')}"
    end

    # If the provider is available create a connection object
    if installed or is_provider_installed?(provider)
      if provider == "freeipmi"
        Rubyipmi::Freeipmi::Connection.new(user, pass, host, opts)
      elsif provider == "ipmitool"
        Rubyipmi::Ipmitool::Connection.new(user,pass,host, opts)
      else
        logger.error("Incorrect provider given, must use one of #{valid_providers.join(', ')}") if logger
        raise "Incorrect provider given, must use one of #{valid_providers.join(', ')}"
      end
    else
      # Can't find the provider command line tool, maybe try other provider?
      logger.error("The IPMI provider: #{provider} is not installed") if logger
      raise "The IPMI provider: #{provider} is not installed"
    end
  end