# File lib/automateit/plugin/driver.rb, line 145
      def available?
        # Some drivers don't run +depends_on+, so assume they're available.
        return true unless self.class.respond_to?(:_depends_on_opts)
        opts = self.class._depends_on_opts

        # Driver said that it +depends_on :nothing+, so it's available.
        return true if opts == :nothing

        is_available = self.class._is_available
        if is_available.nil? and opts.nil?
          #log.debug(PNOTE+"don't know if driver #{self.class} is available, maybe it doesn't state what it +depends_on+")
          return false
        elsif is_available.nil?
          all_present = true
          missing = {}

          # Check callbacks last
          kinds = opts.keys
          callbacks = kinds.delete(:callbacks)
          kinds << callbacks if callbacks

          begin
            for kind in kinds
              next unless opts[kind]
              for item in [opts[kind]].flatten
                present = \
                  case kind
                  when :files
                    File.exists?(item)
                  when :directories
                    File.directory?(item)
                  when :programs
                    # TODO Driver#available? - Find better way to locate the platform's #which driver and use it to check if a program exists. This is tricky because this #available? method is the one that handles detection, yet we have to bypass it.
                    result = nil
                    for variant in %w(unix windows)
                      variant_token = "which_#{variant}".to_sym
                      begin
                        driver = interpreter.shell_manager[variant_token]
                        result = driver.which!(item)
                        ### puts "%s : %s for %s" % [variant, result, item]
                        break
                      rescue ArgumentError, NotImplementedError, NoMethodError => e
                        # Exceptions are expected, only print for debugging
                        ### puts e.inspect
                      end
                    end
                    result
                  when :requires, :libraries
                    begin
                      require item
                      true
                    rescue LoadError
                      false
                    end
                  when :callbacks
                    item.call() ? true : false
                  else
                    raise TypeError.new("Unknown kind: #{kind}")
                  end
                unless present
                  all_present = false
                  missing[kind] ||= []
                  missing[kind] << item

                  # Do not continue scanning if dependency is missed
                  raise EOFError.new("break")
                end
              end
            end
          rescue EOFError => e
            # Ignore expected "break" warning
            raise e unless e.message == "break"
          end
          self.class._missing_dependencies = missing
          self.class._is_available = all_present
          log.debug(PNOTE+"Driver #{self.class} #{all_present ? "is" : "isn't"} available")
        end
        return self.class._is_available
      end