_unshare_module()
{
	local cur prev words cword
	local OPTS NOARGOPTS OPTARGOPTS REQARGOPTS REQARGOPTS_SHORT NOARGOPTS_SHORT
	_init_completion -n = -- "$@" || return

	OPTARGOPTS="--mount=|--uts=|--ipc=|--net=|--pid=|--user=|--cgroup=|--time=|--kill-child=|--mount-proc=|--mount-binfmt="

	REQARGOPTS="--owner|--propagation|--setgroups|--root|--wd|--load-interp|--map-group|--map-groups|--map-user|--map-users|--monotonic|--boottime|--setuid|--setgid"

	REQARGOPTS_SHORT="-l|-R|-w|-S|-G"

	NOARGOPTS="--fork|--forward-signals|--map-root-user|--map-current-user|--map-auto|--map-subids|--keep-caps|--help|--version|${OPTARGOPTS//=/}"

	NOARGOPTS_SHORT="-r|-f|-c|-h|-V|-m|-u|-i|-n|-p|-U|-C|-T"

	OPTS="${NOARGOPTS//[|]/ } ${NOARGOPTS_SHORT//[|]/ } ${OPTARGOPTS//[|]/ } ${REQARGOPTS//[|]/ } ${REQARGOPTS_SHORT//[|]/ }"

	# Check if we are still completing unshare(1) and set 
	# the offset so that it points to the command that is
	# going to be executed, in order to complete it with
	# its own completion specification.
	local offset=0 i
	for ((i = 1; i < cword; i++)); do
		if [[ "${words[i]}" =~ ^--$ ]]; then
			((i++))
		elif [[ "${words[i]}" =~ ^($NOARGOPTS|$NOARGOPTS_SHORT)$ ]]; then
			continue
		elif [[ "${words[i]}" =~ ^($OPTARGOPTS).* ]]; then
			continue
		elif [[ "${words[i]}" =~ ^($REQARGOPTS|$REQARGOPTS_SHORT)$ ]]; then
			[[ "${words[$((i+1))]}" != -* ]] && ((i++))
			continue
		fi
		offset=$i
		break
	done

	if (( offset > 0 )); then
		# Find completion specification for the wrapped command
		_command_offset $offset
	else
		# $OPTARGOPTS deserve special treatment due
		# to the '=' that delimits the actual argument
		# that we wish to complete and the option name
		if [[ "$cur" =~ ^($OPTARGOPTS).* ]]; then
			# Cut also backslash before '=' in case it ended up there
			# for some reason.
			prev=${cur%%?(\\)=*}
			cur=${cur#*=}

			compopt -o nospace
			case $prev in
				'--kill-child')
					COMPREPLY=( $(compgen -A signal -- $cur) )
					return 0
					;;
				*)
					COMPREPLY=( $(compgen -f -d -- $cur) )
					return 0
					;;
			esac
		fi

		case $prev in
			'--propagation')
				COMPREPLY=( $(compgen -W "slave shared private unchanged" -- $cur) )
				return 0
				;;
			'--setgroups')
				COMPREPLY=( $(compgen -W "allow deny" -- $cur) )
				return 0
				;;
			'-w'|'--wd'|'-l'|'--load-interp'|'-R'|'--root')
				# It's better than simply using 'compgen -f',
				# because it honours spaces in filenames.
				_filedir
				return 0
				;;
			'-S'|'--setuid')
				local uids
				uids="$(awk -F: '{print $3}' /etc/passwd | sort --numeric-sort)"
				COMPREPLY=( $(compgen -W "$uids" -- $cur) )
				return 0
				;;
			'-G'|'--setgid')
				local gids
				gids="$(awk -F: '{print $3}' /etc/group | sort --numeric-sort)"
				COMPREPLY=( $(compgen -W "$gids" -- $cur) )
				return 0
				;;
			'-h'|'--help'|'-V'|'--version')
				return 0
				;;
		esac

		if [[ "$cur" == -* ]]; then
			COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
			return 0
		else
			COMPREPLY=( $(compgen -c -- "$cur") )
		fi
	fi
	return 0
}
complete -F _unshare_module -o bashdefault -o default unshare
