#!/bin/bash
# Copyright megabaks
# Distributed under the terms of the GNU General Public License v3 or later
############################################################################
################ portage functions #########################################
if [[ -f "/lib/gentoo/functions.sh" ]]; then
	source /lib/gentoo/functions.sh
else
	source /usr/lib*/portage/bin/isolated-functions.sh
fi
############################################################################
################ colors ####################################################
green="\033[01;32m"
red="\033[01;31m"
restore="\033[00m"
contrast="\033[1m"
underline="\033[4m"
############################################################################
################ init ######################################################
PKGDB="/var/db/pkg"
BRDIR="/var/lib/portconf"
PORT_ETC="/etc/portage"
WORLD="/var/lib/portage/world"
ARCH="$(eix --print DEFAULT_ARCH)"
[[ -f "/etc/portconf.conf" ]] && . /etc/portconf.conf
COUNT="${COUNT:-10}"
############################################################################
################ ignore ####################################################
[[ -n "${IGNORE_CATEGORY}" ]] && IGNORE_CATEGORY="$(sed -e '/^$/d' -e 's/$/\/.*/g' <<< "`tr "[:space:]" $'\n' <<< "${IGNORE_CATEGORY}"`")"
[[ -n "${IGNORE_PN}" ]] && IGNORE_PN="$(sed -e '/^$/d' -e 's/^/.*\//g' <<< "`tr "[:space:]" $'\n' <<< "${IGNORE_PN}"`")"
IGNORE="${IGNORE_CATEGORY}
${IGNORE_PN}"
IGNORE="$(sed -e '/^$/d' <<< "${IGNORE}")"
IGNORE="${IGNORE:-'Hello, LOR! :3'}"
############################################################################
################ sort_passed_uses ##########################################
sort_passed_uses(){
	for opt in ${1};do
		opt="${opt//\*/\\*}"
		uses="$(tr "[:space:]" $'\n' <<< ${uses} | grep -v -e "^${opt#-}$" -e "^\-${opt#-}$" | tr $'\n' " ")"
		uses+=" $(tr "[:space:]" $'\n' <<< ${1} | grep -e "^${opt#-}$" -e "^\-${opt#-}$" | tail -n1)"
		unset opt
	done
	echo ${uses}
	unset uses
}
############################################################################
################ profile ###################################################
profile() {
	local use path
	[[ -f "${1}/make.defaults" ]] && . "${1}/make.defaults"
	use="$USE"
	if [[ -f "${1}/parent" ]]; then
		for path in `cat ${1}/parent`;do
			use="$use $(profile "${1}/$path")"
		done
	fi
	echo $use
}

[[ -h "/etc/make.profile" ]] && pre_profile="$(profile `readlink -f /etc/make.profile`)"
[[ -h "/etc/portage/make.profile" ]] && pre_profile="$(profile `readlink -f /etc/portage/make.profile`)"
profile_uses="$(sort_passed_uses "${pre_profile}")"
PROFILE="$(tr "[:space:]" $'\n' <<< ${profile_uses})"
############################################################################
################ all_use_all_profiles ######################################
all_use_all_profiles(){
	for target in `eselect --brief profile list`;do
		profile_uses="$(profile "${PORTDIR}/profiles/${target}")"
		USEs="$(sort_passed_uses "${profile_uses}")"
		echo -e "\n${green}${target}${restore}: "${USEs} | fold -s -w `tput cols`
		unset USEs
	done
}
############################################################################
################ profile_use ###############################################
profile_use(){
	PS3=`echo -e "${contrast}Choose number:${restore} "`
	select target in `eselect --brief profile list`;do
		profile_uses="$(profile "${PORTDIR}/profiles/${target}")"
		USEs="$(sort_passed_uses "${profile_uses}")"
		echo -e "\n${green}${target}${restore}: "${USEs} | fold -s -w `tput cols`
		unset USEs
		break
	done
}
############################################################################
################ current_profile ###########################################
current_profile(){
	if [[ -h "/etc/make.profile" ]];then
		target="$(readlink /etc/make.profile | sed 's|.*/profiles/||')"
	else
		target="$(readlink /etc/portage/make.profile | sed 's|.*/profiles/||')"
	fi
	profile_uses="$(profile "${PORTDIR}/profiles/${target}")"
	USEs="$(sort_passed_uses "${PROFILE}")"
	echo -e "${green}${target}${restore}: "${USEs} | fold -s -w `tput cols`
	unset USEs
}
############################################################################
################ make.conf #################################################
[[ -f "/etc/make.conf" ]] && makefile="/etc/make.conf"
[[ -f "${PORT_ETC}/make.conf" ]] && makefile="${PORT_ETC}/make.conf"
. "${makefile}" 2>/dev/null
MAKE_USES="${USE}"
unset USE
PORTDIR="${PORTDIR:-/usr/portage}"
############################################################################
################ timestamp #################################################
timestamp(){
	stat -c %Y ${*} 2>/dev/null | sort | tail -n1
}
############################################################################
################ repo fix ##################################################
repo_fix(){
	if [[ -n "${PORTDIR_OVERLAY}" ]];then
		for path in ${PORTDIR_OVERLAY};do
			local_categories="$(ls -d1 ${path}/{*-*,virtual} 2>/dev/null | sed -e "s|${path}/||g" | sort -u)"
			portage_categoties="$(cat ${PORTDIR}/profiles/categories)"
			if [[ -n "$(grep -v "${portage_categoties}" <<< "${local_categories}")" ]];then
				if [[ ! -f "${path}/profiles/categories" ]];then
					[[ ! -d "${path}/profiles" ]] && mkdir "${path}/profiles" && tmp_categories+=" ${path}/profiles"
					echo -e "Creating temporary 'categories': ${path}"
					echo "${local_categories}" >> "${path}/profiles/categories"
					tmp_categories+=" ${path}/profiles/categories"
				fi
			fi
		done
	fi
}
############################################################################
################ rm repo fix ###############################################
rm_repo_fix(){
	if [[ -n "${tmp_categories}" ]];then
		for tmp_category in ${tmp_categories};do
			rm -rf "${tmp_category}"
		done
	fi
}
############################################################################
################ eix check #################################################
eix_check(){
	if [[ -n "$(eix --version 2>/dev/null)" ]];then
		echo -e "${underline}Creating new temporary cache.${restore}"
		repo_fix
		eix_cache="$(mktemp)"
		chown portage:portage "${eix_cache}" 2>/dev/null
		export EIX_CACHEFILE="${eix_cache}"
		export OVERLAY_CACHE_METHOD="parse|ebuild*"
		eix-update
	else
		echo -e "${green}app-portage/eix${restore} ${red}not installed!${restore}"
		eend 1 2>/dev/null
		exit 1
	fi
	rm_repo_fix
}
############################################################################
################ eix check method ##########################################
eix_method(){
	if [[ -n "$(eix --version 2>/dev/null)" ]];then
		if [[ "$(eix --print OVERLAY_CACHE_METHOD)" != "parse|ebuild*" ]];then
			[[ -n "${yes}" ]] && eix_check
			echo -ne "\n${red}!default 'OVERLAY_CACHE_METHOD'${restore}${contrast}
Create temporary cache?${restore} [${green}Yes${restore}/${red}No${restore}] ";
			while read x;do
				case ${x} in
					Yes | YES | yes | Y | y | "" )
						eix_check
						break;;
					No | NO | no | N | n )
						break;;
					* ) echo -ne "Sorry, response '${x}' not understood. [${green}Yes${restore}/${red}No${restore}] "
						continue;;
				esac
			done
		fi
	else
		echo -e "${green}app-portage/eix${restore} ${red}not installed!${restore}"
		eend 1 2>/dev/null
		exit 1
	fi
}
############################################################################
################ backup ####################################################
backup(){
	[[ -d "${BRDIR}" ]] || mkdir -p "${BRDIR}"
	tarballs="$(ls -1 --color=never ${BRDIR})"
	oldest="$(head -n1 <<< "${tarballs}")"
	newest="$(tail -n1 <<< "${tarballs}")"
	count="$( wc -l <<< "${tarballs}")"
	count="${count:-0}"
	if [[ -f "/etc/make.conf" ]];then
		etc_update="$(timestamp ${PORT_ETC}/{*,*/*,*/*/*,*/*/*/*} /etc/make.conf)"
	else
		etc_update="$(timestamp ${PORT_ETC}/{*,*/*,*/*/*,*/*/*/*})"
	fi
	portconf_update="$(timestamp ${BRDIR}/*)"
	portconf_update="${portconf_update:-0}"
	if (( "${etc_update}" > "${portconf_update}" ));then
		if (( "${count}" >= "${COUNT}" ));then
			rm "${BRDIR}/${oldest}"
		fi
		echo -e "/etc/portage backup: ${green}creating${restore}..."
		name="${BRDIR}/portage_$(date +%g.%m.%d-%H:%M).tar.bz2"
		if [[ -f "/etc/make.conf" ]];then
			tar -jcf "${name}" -C /etc/ portage make.conf
		else
			tar -jcf "${name}" -C /etc/ portage
		fi
		eend $? 2>/dev/null
	else
		echo -e "/etc/portage backups: ${green}already up-to-date${restore}"
		eend $? 2>/dev/null
	fi
}
############################################################################
################ world_backup ##############################################
world_backup(){
	world_dir="${BRDIR}/world"
	[[ -d "${world_dir}" ]] || mkdir -p "${world_dir}"
	tarballs="$(ls -1 --color=never ${world_dir})"
	oldest="$(head -n1 <<< "${tarballs}")"
	newest="$(tail -n1 <<< "${tarballs}")"
	count="$( wc -l <<< "${tarballs}")"
	count="${count:-0}"
	world_update="$(timestamp ${WORLD})"
	portconf_update="$(timestamp ${world_dir}/*)"
	portconf_update="${portconf_update:-0}"
	if (( "${world_update}" > "${portconf_update}" ));then
		if (( "${count}" >= "${COUNT}" ));then
			rm "${world_dir}/${oldest}"
		fi
		echo -e "world backup: ${green}creating${restore}..."
		name="${world_dir}/world_$(date +%g.%m.%d-%H:%M).tar.bz2"
		tar -jcf "${name}" -C ${WORLD%world} world
		eend $? 2>/dev/null
	else
		echo -e "world backups: ${green}already up-to-date${restore}"
		eend $? 2>/dev/null
	fi
}
############################################################################
################ restore ###################################################
restore(){
	tarballs="$(ls -1 --color=never ${1}/*.bz2)"
	tarballs="${tarballs//${1}\/}"
	tarballs="${tarballs//.tar.bz2/}"
	tarballs="${tarballs//${2}_/}"
	PS3=`echo -e "${contrast}Choose number:${restore} "`
	echo -e "${contrast}Available backups${restore}:"
	select answer in ${tarballs};do
		echo -e "Rolling back ${3} to the state ${green}${answer}${restore}"
		[[ -n "${5}" ]] && rm -rf ${5}
		tar -xf "${1}/${2}_${answer}.tar.bz2" -C ${4} 2>/dev/null
		eend $? 2>/dev/null
		break
	done
}
############################################################################
################ etc_restore ###############################################
etc_restore(){
	restore "${BRDIR}" "portage" "${PORT_ETC}" "/etc/" "${PORT_ETC}/*"
}
############################################################################
################ world_restore #############################################
world_restore(){
	restore "${BRDIR}/world" "world" "${WORLD}" "${WORLD%world}"
}
############################################################################
################ diff_ask ##################################################
diff_ask(){
	my_diff="$(diff ${1} ${2} | grep --color=never "[[:digit:]][a-z][[:digit:]]")"
	if [[ -n "${my_diff}" ]];then
		while read subj;do
			old_num="$(tr ',' ' ' <<< "${subj%[a-z]*}")"
			[[ "$(wc -w <<< "${old_num}")" == "2" ]] && old_num="$(seq ${old_num})"
			new_num="$(tr ',' ' ' <<< "${subj#*[a-z]}")"
			[[ "$(wc -w <<< "${new_num}")" == "2" ]] && new_num="$(seq ${new_num})"

			action="$(grep -o "[a-z]" <<< "${subj}")"
 			if [[ "${action}" == "a" ]];then
				for num in ${new_num};do
					[[ "${num}" != "0" ]] && full_diff+="${num}^#+#${green}`sed -n "${num}p" "${2}"`${restore}#"$'\n'
				done
			elif [[ "${action}" == "d" ]];then
				for num in ${old_num};do
					[[ "${num}" != "0" ]] && full_diff+="${num}^#-#${red}`sed -n "${num}p" "${1}"`${restore}#"$'\n'
				done
			elif [[ "${action}" == "c" ]];then
				for num in ${old_num};do
					[[ "${num}" != "0" ]] && full_diff+="${num}^#-#${red}`sed -n "${num}p" "${1}"`${restore}#"$'\n'
				done
				for num in ${new_num};do
					[[ "${num}" != "0" ]] && full_diff+="${num}^#+#${green}`sed -n "${num}p" "${2}"`${restore}#"$'\n'
				done
			fi
		done <<< "${my_diff}"
		echo -e "\n${contrast}Changes for ${green}${1}${restore}:${restore}"
		echo "###############################################"
		echo -e "${full_diff%\\n}" | column -s \^ -t
		echo "###############################################"
		if [[ -z "${yes}" && -z "${PRETEND}" ]];then
			echo -ne "${contrast}Apply changes?${restore} [${green}Yes${restore}/${red}No${restore}] ";
			while read x;do
				case ${x} in
					Yes | YES | yes | Y | y | "" )
						if [[ "${UID}" == "0" ]];then
							mv "${2}" "${1}" 2>/dev/null
							chmod 0644 "${1}"
						else
							echo -e "you are ${red}!root${restore} ---> go away!"
							exit 1
						fi
						unset full_diff
						return 0
						break;;
					No | NO | no | N | n )
						unset full_diff
						rm "${2}" 2>/dev/null
						return 0
						break;;
					* ) echo -ne "Sorry, response '${x}' not understood. [${green}Yes${restore}/${red}No${restore}] "
						continue;;
				esac
			done
		elif [[ -n "${yes}" && -z "${PRETEND}" ]];then
			mv "${2}" "${1}" 2>/dev/null
			chmod 0644 "${1}"
			unset full_diff
			return 0
		elif [[ -z "${yes}" && -n "${PRETEND}" ]];then
			unset full_diff
			rm "${2}" 2>/dev/null
			return 0
			break
		fi
	fi
	rm "${2}" 2>/dev/null
	return 0
}
############################################################################
################ remove_ask ################################################
remove_ask(){
	if [[ -z "${yes}" && -z "${PRETEND}" ]];then
		echo -ne "${contrast}Remove${restore} ${green}${1}${restore}${contrast}?${restore} [${green}Yes${restore}/${red}No${restore}] "
		while read x;do
			case ${x} in
				Yes | YES | yes | Y | y | "" )
					rm -rf ${1} 2>/dev/null
					break;;
				No | NO | no | N | n )
					break;;
				* ) echo -ne "Sorry, response '${x}' not understood. [${green}Yes${restore}/${red}No${restore}] "
					continue;;
			esac
		done
		eend $? 2>/dev/null
	elif [[ -n "${yes}" && -z "${PRETEND}" ]];then
		echo -e "${contrast}Removing${restore} ${green}${1}${restore}"
		rm -rf ${1} 2>/dev/null
		eend $? 2>/dev/null
	elif [[ -z "${yes}" && -n "${PRETEND}" ]];then
		eend 0 2>/dev/null
	fi
}
############################################################################
################ sort_packages #############################################
sort_uniq_files(){
	for package in `find ${PORT_ETC}/ -type f \! -name '*~' \! -name '*.bak' | grep "/package\."`;do
		tmp_sort="$(mktemp)"
		echo -e "${underline}Sorting${restore} ${contrast}${package#${PORT_ETC}/}${restore}"

		all_atoms="$(awk '{print $1}' "${package}" | grep -v "^#"| sort -u)"
		while read atom;do
			opts="$(grep "^${atom//\*/\\*} " "${package}" | uniq | cut -d" " -f2-)"
			echo "${atom} ${opts//$'\n'/ }" >> "${tmp_sort}"
		done <<< "${all_atoms}"

		sed -e '/^$/d' -e 's/[ \t]*$//' -i ${tmp_sort}
		sort -u "${tmp_sort}" -o "${tmp_sort}" 2>/dev/null
		diff_ask "${package}" "${tmp_sort}"
		eend $? 2>/dev/null
	done
}
############################################################################
################ file or dir... ############################################
file_or_dir(){
	local founded
	for i in ${1};do
		founded+=" $(ls -d1 ${PORT_ETC}/${i} 2>/dev/null)"
	done
	if [[ -z "${founded}" ]];then
		echo -e "${underline}${2}${restore}${contrast}${PORT_ETC}/${1}${restore}: No such file or directory${restore}"
		eend 1 2>/dev/null
		return 1
	fi
	for target in ${founded};do
		if [[ -f "${target}" ]];then
			file="${target}"
			if [[ -s ${file} ]];then
				echo -e "${underline}${2}${restore} ${contrast}${file#${PORT_ETC}/}${restore}"
				${3};${4};${5};${6};${7};
			else
				echo -e "${underline}Empty file${restore} ${contrast}${file}${restore}"
				remove_ask "${file}"
				eend $? 2>/dev/null
			fi
		elif [[ -d "${target}" ]];then
			for f in `find ${target} -type f \! -name '*~' \! -name '*.bak'`;do
				file="${f}"
				if [[ -s ${file} ]];then
					echo -e "${underline}${2}${restore} ${contrast}${file#${PORT_ETC}/}${restore}"
					${3};${4};${5};${6};${7};
				else
					echo -e "${underline}Empty file${restore} ${contrast}${file}${restore}"
					remove_ask "${file}"
					eend $? 2>/dev/null
					continue
				fi
			done
		fi
	done
}
############################################################################
################ rm_comments ###############################################
rm_comments(){
	no_newline(){
		tmp_file="$(mktemp)"
		cp "${file}" "${tmp_file}"
		sed -e "s|^#.*||g" -e '/^$/d' -i ${tmp_file}
		diff_ask "${file}" "${tmp_file}"
		eend $? 2>/dev/null
	}
	file_or_dir "package.*" "Checking comments:" "no_newline" || return 1
}
############################################################################
################ rm_all_comments ###########################################
rm_all_comments(){
	no_newline_inline(){
		tmp_file="$(mktemp)"
		cp "${file}" "${tmp_file}"
		sed -e "s|#.*||g" -e 's/[ \t]*$//' -e '/^$/d' -i ${tmp_file}
		diff_ask "${file}" "${tmp_file}"
		eend $? 2>/dev/null
	}
	file_or_dir "package.*" "Checking comments:" "no_newline_inline"  || return 1
}
############################################################################
################ sort_uses #################################################
sort_uses(){
	tmp_file="$(mktemp)"
	striped="$(mktemp)"
	PACKAGES="$(awk '{print $1}' ${file} | grep -v '^#.*' | uniq)"
	for atom in ${PACKAGES};do
		comment="$(grep "${atom}[[:space:]].*#" "${file}" | cut -d\# -f2-)"
		for option in \
		"$(grep "^${atom//\*/\\*}[[:space:]]" ${file} | sed -e "s|${atom//\*/\\*} ||" -e "s|#.*${comment}||" | tr "[:space:]" $'\n' | uniq | tr $'\n' " ")";do
			atom_opts+="${option}"
		done
		uses="$(sort_passed_uses "${atom_opts}")"
		uses="$(sed -e "s|^- | |g" -e "s| -- ||g" -e "s| - | |g" <<< ${uses})"
		if [[ -n "${comment}" ]];then
			echo "${atom} ${uses} #${comment}" >> "${tmp_file}"
		else
			echo "${atom} ${uses}" >> "${tmp_file}"
		fi
		unset atom atom_opts option options uses comment
	done
	cp "${tmp_file}" "${striped}" 2>/dev/null

	while read atom opt;do
		[[ -z "${opt}" ]] && sed -e "s|^${atom} ||" -i "${striped}" 2>/dev/null
		unset atom opt
	done < "${tmp_file}"
	sed -e 's/[ \t]*$//' -e '/^$/d' -e 's|  | |g' -e "s| - | |g" -i "${striped}" 2>/dev/null
	sort -u "${striped}" -o "${striped}" 2>/dev/null
	rm "${tmp_file}" 2>/dev/null
	diff_ask "${file}" "${striped}"
	eend $? 2>/dev/null
} 2>/dev/null
############################################################################
################ package.use ###############################################
sort_use_file(){
	file_or_dir "package.use" "Sorting use flags in" "set -f" "sort_uses" "set +f" || return 1
}
############################################################################
################ stupid_keyword ############################################
stupid_keywords(){
	unset ACCEPT_KEYWORDS
	local ACCEPT_KEYWORDS="$(eix --print ACCEPT_KEYWORDS)"
	for KEY in ${ACCEPT_KEYWORDS};do
		while read satom lkeys;do
			comment="$(cut -d\# -f2- <<< "${lkeys}")"
			lkeys="${lkeys%%#*}"
			lkeys="${lkeys%% }"
			out_keys="$(tr ' ' $'\n' <<< "${lkeys}")"
			#### wildcards
			pcategory="${satom%%/*}"
			pcategory="$(tr -d "<>=~" <<< "${pcategory}")"
			parent_keys="$(grep -e "${pcategory}/\*" -e "\*/\*" "${1}" | sed 's|^.* ||' | sort -u)"
			#### /wildcards
			if [[ "${satom}" != "${pcategory}/*" && "${satom}" != "*/*" ]];then
				for key in ${lkeys};do
					for pkey in ${parent_keys};do
						if [[ "${key}" == "${KEY}" || ${key} == "${pkey}" ]];then
							echo -e "Twice defined keyword ${red}${key}${restore}:\t${green}${satom}${restore}"
							out_keys="$(grep -v "`printf ${key}`"  <<< "${out_keys}")"
						fi
					done
				done
			fi
			out_keys="$(tr $'\n' ' ' <<< "${out_keys}")"
			out_keys="${out_keys% }"
			if [[ "${lkeys}" != "${out_keys}" ]];then
				if [[ -n "${out_keys% }" ]];then
					if [[ -n "${comment}" ]];then
						string="$(grep "^${satom} ${lkeys} .*#${comment}$" "${1}")"
						fixed_string="${satom} ${out_keys% } #${comment}"
					else
						string="$(grep "^${satom} ${lkeys}$" "${1}")"
						fixed_string="${satom} ${out_keys}"
					fi
				else
					string="$(grep "^${satom} ${lkeys}.*$" "${1}")"
					fixed_string=""
				fi
				sed -e "s|^${string//\*/\\*}$|${fixed_string}|"  -e '/^$/d' -i "${2}" || echo fail 525
			fi
		done < "${1}"
	done
}
############################################################################
################ sort_keys #################################################
sort_keys(){
	tmp_file="$(mktemp)"
	striped="$(mktemp)"
	PACKAGES="$(awk '{print $1}' ${file} | grep -v '^#.*' | uniq)"
	for atom in ${PACKAGES};do
		comment="$(grep "${atom}[[:space:]].*#" "${file}" | cut -d\# -f2-)"
		for option in \
		"$(grep "^${atom//\*/\\*}[[:space:]]" ${file} | sed -e "s|${atom//\*/\\*} ||" -e "s|#.*${comment}||" | tr "[:space:]" $'\n' | uniq | tr $'\n' " ")";do
			atom_opts+="${option}"
		done
		keys="$(sort_passed_uses "${atom_opts}")"
		keys="$(sed -e "s|^- | |g" -e "s| -- ||g" -e "s| - | |g" <<< ${keys})"
		keys="${keys:-"~${ARCH}"}"
		if [[ -n "${comment}" ]];then
			echo "${atom} ${keys} #${comment}" >> "${tmp_file}"
		else
			echo "${atom} ${keys}" >> "${tmp_file}"
		fi
		unset atom atom_opts option options keys comment
	done
	cp "${tmp_file}" "${striped}" 2>/dev/null

	while read atom opt;do
		[[ -z "${opt}" ]] && sed -e "s|^${atom}[ \t]$|${atom} ~${ARCH}|;s|^${atom}$|${atom} ~${ARCH}|" -i "${striped}" 2>/dev/null
		unset atom opt
	done < "${tmp_file}"

	sed -e 's/[ \t]*$//' -e '/^$/d' -e 's|  | |g' -e "s| - | |g" -i "${striped}" 2>/dev/null
	sort -u "${striped}" -o "${striped}" 2>/dev/null
	cp "${striped}" "${tmp_file}"
	stupid_keywords "${tmp_file}" "${striped}"
	rm "${tmp_file}" 2>/dev/null
	diff_ask "${file}" "${striped}"
	eend $? 2>/dev/null
} #2>/dev/null
############################################################################
################ one_keyword ###############################################
sort_keywords(){
	keys(){
		tmp_file="$(mktemp)"
		striped="$(mktemp)"
		atoms="$(awk '{print $1}' "${file}" | sort -u)"
		while read atom;do
			comment="$(grep "${atom}[[:space:]].*#" "${file}" | cut -d\# -f2-)"
			keyword="$(grep "${atom}[[:space:]]" ${file} | sed -e "s|${atom} ||" -e "s|#.*${comment}||" |\
						tr "[:space:]" $'\n' | sed '/^$/d' | tail -n1)"
			keyword="${keyword:-"~${ARCH}"}"
			if [[ -n "${comment}" ]];then
				echo "${atom} ${keyword} #${comment}" >> "${tmp_file}"
			else
				echo "${atom} ${keyword}" >> "${tmp_file}"
			fi
		done <<< "${atoms}"
		sort -u "${tmp_file}" -o "${tmp_file}" 2>/dev/null
		cp "${tmp_file}" "${striped}"
		stupid_keywords "${striped}" "${tmp_file}"
		rm "${striped}"
		diff_ask "${file}" "${tmp_file}"
		eend $? 2>/dev/null
	}
	file_or_dir "package.keywords package.accept_keywords" "Sorting keywords in" "keys" || return 1
}
############################################################################
################ uniq_keyword ##############################################
uniq_keywords(){
	file_or_dir "package.keywords package.accept_keywords" "Sorting keywords in" "set -f" "sort_keys" "set +f" || return 1
}
############################################################################
################ not_installed #############################################
installed(){
	installed="$(qlist -ICSec "${category}/${pn}" | awk '{print $2}')"
	if [[ -n "${installed}" ]];then
		installed_vers="$(awk -F \: '{print $1}' <<< "${installed}")"
		installed_min_ver="$(head -n1 <<< "${installed_vers}")"
		installed_max_ver="$(tail -n1 <<< "`grep -v 9999 <<< "${installed_vers}"`")"
		installed_live_ver="$(tail -n1 <<< "`grep 9999 <<< "${installed_vers}"`")"
		installed_slots="$(awk -F \: '{print $2}' <<< "${installed}")"
		#::repo check
		full_vers="$(qlist -ICev "${category}/${pn}" | sed "s|${category}/${pn}-||g")"
		(( "$(wc -l <<< "${full_vers}")" '>' "1" ))
		if [[ -n "${defined_repo}" ]];then
			for ver in ${full_vers};do
				all_vers+=" ${PKGDB}/${category}/${pn}-${ver}/repository"
			done
			grep -qe "^${defined_repo}$" ${all_vers} || unset installed
			unset all_vers
		fi
		[[ "${installed_slots}" == "0" ]] && unset installed_slots
	fi
}

not_if(){
	atoms="$(awk '{print $1}' <<< "`grep -v "^#" < ${package}`")"
	[[ -n "${IGNORE}" ]] && atoms="$(grep -v "${IGNORE}" <<< "${atoms}")"
	echo -e "${underline}Checking${restore} ${contrast}$package${restore}"
	if [[ -n "${atoms}" ]];then
		while read atom;do
			#::repo check
			if grep -q "::" <<< "${atom}";then
				defined_repo="${atom##*::}"
			else
				unset defined_repo
			fi
			[[ -n "${defined_repo}" ]] && atom="${atom%%::${defined_repo}}"
			while read category pn ver rev slot;do
				sw="$(grep -o "[<>=~]" <<< "${category}" | tr -d $'\n')"
				category="${category##${sw}}"

				[[ "${category}" == "(null)" || "${pn}" == "(null)" ]] && continue

				if [[ -n "${rev}" ]] && [[ -z "${slot}" ]] && `grep -q \: <<< "${rev}"`;then
					slot="${rev}"
					unset rev
				fi
				slot="${slot#:}"
				pn="${pn%:}"
				installed;

				if [[ -z "${installed}" ]];then
					if [[ -n "${defined_repo}" ]];then
						echo -e "${red}Not installed${restore} ${green}${category}/${pn}::${underline}${defined_repo}${restore}"
					else
						echo -e "${red}Not installed${restore} ${green}${category}/${pn}${restore}"
					fi
					sed -e "s|.*\<${category}/${pn}\>.*||" -e '/^$/d' -i "${tmp_package}" 2>/dev/null
					eend $? 2>/dev/null
				fi
			done <<< `qatom "${atom}"`
		done <<< "${atoms}"
	fi
}

force_not_installed(){
	for package in `find ${PORT_ETC}/package* -type f \! -name '*~' \! -name '*.bak'`;do
		if [[ -s "${package}" && -n "$(grep -v "^#" < "${package}")" ]];then
			tmp_package="$(mktemp)"
			cp "${package}" "${tmp_package}"
			if ! `grep -q "\.mask" <<< "${package}"`;then
				not_if;
				eend $? 2>/dev/null
			fi
			diff_ask "${package}" "${tmp_package}"
		else
			pack="${package%/*}"
			echo -e "${underline}Empty file${restore} ${contrast}${pack}${restore}"
			remove_ask "${package}"
			eend $? 2>/dev/null
		fi
	done

	for x in `find ${PORT_ETC}/package* -type f`;do
		if [[ ! -s "${x}" ]];then
			echo -e "${underline}Empty file${restore} ${contrast}${x}${restore}"
			remove_ask "${x}"
			eend $? 2>/dev/null
		fi
	done
}
############################################################################
################ package.env conf ##########################################
package_env_conf(){
	all_confs="$(find ${PORT_ETC}/env/ -maxdepth 1 -type f)"
	all_confs="${all_confs//${PORT_ETC////\/}\/env\//}"
	check_env_conf(){
		atoms="$(sed 's/^[ \t]*//;s/[ \t]*$//;/^#/d;/^$/d;' < ${file} | awk '{print $1}')"
		while read line;do
			line="$(sed 's/^[ \t]*//;s/[ \t]*$//' <<< "${line%%#*}")"
			for atom in ${atoms};do
				USED_ENV+=" ${line#${atom} }"
			done
		done < "${file}"
		USED_ENV="$(tr ' ' $'\n' <<< "${USED_ENV}")"
		for conf in ${all_confs};do
			if ! grep -q "^${conf}$" <<< "${USED_ENV}";then
				echo -e "Unused conf: ${red}${conf}${restore}"
				remove_ask "${PORT_ETC}/env/${conf}"
				eend $? 2>/dev/null
			fi
		done
	}
	file_or_dir "package.env" "Checking unused configs in" "check_env_conf" || return 1
}
############################################################################
################ package.env ###############################################
package_env(){
	package_env_def(){
		tmp_file="$(mktemp)"
		cp "${file}" "${tmp_file}"
		while read line;do
			xline="$(sed 's/^[ \t]*//;s/[ \t]*$//' <<< "${line%%#*}")"
			atom="${xline%% *}"
			all_confs="${xline#${atom} }"
			for conf in ${all_confs};do
				if [[ -f "${PORT_ETC}/env/${conf}" ]];then
					IGNORE+=$'\n'"${conf}"
				else
					echo -e "Defined conf not exists: ${red}${conf}${restore}"
					new_line=$(grep -v "^${conf}$" <<< "$(tr ' ' $'\n' <<< "${line}")" | tr $'\n' ' ')
					new_line="$(sed 's/^[ \t]*//;s/[ \t]*$//' <<< "${new_line}")"
					sed "s|${line}|${new_line}|" -i "${tmp_file}"
					line="${new_line}"
				fi
			done
		done < "${file}"
		diff_ask "${file}" "${tmp_file}"
		eend $? 2>/dev/null
	}
	file_or_dir "package.env" "Checking defined configs in" "package_env_def" || return 1
}
############################################################################
################ env not_installed #########################################
env_not_installed(){
	echo -e "${underline}Looking not installed in${restore} ${contrast}${PORT_ETC}/env${restore}"
	for x in "env" "env.d";do
		files="$(find ${PORT_ETC}/${x}/ -mindepth 2 -maxdepth 2 -type f \! -name '*~' \! -name '*.bak' 2>/dev/null| cut -d\/ -f5-)"
		[[ -n "${IGNORE}" ]] && files="$(grep -v "${IGNORE}" <<< "${files}")"
		dirs="$(find ${PORT_ETC}/${x}/ -type d 2>/dev/null)"
		[[ -n "${IGNORE}" ]] && dirs="$(grep -v "${IGNORE}" <<< "${dirs}")"
		[[ -n "${files}" || -n "${dirs}" ]] || break

		while read file;do
			atom="$(qatom "${file}")"
			atom="$(sed -e '/^$/d' <<< "${atom}")"
			while read category pn ver rev slot;do
				[[ "${category}" == "(null)" || "${pn}" == "(null)" ]] && continue
				[[ "${ver}" == "(null)" ]] && ver="${ver//(null)/}"
				if [[ -n "${rev}" ]] && ! `grep -q \: <<< "${rev}"`;then
					full_ver="${ver}-${rev}"
				else
					full_ver="${ver}"
				fi

				[[ -n "${rev}" && -z "${slot}" ]] && grep -q \: <<< "${rev}" && slot="${rev}"
				slot="${slot#:}"

				if [[ -z "${ver}" && -z "${slot}" ]];then
					if ! ls -d1 ${PKGDB}/${category}/${pn}-[0-9]* &>/dev/null;then
						echo -e "${red}Not installed${restore} ${green}${category}/${pn}${restore}"
						RM+="${PORT_ETC}/${x}/${file}%"
						eend $? 2>/dev/null
					fi
				fi

				if [[ -n "${ver}" && -z "${slot}" ]] ;then
					if ! ls -d1 ${PKGDB}/${category}/${pn}-${full_ver} &>/dev/null;then
						echo -e "${red}Not installed${restore} ${green}${category}/${pn}-${full_ver}${restore}"
						RM+="${PORT_ETC}/${x}/${file}%"
						eend $? 2>/dev/null
					fi
				fi

				if [[ -z "${ver}" && -n "${slot}" ]] ;then
					if [[ -z "$(cat ${PKGDB}/${category}/${pn}-[0-9]*/SLOT 2>/dev/null | grep ${slot})" ]];then
						echo -e "${red}Not installed${restore} ${green}${category}/${pn}:${slot}${restore}"
						RM+="${PORT_ETC}/${x}/${file}%"
						eend $? 2>/dev/null
					fi
				fi
			done <<< "${atom}"
		done <<< "${files}"

		IFS="%"
		for target in ${RM%\%};do
			remove_ask "${target}"
		done
		IFS=$'\n'
		for target in ${dirs};do
			[[ -z "`ls ${target}`" ]] && remove_ask "${target}"
		done
	unset IFS
	done
	eend $? 2>/dev/null
}
############################################################################
################ incorrect uses ############################################
invalid_uses(){
	set -f
	FULL="${PROFILE} ${MAKE_USES}"
	for opt in ${FULL};do
		GLOBAL+=" $(echo ${FULL} | tr "[:space:]" $'\n' | grep -e "^${opt#-}$" -e "^\-${opt#-}$" | tail -n1)"
	done
	GLOBAL="$(echo ${GLOBAL} | tr "[:space:]" $'\n' | sort -u)"
############################################################################
	check_uses(){
		echo -e "${underline}Checking use flags in${restore} ${contrast}${file#${PORT_ETC}/}${restore}:"
		##### eix env #####
		export OVERLAYS_LIST="no"
		export FORMAT='<availableversions:USEONLY>'
		export USEONLY=' <colliuse>'
		#### just count
		tput sc
		tput civis
		while read category pn ver slot;do
			tput el
			tput el1
			echo -ne "["; printf "% ${chars}d" $((count--));echo -ne " ]" "atoms left" 2>/dev/null
			tput rc
			prepare(){
				while read string;do
					struse="${string#${category}/${pn}}"
					struse="$(tr "[:space:]" $'\n' <<< ${struse})"
					usefxd="$(sed -e "s|^${trash#-}$||" -e "s|^\-${trash#-}$||" -e '/^$/d' <<< "${struse}")"
					usefxd="$(tr $'\n' " " <<< "${usefxd}")"
					usefxd="$(sed -e 's| - | |g' -e 's/[ -]*$//' <<< ${usefxd})"
					strfxd="${category}/${pn} ${usefxd}"
					sed -e "s|^${category}/${pn}[[:space:]].*${trash#-}.*|$strfxd|" -i ${tmp_file} 2>/dev/null
					eend $? 2>/dev/null
				done <<< "${strings}"
			}

			prepare_similar(){
				while read string;do
					struse="${string#${category}/${pn}}"
					struse="$(tr "[:space:]" $'\n' <<< ${struse})"
					usefxd="$(sed -e "s|^${use#-}$|${similar_use}|" -e "s|^\-${use#-}$|\-${similar_use}|" -e '/^$/d' <<< "${struse}")"
					usefxd="$(tr $'\n' " " <<< "${usefxd}")"
					usefxd="$(sed -e 's| - | |g' -e 's/[ -]*$//' <<< ${usefxd})"
					strfxd="${category}/${pn} ${usefxd}"
					sed -e "s|^${category}/${pn}[[:space:]].*${use#-}.*|$strfxd|" -i ${tmp_file} 2>/dev/null
					eend $? 2>/dev/null
				done <<< "${strings}"
			}

			ALL_USE=" $(eix -e "${category}/${pn}")" || continue
			ALL_USE="$(sed -e 's| +| |g;s| -| |g;s|(+)||g;s|(-)||g' <<< "${ALL_USE}" | tr "[:space:]" $'\n' | sort -u | sed -e '/^$/d')"
			LOCAL="$(grep "\<${category}/${pn}\> " "${file}" | cut -d" " -f2- | sed -e "s|#.*||g" | tr "[:space:]" $'\n' | sort -u)"
			USES="$(sed -e 's|^-||g' <<< "${LOCAL}")"
			for use in ${USES};do
				if ! grep -q "^${use}$" <<< "${ALL_USE}" && [[ "${use}" != "*" ]];then
					for agrep_opt in 1 2 3 B;do
						for use_opt in "${use}" "^${use}" "${use}$" "^${use}$";do
							similar_use="$(agrep -${agrep_opt} "${use_opt}" 2>/dev/null <<< "${ALL_USE}")"
							[[ -n "${similar_use}" ]] && (( $(wc -l <<< "${similar_use}") '==' 1 )) && break
						done
						[[ -n "${similar_use}" ]] && (( $(wc -l <<< "${similar_use}") '==' 1 )) && break
						[[ -z "${similar_use}" ]] || (( $(wc -l <<< "${similar_use}") '>' 1 )) && similar_use=""
					done
					if [[ -z "${similar_use}" ]];then
						grep -q " ${use}\>" <<< "${incorrect_use}" || incorrect_use="${incorrect_use} ${use}"
					else
						strings="$(grep "^${category}/${pn}[[:space:]].*\<${use}\>" ${tmp_file})"
						echo -e "${category}/${pn}: ${red}${use} ---> ${green}${similar_use}${restore}"
						prepare_similar;
						incorrect_use="${incorrect_use// ${similar_use}/}"
					fi
				else
					incorrect_use="${incorrect_use// ${use}/}"
				fi

				if grep -q "^${use}$" <<< "${GLOBAL}" && grep -q "^${use}$" <<< "${LOCAL}";then
					global_use="${global_use} ${use}"
				elif grep -q "^\-${use}$" <<< "${GLOBAL}" && grep -q "^\-${use}$" <<< "${LOCAL}";then
					global_use="${global_use} -${use}"
					incorrect_use="${incorrect_use// ${use}/}"
				fi
			done

			incorrect_use="$(echo ${incorrect_use} | tr "[:space:]" $'\n' | sed -e 's|  | |g' -e '/^ $/d' -e '/^$/d' | sort -u)"
			global_use="$(echo ${global_use} | tr "[:space:]" $'\n' | sed -e 's|  | |g' -e '/^ $/d' -e '/^$/d' | sort -u)"
			if [[ -n "${incorrect_use}" ]];then
				while read trash;do
					echo -e "Invalid use: ${green}${category}/${pn}${restore}: ${red}${trash}${restore}"
					strings="$(grep "^${category}/${pn}[[:space:]].*\<${trash}\>" ${tmp_file})"
					prepare;
				done <<< "${incorrect_use}"
			fi
			if [[ -n "${global_use}" ]];then
				while read trash;do
					echo -e "Global  use: ${green}${category}/${pn}${restore}: ${red}${trash}${restore}"
					strings="$(grep "^${category}/${pn}[[:space:]].*\<${trash#-}\>" ${tmp_file})"
					prepare;
				done <<< "${global_use}"
			fi
			unset ALL_USE LOCAL USES incorrect_use global_use use
		done <<< "`[[ -n "${atoms}" ]] && echo -e "${atoms}"`"
		while read atom opt;do
			if [[ -n "${atom}" ]] && [[ -z "${opt}" ]];then
				echo -e "Removing atom: ${green}${atom}${restore}"
				sed -e "s|^${atom} *$||" -e '/^$/d' -i "${tmp_file}" 2>/dev/null
				eend $? 2>/dev/null
			fi
		done <<< "$([[ -n "${IGNORE}" ]] && grep -v "${IGNORE}" < "${file}" || cat "${file}")"
		while read atom opt;do
			if [[ -n "${atom}" ]] && [[ -z "${opt}" ]];then
				echo -e "Removing atom: ${green}${atom}${restore}"
				sed -e "s|^${atom} *$||" -e '/^$/d' -i "${tmp_file}" 2>/dev/null
				eend $? 2>/dev/null
			fi
		done <<< "$([[ -n "${IGNORE}" ]] && grep -v "${IGNORE}" < "${tmp_file}" || cat "${tmp_file}")"
		eend $? 2>/dev/null
		unset FORMAT USEONLY
	}
	if [[ -f "${PORT_ETC}/package.use" ]];then
		file="${PORT_ETC}/package.use"
		tmp_file="$(mktemp)"
		cp "${file}" "${tmp_file}"
		if [[ -n "${IGNORE}" ]];then
			content="$(awk '{print $1}' ${file} | tr -d "<>=~" | sed -e 's|^#.*||g' | grep -v "${IGNORE}")"
			[[ -n "${content}" ]] && atoms="$(qatom ${content})"
		else
			content="$(awk '{print $1}' ${file} | tr -d "<>=~" | sed -e 's|^#.*||g')"
			[[ -n "${content}" ]] && atoms="$(qatom ${content})"
		fi
		count="$(wc -l <<< "${atoms}")"
		((count--))
		chars="$(wc -m <<< "${count}")"
		check_uses;
		tput el;
		tput cnorm;
		diff_ask "${file}" "${tmp_file}"
		[[ ! -s "${file}" ]] && remove_ask "${file}"
	elif [[ -d "${PORT_ETC}/package.use" ]];then
		for f in `find ${PORT_ETC}/package.use/ -type f \! -name '*~' \! -name '*.bak'`;do
			if [[ -s "${f}" ]];then
				file="${f}"
				tmp_file="$(mktemp)"
				cp "${file}" "${tmp_file}"
				if [[ -n "${IGNORE}" ]];then
					content="$(awk '{print $1}' ${file} | tr -d "<>=~" | sed -e 's|^#.*||g' | grep -v "${IGNORE}")"
					[[ -n "${content}" ]] && atoms="$(qatom ${content})"
				else
					content="$(awk '{print $1}' ${file} | tr -d "<>=~" | sed -e 's|^#.*||g')"
					[[ -n "${content}" ]] && atoms="$(qatom ${content})"
				fi
				count="$(wc -l <<< "${atoms}")"
				((count--))
				chars="$(wc -m <<< "${count}")"
				check_uses;
				tput cnorm
				diff_ask "${file}" "${tmp_file}"
				[[ ! -s "${file}" ]] && remove_ask "${file}"
			else
				echo -e "${underline}Removing empty file${restore} ${contrast}${f}${restore}"
				rm ${f} 2>/dev/null
				eend $? 2>/dev/null
				continue
			fi
		done
	fi
	tput cnorm
	set +f
}
############################################################################
################ incorrect uses in make.conf ###############################
make_conf_use() {
	defined_flags="$(grep "${1}=\".*\"" ${makefile})"
	defined_flags="${defined_flags:-"$(sed -ne "/${1}=\"/,/\"/p" ${makefile})"}"
	echo "${defined_flags}"
}

hell_parser(){
	sed -e 's|[[:space:]]| |g' -e :a -e '/\\$/N; s/\\\n//; ta' | \
	cut -d\" -f2 | tr "[[:space:]]" $'\n' | sed '/^$/d;s|^-||g'  | sort -u
}

invalid_uses_make(){
	set -f
	echo -e "${underline}Checking use flags in${restore} ${contrast}${makefile}${restore}"
	tmp_file="$(mktemp)"
	cp "${makefile}" "${tmp_file}"

	vars_in_USE="$(make_conf_use USE | hell_parser | grep '\$' | tr -d '${}')"
	real_uses="$(eix --print-all-useflags | sed 's|^[-+]||g;s|^(+)||g' | sort -u)"
	for var in ${vars_in_USE} USE;do
		sub_uses="$(make_conf_use ${var} | hell_parser | grep -v '\$')"
		for use in ${sub_uses};do
			if ! grep -q "^${use}$" <<< "${real_uses}" && [[ "${use}" != "*" ]];then
				echo -ne "Invalid use ${contrast} ${var}: ${red}${use}${restore}" | column -t
				invalid_uses+=" ${use}"
			fi
		done
	done

	if [[ -n "${invalid_uses}" ]];then
		for iuse in ${invalid_uses};do
			line="$(grep "\<${iuse}\>" ${tmp_file})"
			fixed_line="$(sed "s|[- \t]${iuse}||" <<< "${line}")"
			sed -e "s|${line%\\}|${fixed_line%\\}|" -i "${tmp_file}"
		done
	fi
	diff_ask "${makefile}" "${tmp_file}"
	set +f
}
############################################################################
################ not_found #################################################
not_found(){
	echo -e "${underline}Checking invalid entries${restore}..."
	TRASH="$(LANG=en eix -Ttc 2>/dev/null)"
	for package in $(ls -d1 ${PORT_ETC}/package* | grep -v -e "~" -e "\.bak" -e "\.old");do
		incorrect="$(echo -e "${TRASH}" | tr $'\n' "%" | sed -e "s|.*${package}:||" -e 's|--.*||' -e 's|No.*||'|\
		tr "%" $'\n' | sed -e '/^$/d' | grep -v "${IGNORE}")"
		if [[ -n "${incorrect}" && -f "${package}" ]];then
			tmp_package="$(mktemp)"
			cp "${package}" "${tmp_package}"
			echo -e "${underline}Removing incorrect from${restore} ${contrast}${package}${restore}:"
			while read line;do
				echo -e "${red}Incorrect:${restore} ${line}"
				line="${line//'*'/\*}"
				[[ -n "${line}" ]] && sed -e "s|$line||" -e 's/[ \t]*$//' -e '/^$/d' -i ${tmp_package} 2>/dev/null
				eend $? 2>/dev/null
			done <<< "${incorrect}"
			diff_ask "${package}" "${tmp_package}"
		elif [[ -n "${incorrect}" && -d "${package}" ]];then
			echo -e "${underline}Removing incorrect from${restore} ${contrast}${package}${restore}:"
			IFS=$'\n'
			for line in ${incorrect};do
				for file in `grep -RH "${line//'*'/\*}" "${package}"/ | awk -F \: '{print $1}'`;do
					tmp_file="$(mktemp)"
					cp "${file}" "${tmp_file}"
					echo -e "${red}Incorrect:${restore} ${line}"
					[[ -n "${line}" ]] && sed -e "s|${line//'*'/\*}||" -e 's/[ \t]*$//' -e '/^$/d' -i ${tmp_file}
					diff_ask "${file}" "${tmp_file}"
					eend $? 2>/dev/null
				done
			done
			unset IFS
		fi
	done

	INVALID="$(LANG=en eix -Ttc 2>&1 | grep "Invalid.*\'.*\'" | grep -v '\.\.\.' | sort -u)"

	IFS=$'\n'
	for string in ${INVALID};do
		[[ -z "${string}" ]] && break
		file="$(awk -F ':' '{print $1}' <<< "${string}")"
		file="${file##* }"
		file="${file//[[:space:]]/}"

		line="$( awk -F ':' '{print $2}' <<< "${string}")"
		line="${line//\'/}"
		echo -e "${red}Incorrect:${restore} ${line}"
		line="${line//'*'/\*}"
		line="${line#[[:space:]]}"
		INVALID_FOUNDED+="${line}"$'\n'

		if [[ -n "${line}" && -f "${file}" ]];then
			tmp_file="$(mktemp)"
			cp "${file}" "${tmp_file}"
			[[ -n "${line}" ]] && sed -e "s|`echo $line`$||" -e 's|[ \t]| |' -e '/^[ \t]$/d' -e '/^$/d' -i ${tmp_file}
			diff_ask "${file}" "${tmp_file}"
		elif [[ -n "${line}" && -d "${file}" ]];then
			for package in `grep -RH "${line//'*'/\*}" "${file}"/ | awk -F \: '{print $1}'`;do
					tmp_package="$(mktemp)"
					cp "${package}" "${tmp_package}"
					echo -e "${red}Incorrect:${restore} ${line}"
					[[ -n "${line}" ]] && sed -e "s|${line//'*'/\*}||" -e 's/[ \t]*$//' -e '/^$/d' -i ${tmp_package}
					diff_ask "${package}" "${tmp_package}"
					eend $? 2>/dev/null
			done
		fi
		eend $? 2>/dev/null
	done
	unset IFS

	##### don't quote it! #####
	if [[ -n "${INVALID_FOUNDED}" ]];then
		invalid=$(emerge --version 2>&1 | sed -e '/--- Invalid atom in /!d' -e 's|--- Invalid atom in ||g;s|:||' |\
			grep -v "${INVALID_FOUNDED}")
	else
		invalid=$(emerge --version 2>&1 | sed -e '/--- Invalid atom in /!d' -e 's|--- Invalid atom in ||g;s|:||')
	fi
	broken_files="$(awk '{print $1}' <<< "${invalid}" | sort -u)"
	invalid_lines(){
		tmp_file="$(mktemp)"
		cp "${file}" "${tmp_file}"
		set -f
		tlines="$(grep "^${file} " <<< "${invalid}" | sed "s|${file} ||g")"
		while read line;do
			sed -e "s|^`printf ${line}`.*$||;s|^${line//\*/\\*}.*$||" -e 's|[ \t]| |;/^[ \t]$/d;/^$/d' -i "${tmp_file}"
		done <<< "${tlines}"
		diff_ask "${file}" "${tmp_file}"
		set +f
	}
	if [[ -n "${invalid}" ]];then
		for bad_file in ${broken_files};do
			file_or_dir "${bad_file#${PORT_ETC}/}" "Founded invalid lines in" "invalid_lines"
		done
	fi
	unset invalid broken_files
}
############################################################################
################ profile's uses in make.conf ###############################
use_makeconf(){
	echo -e "${underline}Checking use flags in${restore} ${contrast}${makefile##/etc*/}${restore}"
	USE="$(echo -e "${MAKE_USES}" | tr "[:space:]" $'\n' | sort -u | sed -e '/^$/d')"

	tmp_file="$(mktemp)"
	cp "${makefile}" "${tmp_file}"
	while read use;do
		flag="${use#-}"
		if [[ -n ${flag} ]];then
			if grep -q "^${flag}$" <<< "${USE}" && grep -q "^${flag}$" <<< "${PROFILE}";then
				echo -e "Twice defined: ${red}${use}${restore}"
				sed -e "s|[^[:punct:]]\<${flag}\>||g" -i ${tmp_file}
			elif grep -q "^\-${flag}$" <<< "${USE}" && grep -q "^\-${flag}$" <<< "${PROFILE}";then
				echo -e "Twice defined: ${red}-${use}${restore}"
				sed -e "s|[^[:punct:]]\-\<${flag}\>||g" -i ${tmp_file}
			fi
		fi
	done <<< "${PROFILE}"
	diff_ask "${makefile}" "${tmp_file}"
	eend $? 2>/dev/null
}
############################################################################
################ empty files ###############################################
empty_files(){
	echo -e "${underline}Looking empty files${restore}"
	for target in `find ${PORT_ETC} -type f`;do
		[[ ! -s "${target}" || -z "$(grep -v "^#" < "${target}")" ]] && remove_ask "${target}"
	done
	eend 0 2>/dev/null
}
############################################################################
################ backup files ##############################################
backup_files(){
	echo -e "${underline}Looking backup files${restore}"
	for target in `find ${PORT_ETC} -type f \( -name "*~" -o  -name "*.bak" -o -name "*.old" \)`;do
		remove_ask "${target}"
	done
	eend 0 2>/dev/null
}
############################################################################
################ package.* files 2 dirs ####################################
f_to_d(){
	while read package;do
		if [[ -f "${package}" ]];then
			echo -e "${underline}Processing${restore}: ${contrast}${package##*/}${restore}"
			tmp_file="$(mktemp)"
			mv ${package} ${tmp_file} 2>/dev/null
			sed -e 's|^#.*||g' -i "${tmp_file}"
			dir="${PORT_ETC}/${package##*/}"
			mkdir "${dir}"
			while read line;do
			set -f
				atom="$(awk '{print $1}' <<< "${line}")"
				category="$(awk '{print $1}' <<< `qatom ${atom}`)"
				if [[ "${category}" != "(null)" ]];then
					category="$(tr -d "<>=~" <<< "${category}" )"
					[[ "${category}" == "*" ]] && category="all_categories"
					echo "${line}" >> "${dir}/${category}"
				fi
			done < "${tmp_file}"
			set +f
			eend $? 2>/dev/null
			rm "${tmp_file}" 2>/dev/null
		elif [[ -d "${package}" ]];then
			echo -e "${underline}Skipping ${red}directory${restore}: ${contrast}${package##*/}${restore}"
			eend $? 2>/dev/null
		fi
	done <<< "`ls -d1 ${PORT_ETC}/package* | grep -v "~"`"
}
############################################################################
################ package.* dirs 2 files ####################################
d_to_f(){
	while read package;do
		if [[ -d "${package}" ]];then
			echo -e "${underline}Processing${restore}: ${contrast}${package##*/}${restore}"
			tmp_file="$(mktemp)"
			file="${PORT_ETC}/${package##*/}"
			touch "${file}"
			for subfile in `find "${package}" -type f \! -name '*~' \! -name '*.bak' | sort`;do
				while read line;do
					echo "${line}" >> "${tmp_file}"
				done < "${subfile}"
			done
			rm -rf "${package}" 2>/dev/null
			mv "${tmp_file}" "${package}" 2>/dev/null
			chmod 0644 "${package}"
			eend $? 2>/dev/null
			rm "${tmp_file}" 2>/dev/null
		elif [[ -f "${package}" ]];then
			echo -e "${underline}Skipping ${red}file${restore}: ${contrast}${package##*/}${restore}"
			eend $? 2>/dev/null
		fi
	done <<< "`ls -d1 ${PORT_ETC}/package* | grep -v "~"`"
}
############################################################################
################ version diff ##############################################
ver_diff(){
	check="$(versionsort ${1} ${2} 2>/dev/null | tail -n1)"
	[[ "${check}" == "${1}" && "${check}" != "${2}" ]] && echo 1 # ${1} > ${2}
	[[ "${check}" == "${2}" && "${check}" != "${1}" ]] && echo 2 # ${2} > ${1}
	[[ "${check}" == "${1}" && "${check}" == "${2}" ]] && echo 0 # ${1} = ${2}
}
############################################################################
################ version between ###########################################
ver_btwn(){
	for between in ${3};do
		if [[ "$(ver_diff "${1}" "${between}")" == "1" && "$(ver_diff "${2}" "${between}")" == "2" ]];then
			echo "1" # we have one_or_more version between ${1} and ${2}
			break
		fi
	done
}
############################################################################
package_envs(){
	for atom in ${1};do
		while read category pn ver rev slot;do
			sw="$(grep -o "[<>=~]" <<< "${category}" | tr -d $'\n')"
			category="${category##${sw}}"
			[[ "${category}" == "(null)" || "${pn}" == "(null)" ]] && continue
			if [[ -n "${rev}" && -z "${slot}" ]] && grep -q \: <<< "${rev}";then
				slot="${rev}"
				unset rev
			fi
			slot="${slot#:}"
			pn="${pn%:}"
			echo "${sw} ${category} ${pn} ${ver} ${rev:-(null)} ${slot:-(null)} ${file}"
		done <<< `qatom "${atom}"`
	done
}
############################################################################
################ mask/unmask trash #########################################
all_mask_trash(){
	pre_mask_trash(){
		masked="$(awk '{print $1}' ${file} | grep -v '^#.*')"
		MASKED+="$(package_envs "${masked}")"$'\n'
	}
	file_or_dir "package.mask" "Preparing atoms in" "pre_mask_trash" || return 1
	pre_unmask_trash(){
		unmasked="$(awk '{print $1}' ${file} | grep -v '^#.*')"
		UNMASKED+="$(package_envs "${unmasked}")"$'\n'
	}
	file_or_dir "package.unmask" "Preparing atoms in" "pre_unmask_trash" || return 1
}
mask_trash(){
	slot_output(){
		if [[ "${mslot}" != "(null)" ]];then
			echo -e "${red}Incorrect${restore}: ${mcategory}/${mpn}:${mslot}"
		else
			echo -e "${red}Incorrect${restore}: ${mcategory}/${mpn}"
		fi
		TRASH+="${mfile} ${mcategory}/${mpn}"$'\n'
		unset msw mcategory mpn mver mrev mslot mfile usw ucategory upn uver urev uslot ufile
		continue
	}
	non_slot_output(){
		echo -e "${red}Incorrect${restore}: ${msw}${mcategory}/${mpn}-${mver}"
		TRASH+="${mfile} ${msw}${mcategory}/${mpn}-${mver}"$'\n'
		unset msw mcategory mpn mver mrev mslot mfile usw ucategory upn uver urev uslot ufile
		continue
	}
	all_mask_trash || return 1
	###### m->masked; u->unmasked
	while read msw mcategory mpn mver mrev mslot mfile;do
		while read usw ucategory upn uver urev uslot ufile;do
			[[ "${mrev}" == "(null)" ]] && unset mrev || mver="${mver}-${mrev}"
			[[ "${urev}" == "(null)" ]] && unset urev || uver="${uver}-${urev}"
			[[ "${mver}" == "(null)" ]] && unset mver
			[[ "${uver}" == "(null)" ]] && unset uver

			if [[ -n "${mver}" || -n "${uver}" ]];then
				export OVERLAYS_LIST="no"
				export VERSIONONLY='<version> '
				export FORMAT='<availableversions:VERSIONONLY>'
				versions="$(eix -e "${mcategory}/${mpn}")"
				oldest="$(awk '{print $1}' <<< "${versions}")"
			fi

			if [[ -n "${mver}" && -n "${uver}" ]];then
				versions_diff="$(ver_diff "${mver}" "${uver}")"
				versions_btwn="$(ver_btwn "${uver}" "${mver}" "${versions}")"
			fi

			if [[ "${msw}" != "(null)" ]];then
				if [[ "${usw}" == "(null)" && "${uslot}" == "(null)" ]];then
					non_slot_output
				elif [[ "${msw}" == ">" || "${msw}" == ">=" ]];then
					if [[ "${usw}" == ">" || "${usw}" == ">=" ]];then
						if [[ "${versions_diff}" != "1" && -z "${versions_btwn}" ]];then
							non_slot_output
						fi
					fi
				elif [[ "${msw}" == "<" || "${msw}" == "<=" ]];then
					if [[ "${usw}" == "<" || "${usw}" == "<=" ]];then
						if [[ "${versions_diff}" != "1" ]];then
							non_slot_output
						fi
					fi
				fi
			else
				if [[ "${mslot}" == "${uslot}" ]];then
					if [[ "${usw}" == ">=" || "${usw}" == ">" ]];then
						if [[ "$(ver_diff "${uver}" "${oldest}")" != "1" ]];then
							slot_output
						fi
					elif [[ "${usw}" == "<"  && "$(ver_diff "${uver}" "${oldest}")" == "1" ]];then
						slot_output
					elif [[ "${usw}" == "<=" && "$(ver_diff "${uver}" "${oldest}")" != "1" ]];then
						slot_output
					elif [[ "${usw}" == "(null)" ]];then
						slot_output
					fi
				fi
			fi
		done <<< "$(grep " ${mcategory} ${mpn} " <<< "${UNMASKED}")"
	done <<< "${MASKED}"

	files="$(awk '{print $1}' <<< "${TRASH}" | sort -u | sed '/^$/d')"
	for target in ${files};do
		if [[ -f "${target}" ]];then
			tmp_file="$(mktemp)"
			cp "${target}" "${tmp_file}"
			incorrect="$(grep ${target} <<< "${TRASH}" | sed -e "s|${target} ||g")"
			for trash_atom in ${incorrect};do
				sed -e "s|^${trash_atom}.*||" -e '/^$/d' -e 's/[ \t]*$//' -i "${tmp_file}"
			done
			diff_ask "${target}" "${tmp_file}"
		fi
	done
	unset TRASH OVERLAYS_LIST VERSIONONLY FORMAT MASKED UNMASKED versions oldest versions_diff versions_btwn
}
############################################################################
################ looking trash #############################################
remove_trash(){
	tmp_file="$(mktemp)"
	cp "${file}" "${tmp_file}"
	for atom in `eix -Tc#`;do
		lines="$(grep "${atom}" "${file}")"
		while read line;do
			entry="$(qatom "$(tr -d '<>=~#' <<< "${line}")" | awk '{print $1,$2}' | tr ' ' '/')"
			if [[ "${atom}" == "${entry}" ]];then
				if ! eix -qe --installed-masked "${entry}";then
					if `eix -Iqe ${atom}`;then
						echo -e "stupid entry:              ${green}${line}${restore}"
					else
						echo -e "stupid entry (${red}!${restore}installed): ${green}${line}${restore}"
					fi
					sed -e "s|${line}||" -e '/^$/d' -i "${tmp_file}"
					break
				fi
			fi
		done <<< "${lines}"
	done
	diff_ask "${file}" "${tmp_file}"
	eend $? 2>/dev/null
}
############################################################################
################ stupid unmask #############################################
stupid_unmask(){
	export REDUNDANT_IF_IN_UNMASK="all"
	export REDUNDANT_IF_IN_MASK="no"
	export TEST_FOR_NONEXISTENT="true"
	export REDUNDANT_IF_UNMASK_NO_CHANGE="all"
	file_or_dir "package.unmask" "Checking stupid unmasks:" "remove_trash" || return 1
	unset REDUNDANT_IF_IN_UNMASK REDUNDANT_IF_IN_MASK TEST_FOR_NONEXISTENT REDUNDANT_IF_UNMASK_NO_CHANGE
}
############################################################################
################ stupid mask/unmask uses ###################################
sort_uniq_mask_use(){
	if [[ -d "${PORT_ETC}/profile" || -h "${PORT_ETC}/profile" ]];then
		for package in `find ${PORT_ETC}/profile -type f \! -name '*~' \! -name '*.bak' -name "use.stable.mask" -or -name "use.mask"`;do
			tmp_sort="$(mktemp)"
			echo -e "${underline}Sorting${restore} ${contrast}${package#${PORT_ETC}/}${restore}"

			masked_uses="$(grep -v "^#" "${package}")"

			sort_passed_uses "${masked_uses}" | tr "[:space:]" $'\n' > ${tmp_sort}

			diff_ask "${package}" "${tmp_sort}"
			eend $? 2>/dev/null
		done
	fi
}

profile_masked_uses() {
	file="${1}/${2}"
	if [[ -f "${file}" ]];then
		all_uses+="$(grep "^[^#].*$" "${file}")"$'\n'
	fi
	if [[ -f "${1}/parent" ]]; then
		for path in $(cat ${1}/parent);do
			profile_masked_uses "${1}/${path}" "${2}"
		done
	fi
}

mask_files() {
	if grep -q "~" <<< "$(eix --print ACCEPT_KEYWORDS)";then
		echo "use.mask"
	else
		echo "use.mask use.stable.mask"
	fi
}

use_mask() {
	[[ -h "/etc/make.profile" ]] && makeprof="/etc/make.profile"
	[[ -h "/etc/portage/make.profile" ]] && makeprof="/etc/portage/make.profile"
	for target in $(mask_files);do
		profile_masked_uses "$(readlink -f ${makeprof})" "${target}"
	done
	sort_passed_uses "${all_uses} " | tr "[:space:]" $'\n'
}

etc_profile_use_mask() {
	if [[ -f "${PORT_ETC}/profile/use.mask" ]];then
		orig_file="${PORT_ETC}/profile/use.mask"
	else
		return 1
	fi
	tmp_file="$(mktemp)"
	cp "${orig_file}" "${tmp_file}"
	while read use;do
		if grep -q "^${use/-/\-}$" <<< "$(use_mask)";then
			if grep -q "^-" <<< "${use}";then
				echo -e "Twice unmasked: ${red}${use}${restore}"
				sed -e "s|^${use}.*||" -e '/^$/d' -e 's/[ \t]*$//' -i "${tmp_file}"
			else
				echo -e "Twice masked: ${red}${use}${restore}"
				sed -e "s|^${use}.*||" -e '/^$/d' -e 's/[ \t]*$//' -i "${tmp_file}"
			fi
		else
			if grep -q "^-" <<< "${use}";then
				echo -e "Stupid unmask: ${red}${use}${restore}"
				sed -e "s|^${use}.*||" -e '/^$/d' -e 's/[ \t]*$//' -i "${tmp_file}"
			fi
		fi
	done < "${orig_file}"
	diff_ask "${orig_file}" "${tmp_file}"
}

check_use_masked() {
	for target in $(mask_files);do
		file_or_dir "profile/${target}" "Checking masked uses:" "etc_profile_use_mask" || return 1
	done
}
############################################################################
################ regen_world ###############################################
regen_world(){
	tmp_world="$(mktemp)"
	ex_world="$(mktemp)"
	emerge_log="$(mktemp)"
	mv "${WORLD}" "${ex_world}"
	installed="$(qlist -CI | sort -u)"
	echo "${installed}" > "${WORLD}"
	echo -e "Calculating dependencies"

	pre_pre="$(emerge -eopd --columns --with-bdeps=y world 2>"${emerge_log}" || exit 1)"

	if [[ $? == 1 ]];then
		mv "${ex_world}" "${WORLD}"
		cat "${emerge_log}"
		rm "${tmp_world}" "${emerge_log}"
		echo -e "\n${red}ERROR!!!${restore} exit\n"
		exit 1
	else
		rm "${emerge_log}"
	fi

	pretend="$(grep -v "blocks" <<< "${pre_pre}" | awk '/^\[/ {print $4}')" && eend 0 2>/dev/null
	pretend+="$(qlist -CI `emerge -epO system | awk '/\[/ {print $4}'`)"$'\n'

	for atom in ${installed};do
		if ! grep -q "^${atom}$" <<< "${pretend}" && ! grep -q ".*-libs/" <<< "${atom}" && ! grep -q "virtual/" <<< "${atom}";then
				echo "${atom}" >> "${tmp_world}"
				echo -e "world++: ${green}${atom}${restore}"
		fi
	done
	cp "${tmp_world}" "${WORLD}"

	PS3=`echo -e "${contrast}Choose package which you want save:${restore} "`
	choose_target(){
		select target in ${pretend};do
			echo "=${target}"
			break
		done
	}
	add_in_world(){
		notrash_pkgs+=" $(choose_target)"
		for tp in ${notrash_pkgs};do
			pretend="$(sed -e "s|^${tp#=}$||" -e '/^$/d' <<< "${pretend}")"
		done
	}
	ask(){
		pretend="$(emerge -pc | grep 'All selected packages:' | sed 's|.*:||1' | tr ' ' $'\n')"
		echo -e "\n${pretend// /$'\n'}"
		if [[ -n "$(sed '/^$/d' <<< "${pretend}")" ]];then
			echo -ne "\n${contrast}Would you like save some packages?${restore} [${green}Yes${restore}/${red}No${restore}] "
			while read x;do
				[[ -z "$(sed '/^$/d' <<< "${pretend}")" ]] && break
				case ${x} in
					Yes | YES | yes | Y | y | "" )
						add_in_world;
						while [[ -z "${enough}" && "$(echo "${pretend// /$'\n'}" | sed '/^$/d' | wc -l)" != "0" ]];do
							echo -ne "${contrast}More?${restore} [${green}Yes${restore}/${red}No${restore}] "
							while read y;do
								case ${y} in
									Yes | YES | yes | Y | y | "" )
										add_in_world;
										break;;
									No | NO | no | N | n )
										enough="1"
										break;;
									* ) echo -ne "Sorry, response '${y}' not understood. [${green}Yes${restore}/${red}No${restore}] "
										continue;;
								esac
							done
						done
						break;;
					No | NO | no | N | n )
						break;;
					* ) echo -ne "Sorry, response '${x}' not understood. [${green}Yes${restore}/${red}No${restore}] "
						continue;;
				esac
			done
			[[ -n "$(sed '/^$/d' <<< "${notrash_pkgs}")" ]] && emerge -Own ${notrash_pkgs}
		else
			return 0
		fi
	}
	for t in 1 2;do
		[[ "${t}" == "1" ]] && echo -e "\nemerge -pc: ${green}check...${restore}"
		[[ "${t}" == "2" ]] && echo -e "\nemerge -pc: ${green}recheck...${restore}"
		ask
		unset enough
	done
	cp "${WORLD}" "${tmp_world}"
	cp "${ex_world}" "${WORLD}"
	diff_ask "${WORLD}" "${tmp_world}"
	rm "${ex_world}"
	eend $? 2>/dev/null
	echo -e "\n${green}Result${restore}:"
	cat "${WORLD}"
}
############################################################################
################ unused repo and dep-cache #################################
overlays(){
	########## repo over layman
	layman_path="$(awk '/storage[[:space:]].*:/ {print $3}' /etc/layman/layman.cfg)"
	source "${layman_path}/make.conf" 2>/dev/null
	layman_pkgdir="$(tr '[[:space:]]' $'\n' <<< "${PORTDIR_OVERLAY}" | sed '/^$/d')"
	for repo_dir in ${layman_pkgdir};do
		[[ -f "${repo_dir}/profiles/repo_name" ]] && repo_name="$(cat "${repo_dir}/profiles/repo_name")"
		repo_name="${repo_name:-${repo_dir##*/}}"
		layman_overlays+="${repo_dir} ${repo_name}"$'\n'
	done

	all_overlays="${layman_overlays}"

	######### repo over PORTDIR_OVERLAY ----> used by portage
	local PORTDIR_OVERLAY="$(eix --print PORTDIR_OVERLAY)"
	portage_pkdir="${PORTDIR_OVERLAY}"
	unset PORTDIR_OVERLAY
	for repo_dir in ${portage_pkdir};do
		[[ -f "${repo_dir}/profiles/repo_name" ]] && repo_name="$(cat "${repo_dir}/profiles/repo_name")"
		repo_name="${repo_name:-${repo_dir##*/}}"
		portage_overlays+="${repo_dir} ${repo_name}"$'\n'
	done
	all_overlays+="${portage_overlays}"
	all_overlays="$(sort -u <<< "${all_overlays}" | sed '/^$/d')"

	######## parent_repo for installed packages
	echo "Checking installed packages..."
	tput sc
	tput civis
	for i in ${PKGDB}/*/*/repository;do
		tput el
		tput el1
		output="${i#${PKGDB}/}"
		output="${output%/repository}"
		echo -n "${output}"
		tput rc
		used_repos+="$(grep -sv '^gentoo$' "${i}")"$'\n'
	done
	tput el
	tput cnorm
	used_repos="$(sort -u <<< "${used_repos%$'\n'}")"

	for repo in ${used_repos};do
		repo_path="$(grep " ${repo}$" <<< "${portage_overlays}" | awk '{print $1}')"
		if [[ -d "${repo_path}" ]];then
			######## checking symlinks in repo
			for x in `find "${repo_path}" -type l`;do
				target="$(readlink ${x})"
				if [[ -e "${target}" || -e "${x%/*}/${target}" ]];then
					good_links+="${target}"$'\n'
				else
					bad_links+="${repo} ${x}"$'\n'
				fi
			done
		else
			TRASH_REPO+="repo '${green}${repo}${restore}' used, but not exists in \${PORTDIR_OVERLAY}"$'\n'
			continue
		fi
	done

	####### checking layman_overlays: used by links or not
	while read path name;do
		if grep -q "^${path}" <<< "${good_links%$'\n'}";then
			link_used+="${path} ${name}"$'\n'
		else
			link_unused+="${path} ${name}"$'\n'
		fi
	done <<< "${layman_overlays%$'\n'}"

	####### looking unused layman repo: by portage, by symlinks
	while read path name;do
		if ! grep -q " ${name}$" <<< "${link_used}" && ! grep -q "^${name}$" <<< "${used_repos}";then
			grep -q " ${name}$" <<< "${layman_overlays}" && UNUSED+="${name}"$'\n'
		fi
	done <<< "${all_overlays%$'\n'}"
	UNUSED="$(sort -u <<< "${UNUSED}")"

	if [[ -n "${bad_links}" ]];then
		echo "broken symlinks:"
		echo "${bad_links}"
		echo -ne "\n${contrast}Would you like remove?${restore} [${green}Yes${restore}/${red}No${restore}] "
		while read z;do
			case ${z} in
				Yes | YES | yes | Y | y | "" )
					for symlink in $(awk '{print $2}' <<< "${bad_links%$'\n'}");do
						rm -v "${symlink}"
						eend $? 2>/dev/null
					done
					break;;
				No | NO | no | N | n )
					break;;
				* ) echo -ne "Sorry, response '${z}' not understood. [${green}Yes${restore}/${red}No${restore}] "
					continue;;
			esac
		done
	fi

	choose_target(){
		PS3=`echo -e "${contrast}Choose repo which you want save:${restore} "`
		select target in ${UNUSED};do
			echo "${target}"
			break
		done
	}
	ask(){
		[[ -n "${UNUSED}" ]] && echo -e "Unused repos:\n${UNUSED}"
		if [[ -n "$(sed '/^$/d' <<< "${UNUSED}")" ]];then
			echo -ne "\n${contrast}Would you like save some repo(s)?${restore} [${green}Yes${restore}/${red}No${restore}] "
			while read x;do
				[[ -z "$(sed '/^$/d' <<< "${UNUSED}")" ]] && break
				case ${x} in
					Yes | YES | yes | Y | y | "" )
						UNUSED="$(grep -v "^$(choose_target)$" <<< "${UNUSED}")"
						while [[ -z "${enough}" && "$(echo "${UNUSED// /$'\n'}" | sed '/^$/d' | wc -l)" != "0" ]];do
							echo -ne "${contrast}More?${restore} [${green}Yes${restore}/${red}No${restore}] "
							while read y;do
								case ${y} in
									Yes | YES | yes | Y | y | "" )
										UNUSED="$(grep -v "^$(choose_target)$" <<< "${UNUSED}")"
										break;;
									No | NO | no | N | n )
										enough="1"
										break;;
									* ) echo -ne "Sorry, response '${y}' not understood. [${green}Yes${restore}/${red}No${restore}] "
										continue;;
								esac
							done
						done
						break;;
					No | NO | no | N | n )
						break;;
					* ) echo -ne "Sorry, response '${x}' not understood. [${green}Yes${restore}/${red}No${restore}] "
						continue;;
				esac
			done
		else
			return 0
		fi
	}
	fix_deps(){
		DEP_PATH="/var/cache/edb/dep"
		unset TRASH
		for dep_path in `find ${DEP_PATH} -type d`;do
			repo_path="$(sed "s|${DEP_PATH}||" <<< "${dep_path}")"
			dep_file="${dep_path}.sqlite"
			if [[ -n "${repo_path}" ]];then
				if [[ ! -d "${repo_path}" ]];then
					TRASH+="${dep_path} "
					[[ -f "${dep_file}" ]] && TRASH+="${dep_file} "
				elif [[ -d "${repo_path}" && ! "$(ls -A ${repo_path})" ]];then
					TRASH+="${dep_path} "
					[[ -f "${dep_file}" ]] && TRASH+="${dep_file} "
				elif [[ -d "${repo_path}" && ! "$(ls -A ${dep_path})" && ! -f "${dep_file}" ]];then
					TRASH+="${dep_path} "
				elif [[ -d "${repo_path}" && "$(ls -A ${dep_path})" && -f "${dep_file}" ]];then
					file_stamp="$(timestamp "${dep_file}")"
					path_stamp="$(timestamp ${dep_path}/*)"
					if [[ -n "${file_stamp}" && -n "${path_stamp}" ]] && (( "${file_stamp}" > "${path_stamp}" ));then
						TRASH+="${dep_path}/* "
					elif [[ -n "${file_stamp}" && -n "${path_stamp}" ]] && (( "${file_stamp}" < "${path_stamp}" ));then
						TRASH+="${dep_file} "
					fi
				fi
			fi
		done
		if [[ -n "${TRASH}" ]];then
			echo "${TRASH}"
		else
			stop="true"
		fi
	}
	ask
	for repo in ${UNUSED};do
		layman -d "${repo}"
	done
	echo -e "\n${TRASH_REPO}"
	echo "dep-cache:"
	while [[ -z "${stop}" ]];do
		trash="$(fix_deps)"
		if [[ -n "${trash}" ]];then
			echo -e "$(tr ' ' $'\n' <<< "${trash% }" | sed "s|^|removing:\\${green}|;s|$|\\${restore}|")"
			rm -rf ${trash} 2>/dev/null || echo failed && exit 1
		else
			break
			
		fi
	done
	echo "done"
	eend 0 2>/dev/null
}
############################################################################
################ help ######################################################
help_pc(){
echo -e \
"Usage: portconf [OPTION] [OPTION]…[OPTION]
available OPTIONS:

${contrast}Common${restore}
	-rc, --regen-cache:          Create and use temporary eix-cache and some fix for overlays. ${red}Highly recommend!${restore}
	-b,  --backup:               Create backup for current /etc/portage state.
	-r,  --restore:              Rolling up /etc/portage to one of available states.
	-s,  --sort:                 Sort entries alphabetically, --use-sort, --keyword-uniq.
	-y,  --yes:                  Auto answer (Yes).
	-p,  --pretend:              Check only.
	-h,  -h, -?, h, --help:      This help.
${contrast}\${USE}${restore}
	-us, --use-sort:             Sort useflags. Remove doubles and preserve only last defined state (on/off).
	-ui, --use-invalid:          Delete invalid or twice global-defined useflags.
	-um, --use-make:             Delete profile defined useflags from make.conf.
	-sup,--stupid-use-profile:   Delete incorrect or twice masked/unmasked useflags.
	-uf, --use-full:             An analog '-us -ui -um -sup'.
${contrast}\${KEYWORDS}${restore}:
	-ku, --keyword-uniq:         Like '-us', but for keywords.
	-ko, --keyword-one:          Save only latest defined keyword.
${contrast}Trash${restore}:
	-t,   --trash:               Delete not_founded/not_installed entries, empty/backup/unused files.
	-ft,  --force-trash:         Delete all not_installed entries.(exclude package.mask file/dir)
	-sm,  --stupid-mask:         Remove incorrect masked atoms.
	-sum, --stupid-unmask:       Remove incorrect unmasked atoms.
	-c,   --rm-comments:         Delete lines starting with comment.
	-ac,  --rm-all-comments:     Delete all comments.
	-f,   --full:                An analog '-s -t -uf -ku -sm -sum'
${contrast}Converting${restore}:
	-f2d, --files-2-dirs:        Converting package.* files to directories(comments will be removed).
	-d2f, --dirs-2-files:        Converting package.* dirs to files.
${contrast}Profile${restore}:
	-apu, --all-profiles-use:    List \${USE} defined in profiles.
	-pu,  --profiles-use:        List \${USE} of profile.
	-cpu, --current-profile-use: \${USE} of current profile.
${contrast}World${restore}:
	-wb, --world-backup:         Create backup for current world file state.
	-wr, --world-restore:        Rolling up world file to one of available states.
	-wg, --world-regen:          Regen(cleanup) the world file.(backup: auto)
${contrast}Overlays${restore}:
	-fr, --fix-repos:            Remove unused overlays and dep-cache.

OPTIONS must be separated by SPACE."
}
############################################################################
################ run_it ####################################################
eix_dep_keys="--use-invalid
-ui
--use-make
-um
--use-full
-uf
--trash
-t
--force-trash
-ft
--full
-f"
opts=" ${PORTCONF_DEFAULT_OPTS} ${@}"
grep -q -e " \--yes\>" -e " \-y\>" <<< " ${opts}" && yes="1"
grep -q -e " \--pretend\>" -e " \-p\>" <<< " ${opts}" && PRETEND="1"
opts="$(sed -e 's| --yes\>||g;s| -y\>||g' -e 's| --pretend\>||g;s| -p\>||g' <<< " ${opts}")"
if grep -q "${eix_dep_keys//\-/\\-}" <<< "${opts}";then
	if grep -q -e " \--regen-cache\>" -e " \-rc\>" <<< " ${opts}";then
		eix_check
		opts="$(sed -e 's| --regen-cache\>||g;s| -rc\>||g' -e '/^[ \t]$/d' <<< " ${opts}")"
	else
		eix_method
	fi
else
	opts="$(sed -e 's| --regen-cache\>||g;s| -rc\>||g' -e '/^[ \t]$/d' <<< " ${opts}")"
fi
[[ -z "${@}" || -z "${opts}" ]] && help_pc
for OPT in ${opts};do
	case "${OPT}" in
	--backup | -b ) backup;;
	--restore | -r ) etc_restore;;
	--sort | -s )
		backup;
		sort_use_file;
		uniq_keywords;
		sort_uniq_files;
		sort_uniq_mask_use;;
	--use-sort | -us )
		backup;
		sort_use_file;;
	--use-invalid | -ui )
		backup;
		invalid_uses;
		invalid_uses_make;
		[[ -n "${eix_cache}" ]] && rm "${eix_cache}" && unset eix_cache EIX_CACHEFILE;;
	--use-make | -um )
		backup;
		use_makeconf;;
	--stupid-use-profile | -sup )
		backup;
		sort_uniq_mask_use;
		check_use_masked;;
	--use-full | -uf )
		backup;
		sort_use_file;
		sort_uniq_mask_use;
		invalid_uses;
		invalid_uses_make;
		use_makeconf;
		check_use_masked;
		[[ -n "${eix_cache}" ]] && rm "${eix_cache}" && unset eix_cache EIX_CACHEFILE;;
	--keyword-one | -ko )
		backup;
		sort_keywords;;
	--keyword-uniq | -ku )
		backup;
		uniq_keywords;;
	--trash | -t )
		backup;
		not_found;
		package_env_conf;
		package_env;
		env_not_installed;
		empty_files;
		backup_files;
		[[ -n "${eix_cache}" ]] && rm "${eix_cache}" && unset eix_cache EIX_CACHEFILE;;
	--stupid-mask | -sm )
		backup;
		mask_trash;;
	--stupid-unmask | -sum )
		backup;
		stupid_unmask;;
	--force-trash | -ft )
		backup;
		not_found;
		package_env_conf;
		package_env;
		env_not_installed;
		force_not_installed;
		empty_files;
		backup_files;
		[[ -n "${eix_cache}" ]] && rm "${eix_cache}" && unset eix_cache EIX_CACHEFILE;;
	--rm-comments | -c )
		backup;
		rm_comments;;
	--rm-all-comments | -ac )
		backup;
		rm_all_comments;;
	--full | -f )
		backup;
		sort_uniq_files;
		not_found;
		package_env_conf;
		package_env;
		env_not_installed;
		sort_use_file;
		sort_uniq_mask_use;
		invalid_uses;
		invalid_uses_make;
		use_makeconf;
		check_use_masked;
		uniq_keywords;
		mask_trash;
		stupid_unmask;
		empty_files;
		backup_files;
		[[ -n "${eix_cache}" ]] && rm "${eix_cache}" && unset eix_cache EIX_CACHEFILE;;
	--files-2-dirs | -f2d )
		backup;
		f_to_d;;
	--dirs-2-files | -d2f )
		backup;
		d_to_f;;
	--all-profiles-use | -apu ) all_use_all_profiles;;
	--profiles-use | -pu ) profile_use;;
	--current-profile-use | -cpu ) current_profile;;
	--world-backup | -wb ) world_backup;;
	--world-restore | -wr ) world_restore;;
	--world-regen | -wg )
		world_backup;
		regen_world;;
	--fix-repos | -fr )
		overlays;;
	--help | -h | -? | h ) help_pc;;
	esac
done