docs: def install(self,
  	            package,
  	            options=None,
  	            timeout=shutit_global.shutit_global_object.default_timeout,
  	            force=False,
  	            check_exit=True,
  	            echo=None,
  	            reinstall=False,
  	            run_in_background=False,
  	            ignore_background=False,
  	            block_other_commands=True,
  	            note=None,
  	            loglevel=logging.INFO):
  		"""Distro-independent install function.
  		Takes a package name and runs the relevant install function.
  
  		@param package:    Package to install, which is run through package_map
  		@param timeout:    Timeout (s) to wait for finish of install. Defaults to 3600.
  		@param options:    Dictionary for specific options per install tool.
  		                   Overrides any arguments passed into this function.
  		@param force:      Force if necessary. Defaults to False
  		@param check_exit: If False, failure to install is ok (default True)
  		@param reinstall:  Advise a reinstall where possible (default False)
  		@param note:       See send()
  
  		@type package:     string
  		@type timeout:     integer
  		@type options:     dict
  		@type force:       boolean
  		@type check_exit:  boolean
  		@type reinstall:   boolean
  
  		@return: True if all ok (ie it's installed), else False.
  		@rtype: boolean
  		"""
  		shutit = self.shutit
  		# If separated by spaces, install separately
  		if package.find(' ') != -1:
  			ok = True
  			for p in package.split(' '):
  				if not self.install(p,options,timeout,force,check_exit,reinstall,note):
  					ok = False
  			return ok
  		# Some packages get mapped to the empty string. If so, bail out with 'success' here.
  		if note != None:
  			shutit.handle_note('Installing package: ' + package + '\n' + note)
  		shutit.log('Installing package: ' + package, level=loglevel)
  		if options is None: options = {}
  		install_type = self.current_environment.install_type
  		if install_type == 'src':
  			# If this is a src build, we assume it's already installed.
  			return True
  		elif install_type == 'none':
  			# If this is a none build, installing is invalid.
  			shutit.fail('ShutiIt has no install type for the identified OS, so cannot use install method. Inform maintainers if believed to be a bug.') # pragma: no cover
  		opts = ''
  		cmd = ''
  		if self.package_installed(package):
  			shutit.log(package + ' already installed.', level=loglevel)
  			return True
  		if install_type == 'apt':
  			if not shutit.get_current_shutit_pexpect_session_environment().build['apt_update_done'] and self.whoami() == 'root':
  				opts = '-y'
  				if self.shutit.loglevel > logging.DEBUG:
  					opts += ' -qq'
  				self.send(ShutItSendSpec(self,
  				                         send='apt-get ' + opts + ' update',
  				                         loglevel=logging.INFO,
  				                         echo=echo,
  				                         run_in_background=False,
  				                         ignore_background=False,
  				                         block_other_commands=True))
  				shutit.get_current_shutit_pexpect_session_environment().build['apt_update_done'] = True
  			cmd += 'DEBIAN_FRONTEND=noninteractive apt-get install'
  			if 'apt' in options:
  				opts = options['apt']
  			else:
  				opts = '-y'
  				if self.shutit.loglevel > logging.DEBUG:
  					opts += ' -qq'
  				if force:
  					opts += ' --force-yes'
  				if reinstall:
  					opts += ' --reinstall'
  		elif install_type == 'yum':
  			# TODO: check whether it's already installed?. see yum notes  yum list installed "$@" >/dev/null 2>&1
  			cmd += 'yum install'
  			if 'yum' in options:
  				opts = options['yum']
  			else:
  				if self.shutit.loglevel > logging.DEBUG:
  					opts += ' -q'
  				opts += ' -y'
  			if reinstall:
  				opts += ' reinstall'
  		elif install_type == 'pacman':
  			cmd += 'pacman -Syy'
  			if 'pacman' in options:
  				opts = options['pacman']
  		elif install_type == 'apk':
  			cmd += 'apk add'
  			if 'apk' in options:
  				opts = options['apk']
  		elif install_type == 'emerge':
  			cmd += 'emerge'
  			if 'emerge' in options:
  				opts = options['emerge']
  		elif install_type == 'docker':
  			cmd += 'docker pull'
  			if 'docker' in options:
  				opts = options['docker']
  		elif install_type == 'brew':
  			cmd += 'brew install'
  			if 'brew' in options:
  				opts = options['brew']
  			else:
  				opts += ' --force'
  		else:
  			# Not handled
  			return False
  		# Get mapped packages.
  		package = package_map.map_packages(self, package, self.current_environment.install_type)
  		# Let's be tolerant of failure eg due to network.
  		# This is especially helpful with automated exam.
  		if package.strip() != '':
  			fails = 0
  			while True:
  				pw = self.get_sudo_pass_if_needed(shutit, ignore_brew=True)
  				if pw != '':
  					cmd = 'sudo ' + cmd
  					res = self.multisend(ShutItSendSpec(self,
  					                                    send='%s %s %s' % (cmd, opts, package),
  					                                    send_dict={'assword':[pw, True]},
  					                                    expect=['Unable to fetch some archives',self.default_expect],
  					                                    timeout=timeout,
  					                                    check_exit=False,
  					                                    loglevel=loglevel,
  					                                    echo=echo,
  					                                    secret=True))
  					if res == -1:
  						## Should not happen
  						#assert False, shutit_util.print_debug()
  						break
  					shutit.log('Result of install attempt was: ' + str(res), level=logging.DEBUG)
  				else:
  					res = self.send(ShutItSendSpec(self,
  					                               send='%s %s %s' % (cmd, opts, package),
  					                               expect=['Unable to fetch some archives',self.default_expect],
  					                               timeout=timeout,
  					                               check_exit=False,
  					                               loglevel=loglevel,
  				                                   echo=echo,
  					                               ignore_background=ignore_background,
  					                               run_in_background=run_in_background,
  				                                   block_other_commands=block_other_commands))
  					if res == -1:
  						## Should not happen
  						#assert False, shutit_util.print_debug()
  						break
  					shutit.log('Result of install attempt was: ' + str(res), level=logging.DEBUG)
  				# Does not work!
  				if res == 1:
  					break
  				else:
  					fails += 1
  					if fails >= 3:
  						shutit.pause_point('Failed to install ' + package)
  						return False
  		else:
  			# package not required
  			shutit.log('Package not required.', level=logging.DEBUG)
  
  		shutit.log('Package is installed.', level=logging.DEBUG)
  		# Sometimes we see installs (eg yum) reset the terminal to a state
  		# ShutIt does not like.
  		self.reset_terminal()
  		shutit.handle_note_after(note=note)
  		return True