diff --git a/TODO b/TODO
index f753199cd21ee70fe594be34cc7127c7da014d77..32329a49b6eefb44c857deedd63e2e401acc38c6 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,9 @@
+TODO: yaourt (pacman frontend), need we?
+https://archlinux.fr/man/yaourt.8.html
+
 /etc/eepm.conf конфиг
 
-FIXME: epm-install need realpath, missed on some systems
+implement distr_info as inside tool and do access via epm command
 
 [18:21:12] <danil> Вот так можно:
 RED='\033[0;31m' ; NC='\033[0m' b="b" ; echo -e "aba" | sed -e "s|${b}|\\${RED}${b}\\${NC}|g" | xargs -0 printf
diff --git a/bin/distr_info b/bin/distr_info
index fbe29174ea28cc96ef8d57addd390cf937880e01..e0d173d3d9229451f674b016e41f8ad5487488bd 100755
--- a/bin/distr_info
+++ b/bin/distr_info
@@ -61,7 +61,7 @@ pkgtype()
 		debian|ubuntu|mint|runtu|mcst|astra) echo "deb" ;;
 		alt|asplinux|suse|mandriva|rosa|mandrake|pclinux|sled|sles)
 			echo "rpm" ;;
-		fedora|redhat|scientific|centos|rhel)
+		fedora|redhat|scientific|centos|rhel|goslinux)
 			echo "rpm" ;;
 		*)  echo "rpm" ;;
 	esac
@@ -69,8 +69,8 @@ pkgtype()
 
 get_var()
 {
-	grep -i "^$1 *=" | head -n 1 | sed -e "s/^[^=]*[ \t]*=[ \t]*//"
-
+	# get first variable and print it out, drop quotes if exists
+	grep -i "^$1 *=" | head -n 1 | sed -e "s/^[^=]*[ \t]*=[ \t]*//" | sed -e "s/^[\'\"]\(.*\)[\'\"]/\1/"
 }
 
 # 2010.1 -> 2010
@@ -97,6 +97,7 @@ if distro altlinux-release ; then
 	if has Sisyphus ; then DISTRIB_RELEASE="Sisyphus"
 	elif has "ALT Linux 7." ; then DISTRIB_RELEASE="p7"
 	elif has "ALT Linux 8." ; then DISTRIB_RELEASE="p8"
+	elif has "ALT .*8.[0-9]" ; then DISTRIB_RELEASE="p8"
 	elif has "Simply Linux 6." ; then DISTRIB_RELEASE="p6"
 	elif has "Simply Linux 7." ; then DISTRIB_RELEASE="p7"
 	elif has "Simply Linux 8." ; then DISTRIB_RELEASE="p8"
@@ -241,6 +242,8 @@ elif distro redhat-release ; then
 		DISTRIB_ID="CentOS"
 	elif has Scientific ; then
 		DISTRIB_ID="Scientific"
+	elif has GosLinux ; then
+		DISTRIB_ID="GosLinux"
 	fi
 	if has Beryllium ; then
 		DISTRIB_ID="Scientific"
@@ -298,7 +301,13 @@ elif [ `uname -o 2>/dev/null` = "Cygwin" ] ; then
 # try use standart LSB info by default
 elif distro lsb-release && [ -n "$DISTRIB_RELEASE" ]; then
 	# use LSB
-	true
+
+	# fix distro name
+	case "$DISTRIB_ID" in
+		"openSUSE Tumbleweed")
+			DISTRIB_ID="Tumbleweed"
+			;;
+	esac
 fi
 
 case $1 in
@@ -340,7 +349,7 @@ case $1 in
 		exit 0
 		;;
 	-V)
-		echo "20160822"
+		echo "20161212"
 		exit 0
 		;;
 	*)
diff --git a/bin/epm b/bin/epm
index 6b1d0930e5a63b67e31cf5839b5b2d4856514d82..df1451483d0cbcbe601dac6961023431ecee9c8d 100755
--- a/bin/epm
+++ b/bin/epm
@@ -65,7 +65,7 @@ print_version()
 {
         echo "EPM package manager version @VERSION@"
         echo "Running on $($DISTRVENDOR) ('$PMTYPE' package manager uses '$PKGFORMAT' package format)"
-        echo "Copyright (c) Etersoft 2012-2016"
+        echo "Copyright (c) Etersoft 2012-2017"
         echo "This program may be freely redistributed under the terms of the GNU AGPLv3."
 }
 
@@ -80,6 +80,7 @@ nodeps=
 noremove=
 force=
 short=
+direct=
 sort=
 non_interactive=
 skip_installed=
@@ -157,7 +158,7 @@ check_command()
     -i|install|add|i)         # HELPCMD: install package(s) from remote repositories or from local file
         epm_cmd=install
         ;;
-    -e|-P|remove|delete|uninstall|erase|e)  # HELPCMD: remove (delete) package(s) from the database and the system
+    -e|-P|rm|del|remove|delete|uninstall|erase|e)  # HELPCMD: remove (delete) package(s) from the database and the system
         epm_cmd=remove
         ;;
     -s|search|s)                # HELPCMD: search in remote package repositories
@@ -189,7 +190,7 @@ check_command()
     check|fix|verify)         # HELPCMD: check local package base integrity and fix it
         epm_cmd=check
         ;;
-    changelog|cl|-cl)         # HELPCMD: show changelog for package
+    -cl|cl|changelog)         # HELPCMD: show changelog for package
         epm_cmd=changelog
         ;;
     -qi|qi|info|show)         # HELPCMD: print package detail info
@@ -210,13 +211,13 @@ check_command()
     conflicts)                # HELPCMD: print package conflicts
         epm_cmd=conflicts
         ;;
-    -qa|list|packages|-l|qa)  # HELPCMD: print list of installed package(s)
+    -qa|qa|-l|list|packages)  # HELPCMD: print list of installed package(s)
         epm_cmd=packages
         ;;
-    programs)                 # HELPCMD: print list of installed GUI program(s)
+    programs)                 # HELPCMD: print list of installed GUI program(s) (they have .desktop files)
         epm_cmd=programs
         ;;
-    assure)                   # HELPCMD: <command> [package]: install package if command does not exists
+    assure)                   # HELPCMD: <command> [package]: install package if command does not exist
         epm_cmd=assure
         ;;
     policy)                   # HELPCMD: print detailed information about the priority selection of package
@@ -283,7 +284,7 @@ check_command()
     site|url)                 # HELPCMD: open package's site in a browser (use -p for open packages.altlinux.org site)
         epm_cmd=site
         ;;
-    ei|epminstall|epm-install|selfinstall) # HELPCMD: install or update eepm from all in one script
+    ei|epminstall|epm-install|selfinstall) # HELPCMD: install or update eepm package from all in one script
         epm_cmd=epm_install
         ;;
     print)                    # HELPCMD: print various info, run epm print help for details
@@ -335,6 +336,9 @@ check_option()
     --short)              # HELPOPT: short output (just 'package' instead 'package-version-release')
         short="--short"
         ;;
+    --direct)              # HELPOPT: direct install package file from ftp (not via hilevel repository manager)
+        direct="--direct"
+        ;;
     --sort)               # HELPOPT: sort output, f.i. --sort=size (supported only for packages command)
         # TODO: how to read arg?
         sort="$1"
@@ -402,7 +406,9 @@ pkg_filenames=$(strip_spaces "$pkg_files $pkg_names")
 if [ -z "$epm_cmd" ] ; then
     print_version
     echo
-    fatal "Unknown command $@. Run $ $PROGNAME --help for get help"
+    fatstr="Unknown command in $@ arg(s)"
+    [ -n "$*" ] || fatstr="That program needs be running with some command"
+    fatal "$fatstr. Run $ $PROGNAME --help to get help."
 fi
 
 # Use eatmydata for write specific operations
diff --git a/bin/epm-addrepo b/bin/epm-addrepo
index e8df16fb0eaf3ff7f0a660de6514398e5106d547..8bdba4ec1f7cd18e822e29b969665081b8ac47b0 100644
--- a/bin/epm-addrepo
+++ b/bin/epm-addrepo
@@ -1,7 +1,7 @@
 #!/bin/sh
 #
-# Copyright (C) 2012, 2016  Etersoft
-# Copyright (C) 2012, 2016  Vitaly Lipatov <lav@etersoft.ru>
+# Copyright (C) 2012, 2017  Etersoft
+# Copyright (C) 2012, 2017  Vitaly Lipatov <lav@etersoft.ru>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -19,12 +19,49 @@
 
 epm_addrepo()
 {
-local repo="$(eval echo $quoted_args)"
-case $PMTYPE in
-	apt-rpm)
+local repo="$(eval echo "$quoted_args")"
+
+case $DISTRNAME in
+	ALTLinux)
+		case "$repo" in
+			etersoft)
+				info "add etersoft repo"
+				load_helper epm-query
+				epm install --skip-installed apt-conf-etersoft-common apt-conf-etersoft-hold || fatal
+				local branch="$DISTRVERSION/branch"
+				[ "$DISTRVERSION" = "Sisyphus" ] && branch="$DISTRVERSION"
+				# FIXME
+				[ -n "$DISTRVERSION" ] || fatal "Empty DISTRVERSION"
+				local arch=$(uname -m)
+				[ "$arch" = "i686" ] && arch="i586"
+				echo "" | sudocmd tee -a /etc/apt/sources.list
+				echo "# added with eepm addrepo etersoft" | sudocmd tee -a /etc/apt/sources.list
+				echo "rpm [etersoft] http://download.etersoft.ru/pub/Etersoft LINUX@Etersoft/$branch/$arch addon" | sudocmd tee -a /etc/apt/sources.list
+				if [ "$arch" = "x86_64" ] ; then
+					echo "rpm [etersoft] http://download.etersoft.ru/pub/Etersoft LINUX@Etersoft/$branch/$arch-i586 addon" | sudocmd tee -a /etc/apt/sources.list
+				fi
+				echo "rpm [etersoft] http://download.etersoft.ru/pub/Etersoft LINUX@Etersoft/$branch/noarch addon" | sudocmd tee -a /etc/apt/sources.list
+				repo="$DISTRVERSION"
+				return 0
+				;;
+			autoimports)
+				[ -n "$DISTRVERSION" ] || fatal "Empty DISTRVERSION"
+				repo="$repo.$(echo "$DISTRVERSION" | tr "[A-Z]" "[a-z]")"
+		esac
+
 		assure_exists apt-repo
+		if [ -z "$repo" ] ; then
+			docmd apt-repo add branch
+			echo "etersoft"
+			return
+		fi
 		sudocmd apt-repo add "$repo"
+		return
 		;;
+esac
+
+
+case $PMTYPE in
 	apt-dpkg|aptitude-dpkg)
 		info "You need manually add repo to /etc/apt/sources.list"
 		;;
diff --git a/bin/epm-autoremove b/bin/epm-autoremove
index f94b3061217375bf8ee1a526bc2869e7a0cbe35e..c421cbfbae8fdd30427daa4244abcf82c31a8eed 100644
--- a/bin/epm-autoremove
+++ b/bin/epm-autoremove
@@ -17,45 +17,76 @@
 # along with this program. If not, see <http://www.gnu.org/licenses/>.
 #
 
-__epm_autoremove_altrpm()
+__epm_autoremove_altrpm_pp()
 {
-	local pkg
-	load_helper epm-packages
-	assure_exists /etc/buildreqs/files/ignore.d/apt-scripts apt-scripts
+	local pkgs
+
+	info "Removing unused python/perl modules..."
+	#[ -n "$force" ] || info "You can run with --force for more deep removing"
+	local force=force
+
+	local flag=
+	[ -n "$force" ] || libexclude=$libexclude'[^-]*$'
+
+	libexclude='^(python-module-|python3-module-|python-modules-|python3-modules|perl-)'
+	[ -n "$force" ] || libexclude=$libexclude'[^-]*$'
+	showcmd "apt-cache list-nodeps | grep -E -- \"$libexclude\""
+	pkgs=$(apt-cache list-nodeps | grep -E -- "$libexclude" )
+	[ -n "$pkgs" ] && sudocmd rpm -v -e $pkgs && flag=1
+
+	if [ -n "$flag" ] ; then
+		info ""
+		info "call again for next cycle until all modules will be removed"
+		__epm_autoremove_altrpm_pp
+	fi
+
+	return 0
+}
+
+__epm_autoremove_altrpm_lib()
+{
+	local pkgs
+
 	info
 	info "Removing all non -devel/-debuginfo libs packages not need by anything..."
 	#[ -n "$force" ] || info "You can run with --force for more deep removing"
 	local force=force
 
 	local flag=
-	local libexclude='^lib'
+	local libexclude='^(lib|i586-lib)'
 	[ -n "$force" ] || libexclude=$libexclude'[^-]*$'
 
 	# https://www.altlinux.org/APT_в_ALT_Linux/Советы_по_использованию#apt-cache_list-nodeps
 	showcmd "apt-cache list-nodeps | grep -- \"$libexclude\""
-	pkgs=$(apt-cache list-nodeps | grep -- "$libexclude" \
-		| grep -E -v -- "-(devel|debuginfo)$" \
+	pkgs=$(apt-cache list-nodeps | grep -E -- "$libexclude" \
+		| sed -e "s/[-\.]32bit$//g" \
+		| grep -E -v -- "-(devel|devel-static|debuginfo)$" \
 		| grep -E -v -- "-(util|utils|tool|tools|plugin|daemon|help)$" \
-		| sed -e "s/\.32bit$//g" \
-		| grep -E -v -- "^(libsystemd|libreoffice|libnss|libvirt-client|libvirt-daemon|eepm)" )
-	[ -n "$pkgs" ] && sudocmd rpm -v -e $pkgs && flag=1
-
-	info "Removing unused python/perl modules..."
-	libexclude='^(python-module-|python3-module-|python-modules-|python3-modules|perl-)'
-	[ -n "$force" ] || libexclude=$libexclude'[^-]*$'
-	showcmd "apt-cache list-nodeps | grep -E -- \"$libexclude\""
-	pkgs=$(apt-cache list-nodeps | grep -E -- "$libexclude" )
+		| grep -E -v -- "^(libsystemd|libreoffice|libnss|libvirt-client|libvirt-daemon|libsasl2-plugin|eepm)" )
 	[ -n "$pkgs" ] && sudocmd rpm -v -e $pkgs && flag=1
 
 	if [ -n "$flag" ] ; then
 		info ""
 		info "call again for next cycle until all libs will be removed"
-		__epm_autoremove_altrpm
+		__epm_autoremove_altrpm_lib
 	fi
 
 	return 0
 }
 
+
+__epm_autoremove_altrpm()
+{
+	local pkg
+	load_helper epm-packages
+	assure_exists /etc/buildreqs/files/ignore.d/apt-scripts apt-scripts
+
+	__epm_autoremove_altrpm_pp
+	__epm_autoremove_altrpm_lib
+
+	return 0
+}
+
 # TODO: keep our eepm package
 epm_autoremove()
 {
diff --git a/bin/epm-check_updated_repo b/bin/epm-check_updated_repo
index 7bdd23f8c8a176f50cf281aabe6fa7edab92f474..f4e453f99b292797a46454520ec9b98085157dfc 100644
--- a/bin/epm-check_updated_repo
+++ b/bin/epm-check_updated_repo
@@ -34,15 +34,15 @@ __is_repo_info_downloaded()
 __is_repo_info_uptodate()
 {
     case $PMTYPE in
-        apt-rpm)
+        apt-*)
             # apt-deb do not update lock file date
-            if $SUDO test -r /var/lib/apt/lists ; then
-                local LOCKFILE=/var/lib/apt/lists/lock
+            #if $SUDO test -r /var/lib/apt/lists ; then
+                local LOCKFILE=/var/lib/apt/lists
                 $SUDO test -r $LOCKFILE || return
                 # if repo older than 1 day, return false
                 # find print string if file is obsoleted
-                test -z "$($SUDO find $LOCKFILE -mtime +1)" || return
-            fi
+                test -z "$(find $LOCKFILE -maxdepth 0 -mtime +1)" || return
+            #fi
             ;;
         *)
             ;;
diff --git a/bin/epm-download b/bin/epm-download
index 7ab4d2305c101feffd04d8d2359455e490554eb7..e223dcfd5aa3fec930dcb8cba3c608fe7cc266df 100644
--- a/bin/epm-download
+++ b/bin/epm-download
@@ -19,11 +19,19 @@
 
 __use_url_install()
 {
-	case $PMTYPE in
-		apt-rpm)
-			# ALT Linux really?
+	case $DISTRNAME in
+		"ALTLinux")
+			# not for https
+			echo "$pkg_urls" | grep -q "https://" && return 1
 			pkg_names="$pkg_names $pkg_urls"
+			return 0
 			;;
+	esac
+
+	case $PMTYPE in
+		#apt-rpm)
+		#	pkg_names="$pkg_names $pkg_urls"
+		#	;;
 		#deepsolver-rpm)
 		#	pkg_names="$pkg_names $pkg_urls"
 		#	;;
@@ -54,13 +62,15 @@ __download_pkg_urls()
 	for url in $pkg_urls ; do
 		# TODO: use some individual tmp dir
 		local new_file=/tmp/$(basename "$url")
-		if eget -O $new_file $url && [ -s "$new_file" ] ; then
+		if docmd eget -O $new_file $url && [ -s "$new_file" ] ; then
 			pkg_files="$pkg_files $new_file"
 			to_remove_pkg_files="$to_remove_pkg_files $new_file"
 		else
 			warning "Failed to download $url, ignoring"
 		fi
 	done
+	# restore
+	pkg_filenames=$(strip_spaces "$pkg_files $pkg_names")
 }
 
 # NOTE: call __clean_downloaded_pkg_files after
@@ -70,8 +80,8 @@ __handle_pkg_urls_to_install()
 
 	# TODO: do it correctly
 	to_remove_pkg_files=
-	
-	if [ "$(get_package_type "$pkg")" != $PKGFORMAT ] || ! __use_url_install ; then
+	# FIXME: check type of pkg_urls separately?
+	if [ "$(get_package_type "$pkg_urls")" != $PKGFORMAT ] || ! __use_url_install ; then
 		# use workaround with eget: download and put in pkg_files
 		__download_pkg_urls
 	fi
@@ -98,11 +108,38 @@ __handle_pkg_urls_to_checking()
 #	rm -fv $to_remove_pkg_files
 #}
 
+__epm_get_altpkg_url()
+{
+	info "TODO: https://packages.altlinux.org/api/branches"
+	load_helper epm-site
+	local arch=$(paoapi packages/$1 | get_pao_var arch)
+	# FIXME: arch can be list
+	[ "$arch" = "noarch" ] || arch=$(arch)
+	# HACK: filename can be list
+	local filename=$(paoapi packages/$1 | get_pao_var filename | grep $arch)
+	[ -n "$filename" ] || fatal "Can't get filename"
+	# fixme: get from /branches
+	local dv=$DISTRNAME/$DISTRVERSION/branch
+	[ "$DISTRVERSION" = "Sisyphus" ] && dv=$DISTRNAME/$DISTRVERSION
+	echo "http://ftp.basealt.ru/pub/distributions/$dv/$arch/RPMS.classic/$filename"
+}
 
 epm_download()
 {
 	local CMD
 
+	case $DISTRNAME in
+		ALTLinux)
+			local pkg
+			for pkg in $pkg_filenames ; do
+				local url=$(__epm_get_altpkg_url $pkg)
+				[ -n "$url" ] || warning "Can't get url for $pkg"
+				docmd eget $url
+			done
+			return
+			;;
+	esac
+
 	case $PMTYPE in
 	dnf-rpm)
 		sudocmd dnf download $pkg_filenames
@@ -118,6 +155,9 @@ epm_download()
 	dnf-rpm)
 		sudocmd dnf download $pkg_filenames
 		;;
+	urpm-rpm)
+		sudocmd urpmi --no-install $URPMOPTIONS $@
+		;;
 	tce)
 		sudocmd tce-load -w $pkg_filenames
 		;;
diff --git a/bin/epm-filelist b/bin/epm-filelist
index 81751fd6d3f0919b2e20ac5414fe5a225d686486..0cffa8a328a11210bab50d53b98990b575c70389 100644
--- a/bin/epm-filelist
+++ b/bin/epm-filelist
@@ -1,7 +1,7 @@
 #!/bin/sh
 #
-# Copyright (C) 2012-2016  Etersoft
-# Copyright (C) 2012-2016  Vitaly Lipatov <lav@etersoft.ru>
+# Copyright (C) 2012-2017  Etersoft
+# Copyright (C) 2012-2017  Vitaly Lipatov <lav@etersoft.ru>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -37,7 +37,7 @@ __alt_local_content_filelist()
 
     {
         [ -n "$USETTY" ] && info "Search in $CI for $1..."
-        grep -h -- ".*$1$" $CI | sed -e "s|\(.*\)\t\(.*\)|\1|g"
+        __local_ercat $CI | grep -h -- ".*$1$" | sed -e "s|\(.*\)\t\(.*\)|\1|g"
     } | $OUTCMD
 }
 
@@ -64,7 +64,7 @@ __epm_filelist_remote()
 			docmd_foreach __deb_local_content_filelist $@
 			;;
 		*)
-			fatal "Query filelist for non installed packages does not realized"
+			fatal "Query filelist for non installed packages is not implemented yet."
 			;;
 	esac
 }
@@ -134,7 +134,7 @@ __epm_filelist_name()
 			return
 			;;
 		slackpkg)
-			is_installed $@ || fatal "Query filelist for non installed packages does not realized"
+			is_installed $@ || fatal "Query filelist for non installed packages is not implemented yet"
 			docmd awk 'BEGIN{desk=1}{if(/^FILE LIST:$/){desk=0} else if (desk==0) {print}}' /var/log/packages/${pkg_filenames}* | less
 			return
 			;;
diff --git a/bin/epm-info b/bin/epm-info
index 1e6c61bd2b5e6027254903f810a613e1e3e261e8..4f7f5c47762454d1b8b7521d725487399ca4f5dd 100644
--- a/bin/epm-info
+++ b/bin/epm-info
@@ -29,10 +29,16 @@ __epm_info_rpm_low()
 }
 
 # TODO: separate to _files and _names parts
-# realize _files part per package, not by PMTYPE (see filelist)
+# implement _files part per package, not by PMTYPE (see filelist)
 epm_info()
 {
 
+# if possible, it will put pkg_urls into pkg_files or pkg_names
+if [ -n "$pkg_urls" ] ; then
+    load_helper epm-download
+    __handle_pkg_urls_to_checking
+fi
+
 [ -n "$pkg_filenames" ] || fatal "Info: missing package(s) name"
 
 case $PMTYPE in
@@ -117,4 +123,10 @@ case $PMTYPE in
 		;;
 esac
 
+local RETVAL=$?
+
+# TODO: reinvent
+[ -n "$to_remove_pkg_files" ] && rm -fv $to_remove_pkg_files
+
+return $RETVAL
 }
diff --git a/bin/epm-install b/bin/epm-install
index e3e62e97d204e2494d9ffe6b7410d52454e93f9a..c339bd6d9fb0d24f7fd496bd137c17952c25fdc4 100644
--- a/bin/epm-install
+++ b/bin/epm-install
@@ -312,7 +312,6 @@ __epm_check_if_try_install_rpm()
 	cd $TDIR
 	for pkg in $rpmpkgs ; do
 		showcmd_store_output fakeroot alien -d -k --scripts "$pkg"
-		clean_store_output
 		local DEBCONVERTED=$(grep "deb generated" $RC_STDOUT | sed -e "s| generated||g")
 		clean_store_output
 		epm install $DEBCONVERTED
@@ -323,6 +322,23 @@ __epm_check_if_try_install_rpm()
 	return 0
 }
 
+__handle_direct_install()
+{
+    case "$DISTRNAME" in
+        "ALTLinux")
+            load_helper epm-download
+            local pkg url
+            for pkg in $pkg_names ; do
+                url=$(__epm_get_altpkg_url $pkg)
+                [ -n "$url" ] || continue
+                # TODO: use estrlist
+                pkg_urls="$pkg_urls $url"
+            done
+            # FIXME: need remove
+            pkg_names=""
+            ;;
+    esac
+}
 
 epm_install_files()
 {
@@ -514,6 +530,10 @@ epm_install()
         return
     fi
 
+    if [ -n "$direct" ] ; then
+        __handle_direct_install
+    fi
+
     # if possible, it will put pkg_urls into pkg_files or pkg_names
     if [ -n "$pkg_urls" ] ; then
         load_helper epm-download
@@ -527,7 +547,7 @@ epm_install()
 
     [ -z "$files$names" ] && info "Skip empty install list" && return 22
 
-    if [ -z "$files" ] ; then
+    if [ -z "$files" ] && [ -z "$direct" ] ; then
         # it is useful for first time running
         update_repo_if_needed
     fi
diff --git a/bin/epm-packages b/bin/epm-packages
index e48a448b0ffb63bc921c0323e5241fabb63d977f..af3fc7abae50eae434318390ea523f082cf9156d 100644
--- a/bin/epm-packages
+++ b/bin/epm-packages
@@ -23,13 +23,13 @@ __epm_packages_sort()
 case $PMTYPE in
 	apt-rpm|yum-rpm|urpm-rpm|zypper-rpm|dnf-rpm)
 		# FIXME: space with quotes problems, use point instead
-		docmd rpm -qa --queryformat "%{size}.%{name}-%{version}-%{release}\n" $pkg_filenames | sort -n
+		docmd rpm -qa --queryformat "%{size}@%{name}-%{version}-%{release}\n" $pkg_filenames | sed -e "s|@| |g" | sort -n -k1
 		;;
 	apt-dpkg)
-		docmd dpkg-query -W --showformat="\${Size}.\${Package}-\${Version}\n" $pkg_filenames | sort -n
+		docmd dpkg-query -W --showformat="\${Installed-Size}@\${Package}-\${Version}\n" $pkg_filenames | sed -e "s|@| |g" | sort -n -k1
 		;;
 	*)
-		fatal "Sorted package list are not realized for $PMTYPE"
+		fatal "Sorted package list function is not implemented for $PMTYPE"
 		;;
 esac
 }
diff --git a/bin/epm-policy b/bin/epm-policy
index 987af2771b44b10c68e82299cbfe83ac3f3e1649..74926b7b490315e2623ac16c74d9970411b4ef20 100644
--- a/bin/epm-policy
+++ b/bin/epm-policy
@@ -1,7 +1,7 @@
 #!/bin/sh
 #
-# Copyright (C) 2015  Etersoft
-# Copyright (C) 2015  Vitaly Lipatov <lav@etersoft.ru>
+# Copyright (C) 2015, 2017  Etersoft
+# Copyright (C) 2015, 2017  Vitaly Lipatov <lav@etersoft.ru>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -17,11 +17,16 @@
 # along with this program. If not, see <http://www.gnu.org/licenses/>.
 #
 
+load_helper epm-query
+
 epm_policy()
 {
 
 [ -n "$pkg_names" ] || fatal "Info: missing package(s) name"
 
+# get package name for hi level package management command (with version if supported and if possible)
+pkg_names=$(__epm_get_hilevel_name $pkg_names)
+
 case $PMTYPE in
 	apt-rpm)
 		docmd apt-cache policy $pkg_names
diff --git a/bin/epm-query b/bin/epm-query
index ec4c8db8aad9ff27ec9aa98ff50d9ac599711a48..b95d307015b4ffbbd5fff421e31e374829697651 100644
--- a/bin/epm-query
+++ b/bin/epm-query
@@ -98,11 +98,11 @@ __epm_get_hilevel_nameform()
 			echo $pkg
 			return
 			;;
-		yum-rpm)
+		yum-rpm|dnf-rpm)
 			# just use strict version with Epoch and Serial
 			local pkg
-			pkg=$(rpm -q --queryformat "%{EPOCH}:%{NAME}%{VERSION}-%{RELEASE}.${ARCH}\n" $1)
-			echo $pkg | grep -q "(none)" && pkg=$(rpm -q --queryformat "%{NAME}-%{VERSION}-%{RELEASE}.${ARCH}\n" $1)
+			pkg=$(rpm -q --queryformat "%{EPOCH}:%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n" $1)
+			echo $pkg | grep -q "(none)" && pkg=$(rpm -q --queryformat "%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n" $1)
 			echo $pkg
 			return
 			;;
diff --git a/bin/epm-query_file b/bin/epm-query_file
index e20853644567d55665f5cc32f6eef847df77f627..ee3d68a1a9457976b64cdf80a35d12c86b4f9911 100644
--- a/bin/epm-query_file
+++ b/bin/epm-query_file
@@ -19,13 +19,27 @@
 
 # copied from etersoft-build-utils/bin/rpmqf
 
+# TODO: check for lib64/name situations
+__abs_filename()
+{
+	if echo "$1" | grep -q "/" ; then
+		echo "$1"
+		return
+	fi
+	if [ -e "$1" ] ; then
+		echo "$(pwd)/$1"
+		return
+	fi
+	echo "$1"
+}
+
 __do_query_real_file()
 {
 	local TOFILE
 	
 	# get canonical path
 	if [ -e "$1" ] ; then
-		TOFILE=$(realpath "$1")
+		TOFILE="$(__abs_filename "$1")"
 	else
 		TOFILE=$(which "$1" 2>/dev/null || echo "$1")
 		if [ "$TOFILE" != "$1" ] ; then
@@ -104,7 +118,7 @@ __do_query()
             ;;
         aptcyg)
             #CMD="apt-cyg packageof"
-            # do not realized locally
+            # is not implemented locally
             return 1
             ;;
         *)
diff --git a/bin/epm-release_upgrade b/bin/epm-release_upgrade
index 49c18888c222ced8d475c3c79655a4e76eadcbed..b577d7ff00a3c7b074b0b21660fe8e5e16383cda 100644
--- a/bin/epm-release_upgrade
+++ b/bin/epm-release_upgrade
@@ -117,7 +117,7 @@ __update_to_the_distro()
 			;;
 		Sisyphus)
 			docmd epm update || fatal
-			docmd epm install apt rpm apt-conf-sisyphus altlinux-release-sisyphus || fatal "Check an error and run again"
+			docmd epm install apt rpm librpm7 librpm apt-conf-sisyphus altlinux-release-sisyphus || fatal "Check an error and run again"
 			docmd epm upgrade || fatal "Check an error and run epm release-upgrade again"
 			;;
 		*)
@@ -232,9 +232,11 @@ epm_release_upgrade()
 		assure_exists dnf-plugin-system-upgrade
 		sudocmd dnf system-upgrade
 		local RELEASEVER="$pkg_filenames"
-		[ -n "$RELEASEVER" ] || fatal "Run me with new version"
+		[ -n "$RELEASEVER" ] || RELEASEVER=$(($DISTRVERSION + 1))
+		#[ -n "$RELEASEVER" ] || fatal "Run me with new version"
+		info "Upgrate to $DISTRNAME/$RELEASEVER"
 		sudocmd dnf system-upgrade download --refresh --releasever=$RELEASEVER
-		sudocmd dnf system-upgrade
+		sudocmd dnf distro-sync --releasever=$RELEASEVER
 		info "Run epm autoorphans to remove orphaned packages"
 		;;
 	urpm-rpm)
diff --git a/bin/epm-removerepo b/bin/epm-removerepo
index b90715df8671485aceeabc27bae18e6a06e6583b..ac03b071609bc68cf5d177ee579a4d66aad2d68c 100644
--- a/bin/epm-removerepo
+++ b/bin/epm-removerepo
@@ -1,7 +1,7 @@
 #!/bin/sh
 #
-# Copyright (C) 2012, 2016  Etersoft
-# Copyright (C) 2012, 2016  Vitaly Lipatov <lav@etersoft.ru>
+# Copyright (C) 2012, 2017  Etersoft
+# Copyright (C) 2012, 2017  Vitaly Lipatov <lav@etersoft.ru>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -20,11 +20,24 @@
 epm_removerepo()
 {
 local repo="$(eval echo $quoted_args)"
-case $PMTYPE in
-	apt-rpm)
+
+case $DISTRNAME in
+	ALTLinux)
+		case "$repo" in
+			autoimports)
+				info "remove autoimports repo"
+				[ -n "$DISTRVERSION" ] || fatal "Empty DISTRVERSION"
+				repo="$repo.$(echo "$DISTRVERSION" | tr "[A-Z]" "[a-z]")"
+				;;
+		esac
+
 		assure_exists apt-repo
 		sudocmd apt-repo rm "$repo"
+		return
 		;;
+esac;
+
+case $PMTYPE in
 	apt-dpkg|aptitude-dpkg)
 		info "You need remove repo from /etc/apt/sources.list"
 		;;
diff --git a/bin/epm-repofix b/bin/epm-repofix
index 0e998fd90148e98e9e04f3de449f64a3f14e48a0..4cd993abf6754c39bb289e3efabed41165432372 100644
--- a/bin/epm-repofix
+++ b/bin/epm-repofix
@@ -29,8 +29,26 @@ __repofix_check_vendor()
 	return 1
 }
 
+# source-list vendor path
+# example: /etc/apt/source.list p7 ALTLinux\/Sisyphus
+__try_fix_apt_source_list()
+{
+	local list="$1"
+	local br="$2"
+	local path="$3"
+	if grep -q -e "^[^#].*$path" $list ; then
+		if __repofix_check_vendor $br ; then
+			regexp_subst "/$path/s/^rpm[[:space:]]*([fhr])/rpm [$br] \1/" $list
+		else
+			warning "Skip set $br vendor key (it misssed) for $list"
+			regexp_subst "/$path/s/^rpm[[:space:]]*\[$br\][[:space:]]*([fhr])/rpm \1/" $list
+		fi
+	fi
+}
+
 __fix_apt_sources_list()
 {
+	# for beauty spaces
 	local SUBST_ALT_RULE='s!^(.*)[/ ](ALTLinux|LINUX\@Etersoft)[/ ](Sisyphus|p8[/ ]branch|p7[/ ]branch|p6[/ ]branch)[/ ](x86_64|i586|x86_64-i586|noarch) !\1 \2/\3/\4 !gi'
 	local i
 	assure_root
@@ -42,33 +60,14 @@ __fix_apt_sources_list()
 		regexp_subst "/^ *#/! $SUBST_ALT_RULE" $i
 
 		# Sisyphus uses 'alt' vendor key
-		if __repofix_check_vendor alt ; then
-			regexp_subst "/ALTLinux\/Sisyphus\//s/^rpm *([fhr])/rpm [alt] \1/" $i
-		else
-			warning "Skip set alt vendor key (it misssed)"
-		fi
+		__try_fix_apt_source_list $i alt "ALTLinux\/Sisyphus"
 
 		# skip branch replacement for ALT Linux Sisyphus
 		[ "$DISTRVERSION" = "Sisyphus" ] && continue
 
 		# add signs for branches
-		local br
-		for br in $DISTRVERSION ; do
-			if ! __repofix_check_vendor $br ; then
-				warning "Skip set $br vendor key (it misssed)"
-				continue
-			fi
-			regexp_subst "/ALTLinux\/$br\/branch/s/^rpm *([fhr])/rpm [$br] \1/" $i
-		done
-
-		for br in $DISTRVERSION ; do
-			#if is_installed apt-conf-etersoft-common ; then
-			if ! __repofix_check_vendor etersoft ; then
-				warning "Skip set etersoft vendor key (it misssed)"
-				continue
-			fi
-			regexp_subst "/Etersoft\/$br\/branch/s/^rpm *([fhr])/rpm [etersoft] \1/" $i
-		done
+		__try_fix_apt_source_list $i $DISTRVERSION "ALTLinux\/$DISTRVERSION\/branch"
+		__try_fix_apt_source_list $i etersoft "Etersoft\/$DISTRVERSION\/branch"
 	done
 }
 
diff --git a/bin/epm-search_file b/bin/epm-search_file
index ddffa4ec058827edd14dfeede0b6007621b8b6c9..567dafd9d5167a8fb66f6bffeb021dc06c7e4c83 100644
--- a/bin/epm-search_file
+++ b/bin/epm-search_file
@@ -1,7 +1,7 @@
 #!/bin/sh
 #
-# Copyright (C) 2012, 2016  Etersoft
-# Copyright (C) 2012, 2016  Vitaly Lipatov <lav@etersoft.ru>
+# Copyright (C) 2012, 2016, 2017  Etersoft
+# Copyright (C) 2012, 2016, 2017  Vitaly Lipatov <lav@etersoft.ru>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -17,21 +17,34 @@
 # along with this program. If not, see <http://www.gnu.org/licenses/>.
 #
 
+# TODO: see epm-search (colorify for all distro)
+
+# args: index_lists word grep_string
+__alt_search_file_output()
+{
+    # grep only on left part (filename), then revert order and grep with color
+    __local_ercat $1 | grep -h -- ".*$2.*[[:space:]]" | sed -e "s|\(.*\)\t\(.*\)|\2: \1|g" $3
+}
+
 __alt_local_content_search()
 {
     load_helper epm-sh-altlinux
+    load_helper epm-search
 
+    info "Locate contents index file(s) ..."
     local CI="$(get_local_alt_contents_index)"
+    # TODO use something like
     [ -n "$CI" ] || fatal "Have no local contents index"
-    #local OUTCMD="less"
-    #[ -n "$USETTY" ] || OUTCMD="cat"
-    OUTCMD="cat"
 
-    {
-        [ -n "$USETTY" ] && info "Search in $CI for $1..."
-        # note! tabulation below!
-        grep -h -- ".*$1.*	" $CI | sed -e "s|\(.*\)\t\(.*\)|\2: \1|g"
-    } | $OUTCMD
+    info "Searching in"
+    echo "$CI"
+    echo "for $1... "
+
+    # FIXME: do it better
+    local MGS
+    MGS=$(eval __epm_search_make_grep $quoted_args)
+    showcmd "$ cat contents_index $MGS"
+    eval "__alt_search_file_output \"$CI\" \"$(eval get_firstarg $quoted_args)\" $MGS"
 }
 
 epm_search_file()
@@ -50,12 +63,12 @@ case $PMTYPE in
 		return ;;
 	yum-rpm)
 		# TODO
-		info "Search by full packages list does not realized"
+		info "Search by full packages list is not implemented yet"
 		CMD="yum provides"
 		;;
 	dnf-rpm)
 		# TODO
-		info "Search by full packages list does not realized"
+		info "Search by full packages list is not implemented yet"
 		CMD="dnf provides"
 		;;
 	urpm-rpm)
diff --git a/bin/epm-sh-altlinux b/bin/epm-sh-altlinux
index a74db9885f9396f268ea00b60e0cf5bee612688b..f9e563e093f5812605212b7974cbc6fe5317ba74 100644
--- a/bin/epm-sh-altlinux
+++ b/bin/epm-sh-altlinux
@@ -1,7 +1,7 @@
 #!/bin/sh
 #
-# Copyright (C) 2014  Etersoft
-# Copyright (C) 2014  Vitaly Lipatov <lav@etersoft.ru>
+# Copyright (C) 2014, 2017  Etersoft
+# Copyright (C) 2014, 2017  Vitaly Lipatov <lav@etersoft.ru>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -17,19 +17,98 @@
 # along with this program. If not, see <http://www.gnu.org/licenses/>.
 #
 
-# TODO: port or rewrite apt-file
+# apt-file like. See also
 # https://bugzilla.altlinux.org/show_bug.cgi?id=14449
+
+# convert "http://download.etersoft.ru/pub/ALTLinux/p8/branch x86_64" to /tmp/epm/ALTLinux/p8/branch/x86_64
+get_local_alt_mirror_path()
+{
+    local DN1=$(dirname "$1")
+    local DN2=$(dirname $DN1)
+    local DN3=$(dirname $DN2)
+
+    local BN0=$(basename "$1") # arch
+    local BN1=$(basename $DN1) # branch/Sisyphus
+    local BN2=$(basename $DN2) # p8/ALTLinux
+    local BN3=$(basename $DN3) # ALTLinux/
+
+    [ "$BN1" = "branch" ] && echo "/tmp/eepm/$BN3/$BN2/$BN1/$BN0" || echo "/tmp/eepm/$BN2/$BN1/$BN0"
+}
+
+__local_ercat()
+{
+   local i
+   for i in $* ; do
+       case "$i" in
+           *.xz)
+               a= xzcat $i
+               ;;
+           *.lz4)
+               a= lz4cat $i
+               ;;
+           *.failed)
+               # just ignore
+               ;;
+           *)
+               cat $i
+               ;;
+       esac
+   done
+}
+
+# something like gzip
+compress_file_inplace()
+{
+    local OFILE="$1"
+    if epm assure lz4 </dev/null ; then
+        #docmd lz4 --rm "$OFILE" "$OFILE.lz4" || return
+        # due old lz4
+        docmd lz4 "$OFILE" "$OFILE.lz4" || return
+        rm -fv "$OFILE"
+    else
+        epm assure xz </dev/null || return
+        docmd xz "$OFILE" || return
+    fi
+    return 0
+}
+
+# args: url/path target_file
+# result: will set FILE
+download_alt_contents_index()
+{
+    local URL="$1"
+    local TD="$2"
+    local OFILE="$TD/$(basename "$URL")"
+
+    local DONE=$(echo $OFILE*)
+    # TODO: check if too old
+    if [ -r "$DONE" ] ; then
+        return
+    fi
+
+    mkdir -p "$TD"
+
+    if echo "$URL" | grep -q "^file:/" ; then
+        URL=$(echo "$URL" | sed -e "s|^file:||")
+        [ -s "$URL" ] || { touch $OFILE.failed ; return 1; }
+        ln -s "$URL" "$OFILE" || { touch $OFILE.failed ; return 1; }
+    else
+        docmd eget -O "$OFILE" "$URL" || { rm -fv $OFILE ; touch $OFILE.failed ; return 1; }
+    fi
+
+    compress_file_inplace "$OFILE"
+}
+
 get_local_alt_contents_index()
 {
     load_helper epm-repolist
 
-    epm_repolist | grep "rpm.*file:/" | sed -e "s|^rpm.*file:||g" | while read URL ARCH other ; do
-        test -d "$URL/$ARCH" || continue # fatal "Local mirror is not accessible via $URL/$ARCH"
-        FILE="$URL/$ARCH/base/contents_index"
-        if [ -r "$FILE" ] ; then
-            echo "$FILE"
-        else
-            info "TODO for girar server: There is no $(basename $FILE) file in $(dirname $FILE)"
-        fi
+    local LOCALPATH
+
+    epm_repolist | grep -E "rpm.*(ftp://|http://|https://|file:/)" | sed -e "s@^rpm.*\(ftp://\|http://\|https://\|file:\)@\1@g" | while read URL ARCH other ; do
+        LOCALPATH=$(get_local_alt_mirror_path "$URL/$ARCH")
+        download_alt_contents_index $URL/$ARCH/base/contents_index $LOCALPATH >&2 || continue
+        echo "$LOCALPATH/contents_index*"
     done
+
 }
diff --git a/bin/epm-sh-functions b/bin/epm-sh-functions
index 3bdbf001358c5d29df2e5a7dba64045a189fe834..93c9c27fb5dd6997740d8999c4940e5bcc215352 100644
--- a/bin/epm-sh-functions
+++ b/bin/epm-sh-functions
@@ -154,6 +154,14 @@ sudocmd_foreach()
 	done
 }
 
+# add realpath if missed
+if ! which realpath 2>/dev/null >/dev/null ; then
+realpath()
+{
+	readlink -f "$@"
+}
+fi
+
 get_firstarg()
 {
 	echon "$1"
@@ -459,14 +467,14 @@ case $DISTRNAME in
 	ArchLinux)
 		CMD="pacman"
 		;;
-	Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific)
+	Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific|GosLinux)
 		CMD="yum-rpm"
 		which dnf 2>/dev/null >/dev/null && test -d /var/lib/dnf/yumdb && CMD=dnf-rpm
 		;;
 	Slackware)
 		CMD="slackpkg"
 		;;
-	SUSE|SLED|SLES)
+	SUSE|SLED|SLES|Tumbleweed)
 		CMD="zypper-rpm"
 		;;
 	ForesightLinux|rPathLinux)
@@ -515,6 +523,7 @@ is_active_systemd()
 	[ -x "$SYSTEMCTL" ] || return
 	[ -d "$SYSTEMD_CGROUP_DIR" ] || return
 	a= mountpoint -q "$SYSTEMD_CGROUP_DIR" || return
+	readlink /sbin/init | grep -q 'systemd' || return
 	# some hack
-	ps ax | grep -q '[s]ystemd' | grep -v 'systemd-udev' >/dev/null
+	ps ax | grep '[s]ystemd' | grep -q -v 'systemd-udev'
 }
diff --git a/bin/epm-site b/bin/epm-site
index c48ccb48b59b4ea6bb2bd72f69282e30938e4fc3..0789ec86c552cbbefd7a8296491aff3592f29847 100644
--- a/bin/epm-site
+++ b/bin/epm-site
@@ -22,6 +22,24 @@ load_helper epm-print
 
 PAOURL="https://packages.altlinux.org"
 
+paoapi()
+{
+	# http://petstore.swagger.io/?url=http://packages.altlinux.org/api/docs
+	epm assure curl || return 1
+	showcmd curl "$PAOURL/api/$1"
+	a= curl -s --header "Accept: application/json" "$PAOURL/api/$1"
+}
+
+# TODO: use /home/lav/Projects/git/JSON.sh
+get_pao_var()
+{
+	local FIELD="$1"
+	#grep '"$FIELD"' | sed -e 's|.*"$FIELD":"||g' | sed -e 's|".*||g'
+	$SHAREDIR/tools_json -b | egrep "\[.*\"$FIELD\"\]" | sed -e 's|.*[[:space:]]"\(.*\)"|\1|g'
+	return 0
+}
+
+
 run_command_if_exists()
 {
 	local CMD="$1"
@@ -43,14 +61,9 @@ open_browser()
 
 __query_package_hl_url()
 {
-	local PAOAPI="$PAOURL/api"
 	case $DISTRNAME in
 		ALTLinux)
-			# http://petstore.swagger.io/?url=http://packages.altlinux.org/api/docs
-			epm assure curl || return 1
-			showcmd curl "$PAOAPI/srpms/$1"
-			a= curl -s --header "Accept: application/json" "$PAOAPI/srpms/$1" | grep '"url"' | sed -e 's|.*"url":"||g' | sed -e 's|".*||g'
-			return 0
+			paoapi srpms/$1 | get_pao_var url
 			;;
 	esac
 	return 1
diff --git a/bin/epm-upgrade b/bin/epm-upgrade
index 0943699cbfb4aa57873eb9f35d046f7fcd7fa965..8ac13cfb05f850bb10084cc37efc9d0970c11bed 100644
--- a/bin/epm-upgrade
+++ b/bin/epm-upgrade
@@ -23,7 +23,7 @@ epm_upgrade()
 {
 	local CMD
 
-	[ -z "$pkg_filenames" ] || fatal "No arguments are allowed here"
+	#[ -z "$pkg_filenames" ] || fatal "No arguments are allowed here"
 
 	# it is useful for first time running
 	update_repo_if_needed
@@ -42,18 +42,18 @@ epm_upgrade()
 	yum-rpm)
 		local OPTIONS="$(subst_option non_interactive -y)"
 		# can do update repobase automagically
-		CMD="yum $OPTIONS update"
+		CMD="yum $OPTIONS update $pkg_filenames"
 		;;
 	dnf-rpm)
 		local OPTIONS="$(subst_option non_interactive -y)"
-		CMD="dnf $OPTIONS distro-sync"
+		CMD="dnf $OPTIONS distro-sync $pkg_filenames"
 		;;
 	snappy)
 		CMD="snappy update"
 		;;
 	urpm-rpm)
 		# or --auto-select --replace-files
-		CMD="urpmi --update --auto-select"
+		CMD="urpmi --update --auto-select $pkg_filenames"
 		;;
 	zypper-rpm)
 		CMD="zypper dist-upgrade"
diff --git a/bin/epm-whatdepends b/bin/epm-whatdepends
index f4ef16876916cdf66e053ce347bfa7fb3e403858..770fd0390c899018fadd9a57c08765272170486c 100644
--- a/bin/epm-whatdepends
+++ b/bin/epm-whatdepends
@@ -17,6 +17,8 @@
 # along with this program. If not, see <http://www.gnu.org/licenses/>.
 #
 
+# TODO: will it has local only mode?
+
 load_helper epm-print
 
 epm_whatdepends()
@@ -44,6 +46,7 @@ case $PMTYPE in
 		CMD="urpmq --whatrequires"
 		;;
 	dnf-rpm)
+		# check command: dnf repoquery --whatrequires
 		CMD="repoquery --whatrequires"
 		;;
 	emerge)
diff --git a/bin/serv b/bin/serv
index 7a5610791a211a47c833e44cc64f4cf62c41d8fd..5e8062ad67acb551e37a344ddd0bac1f852145da 100755
--- a/bin/serv
+++ b/bin/serv
@@ -58,7 +58,7 @@ case $DISTRNAME in
 	ALTLinux)
 		CMD="service-chkconfig"
 		;;
-	Ubuntu|Debian|Mint)
+	Ubuntu|Debian|Mint|AstraLinux)
 		CMD="service-update"
 		;;
 	Mandriva|ROSA)
@@ -73,7 +73,7 @@ case $DISTRNAME in
 #	ArchLinux)
 #		CMD="pacman"
 #		;;
-	Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific)
+	Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific|GosLinux)
 		CMD="service-chkconfig"
 		;;
 	VoidLinux)
@@ -82,7 +82,7 @@ case $DISTRNAME in
 	Slackware)
 		CMD="service-initd"
 		;;
-	SUSE|SLED|SLES)
+	SUSE|SLED|SLES|Tumbleweed)
 		CMD="service-chkconfig"
 		;;
 #	Windows)
diff --git a/bin/tools_json b/bin/tools_json
new file mode 100755
index 0000000000000000000000000000000000000000..c4452f9bf97f2fb2eed33f58685f412b11bca622
--- /dev/null
+++ b/bin/tools_json
@@ -0,0 +1,211 @@
+#!/bin/sh
+
+# License: MIT or Apache
+# Homepage: http://github.com/dominictarr/JSON.sh
+
+throw() {
+  echo "$*" >&2
+  exit 1
+}
+
+BRIEF=0
+LEAFONLY=0
+PRUNE=0
+NO_HEAD=0
+NORMALIZE_SOLIDUS=0
+
+usage() {
+  echo
+  echo "Usage: JSON.sh [-b] [-l] [-p] [-s] [-h]"
+  echo
+  echo "-p - Prune empty. Exclude fields with empty values."
+  echo "-l - Leaf only. Only show leaf nodes, which stops data duplication."
+  echo "-b - Brief. Combines 'Leaf only' and 'Prune empty' options."
+  echo "-n - No-head. Do not show nodes that have no path (lines that start with [])."
+  echo "-s - Remove escaping of the solidus symbol (straight slash)."
+  echo "-h - This help text."
+  echo
+}
+
+parse_options() {
+  set -- "$@"
+  local ARGN=$#
+  while [ "$ARGN" -ne 0 ]
+  do
+    case $1 in
+      -h) usage
+          exit 0
+      ;;
+      -b) BRIEF=1
+          LEAFONLY=1
+          PRUNE=1
+      ;;
+      -l) LEAFONLY=1
+      ;;
+      -p) PRUNE=1
+      ;;
+      -n) NO_HEAD=1
+      ;;
+      -s) NORMALIZE_SOLIDUS=1
+      ;;
+      ?*) echo "ERROR: Unknown option."
+          usage
+          exit 0
+      ;;
+    esac
+    shift 1
+    ARGN=$((ARGN-1))
+  done
+}
+
+awk_egrep () {
+  local pattern_string=$1
+
+  gawk '{
+    while ($0) {
+      start=match($0, pattern);
+      token=substr($0, start, RLENGTH);
+      print token;
+      $0=substr($0, start+RLENGTH);
+    }
+  }' pattern="$pattern_string"
+}
+
+tokenize () {
+  local GREP
+  local ESCAPE
+  local CHAR
+
+  if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1
+  then
+    GREP='egrep -ao --color=never'
+  else
+    GREP='egrep -ao'
+  fi
+
+  if echo "test string" | egrep -o "test" >/dev/null 2>&1
+  then
+    ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
+    CHAR='[^[:cntrl:]"\\]'
+  else
+    GREP=awk_egrep
+    ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
+    CHAR='[^[:cntrl:]"\\\\]'
+  fi
+
+  local STRING="\"$CHAR*($ESCAPE$CHAR*)*\""
+  local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
+  local KEYWORD='null|false|true'
+  local SPACE='[[:space:]]+'
+
+  # Force zsh to expand $A into multiple words
+  local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$')
+  if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi
+  $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$"
+  if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi
+}
+
+parse_array () {
+  local index=0
+  local ary=''
+  read -r token
+  case "$token" in
+    ']') ;;
+    *)
+      while :
+      do
+        parse_value "$1" "$index"
+        index=$((index+1))
+        ary="$ary""$value" 
+        read -r token
+        case "$token" in
+          ']') break ;;
+          ',') ary="$ary," ;;
+          *) throw "EXPECTED , or ] GOT ${token:-EOF}" ;;
+        esac
+        read -r token
+      done
+      ;;
+  esac
+  [ "$BRIEF" -eq 0 ] && value=$(printf '[%s]' "$ary") || value=
+  :
+}
+
+parse_object () {
+  local key
+  local obj=''
+  read -r token
+  case "$token" in
+    '}') ;;
+    *)
+      while :
+      do
+        case "$token" in
+          '"'*'"') key=$token ;;
+          *) throw "EXPECTED string GOT ${token:-EOF}" ;;
+        esac
+        read -r token
+        case "$token" in
+          ':') ;;
+          *) throw "EXPECTED : GOT ${token:-EOF}" ;;
+        esac
+        read -r token
+        parse_value "$1" "$key"
+        obj="$obj$key:$value"        
+        read -r token
+        case "$token" in
+          '}') break ;;
+          ',') obj="$obj," ;;
+          *) throw "EXPECTED , or } GOT ${token:-EOF}" ;;
+        esac
+        read -r token
+      done
+    ;;
+  esac
+  [ "$BRIEF" -eq 0 ] && value=$(printf '{%s}' "$obj") || value=
+  :
+}
+
+parse_value () {
+  local jpath="${1:+$1,}$2" isleaf=0 isempty=0 print=0
+  case "$token" in
+    '{') parse_object "$jpath" ;;
+    '[') parse_array  "$jpath" ;;
+    # At this point, the only valid single-character tokens are digits.
+    ''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;;
+    *) value=$token
+       # if asked, replace solidus ("\/") in json strings with normalized value: "/"
+       [ "$NORMALIZE_SOLIDUS" -eq 1 ] && value=$(echo "$value" | sed 's#\\/#/#g')
+       isleaf=1
+       [ "$value" = '""' ] && isempty=1
+       ;;
+  esac
+  [ "$value" = '' ] && return
+  [ "$NO_HEAD" -eq 1 ] && [ -z "$jpath" ] && return
+
+  [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 0 ] && print=1
+  [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && [ $PRUNE -eq 0 ] && print=1
+  [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 1 ] && [ "$isempty" -eq 0 ] && print=1
+  [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && \
+    [ $PRUNE -eq 1 ] && [ $isempty -eq 0 ] && print=1
+  [ "$print" -eq 1 ] && printf "[%s]\t%s\n" "$jpath" "$value"
+  :
+}
+
+parse () {
+  read -r token
+  parse_value
+  read -r token
+  case "$token" in
+    '') ;;
+    *) throw "EXPECTED EOF GOT $token" ;;
+  esac
+}
+
+if ([ "$0" = "$BASH_SOURCE" ] || ! [ -n "$BASH_SOURCE" ]);
+then
+  parse_options "$@"
+  tokenize | parse
+fi
+
+# vi: expandtab sw=2 ts=2
diff --git a/eepm.spec b/eepm.spec
index 0ffb7a949223458186812b7e2c95ad074cebd469..02c95d8b134646ba07e3f2d5847dfbbfd8f5711e 100644
--- a/eepm.spec
+++ b/eepm.spec
@@ -1,7 +1,7 @@
 # This spec is backported to ALTLinux p7 automatically by rpmbph script from etersoft-build-utils.
 #
 Name: eepm
-Version: 1.9.8
+Version: 2.0.6
 Release: alt0.M70P.1
 
 Summary: Etersoft EPM package manager
@@ -68,9 +68,58 @@ chmod a+x %buildroot%_datadir/%name/tools_*
 %_sysconfdir/bash_completion.d/cerv
 
 %changelog
-* Fri Dec 02 2016 Vitaly Lipatov <lav@altlinux.ru> 1.9.8-alt0.M70P.1
+* Thu Mar 23 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.6-alt0.M70P.1
 - backport to ALTLinux p7 (by rpmbph script)
 
+* Mon Mar 13 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.6-alt1
+- epm-packages: improve sort output
+- hack to support old lz4
+
+* Fri Mar 10 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.5-alt1
+- epm sf: make compressed cache for local file too
+- rewrite epm sf, colorify it
+- more correct message when empty run
+
+* Thu Mar 09 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.4-alt1
+- epm-policy: move to hilevel package name
+- implement local cache for contents index for ALT repos
+
+* Tue Mar 07 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.3-alt1
+- fix query hilevel name for yum/dnf
+- epm install: fix install rpm on deb
+- add missed in some cases AstraLinux and GosLinux
+
+* Thu Mar 02 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.2-alt1
+- distr_info: fix version detection for all ALT p8 distros
+- add workaround for ALT rpm missed https support
+- install librpm7 during upgrade to Sisyphus
+- improve systemd checking
+
+* Tue Feb 07 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.1-alt1
+- autoremove: skip -32bit suffix
+
+* Mon Jan 16 2017 Vitaly Lipatov <lav@altlinux.ru> 2.0.0-alt1
+- distr_info: fix get lsb-release file with quoted fields
+- epm-download: add filename empty checking
+- epm info: add URL support
+- epm upgrade: allow extra args
+- release_upgrade: improve for Fedora
+- epm-download: add support for urpm
+- check_update_repo: check for /var/lib/apt/lists date
+- query_file: improve check for relative path
+- epm-automove: fix i586-lib issue
+- fix systemd detection
+- epm: add/remove autoimports
+
+* Wed Dec 07 2016 Vitaly Lipatov <lav@altlinux.ru> 1.9.9-alt1
+- add own realpath implementation if missed
+- add openSUSE Tumbleweed support
+- autoremove: do separate removing cycles for python/perl and libs
+- epm-site: fix json parsing
+- epm-download: realize download via info from packages.altlinux.org
+- epm-install: add direct install (not via apt) support for ALT Linux
+- addrepo: implement support for epm addrepo etersoft
+
 * Thu Dec 01 2016 Vitaly Lipatov <lav@altlinux.ru> 1.9.8-alt1
 - epm-install: move download code to epm-download
 - epm-checkpkg: add support for checking package by url
diff --git a/pack_in_onefile.sh b/pack_in_onefile.sh
index 68182e243753a3dda93c39bacc6a90c556f48c8c..ec5a51b6dfa7e594a8c7c0f47450d56e4ce7f03c 100755
--- a/pack_in_onefile.sh
+++ b/pack_in_onefile.sh
@@ -44,6 +44,7 @@ filter_out()
 {
 	grep -v "^[ 	]*load_helper " | \
 		sed -e 's|$SHAREDIR/tools_eget|internal_tools_eget|g' | \
+		sed -e 's|$SHAREDIR/tools_json|internal_tools_json|g' | \
 		sed -e 's|DISTRVENDOR=$PROGDIR/distr_info|DISTRVENDOR=internal_distr_info|g' | \
 		sed -e "s|@VERSION@|$(get_version)|g"
 
@@ -64,6 +65,7 @@ done | filter_out >>$OUTPUT
 
 incorporate_subfile distr_info
 incorporate_subfile tools_eget
+incorporate_subfile tools_json
 
 awk 'BEGIN{desk=0}{if(desk>0) {print} ; if(/^load_helper epm-sh-functions/){desk++}}' <bin/$PACKCOMMAND | filter_out >>$OUTPUT
 chmod 0755 $OUTPUT
diff --git a/packed/epm.sh b/packed/epm.sh
index 9269d79bcf097dfb5203cb14c7196ed9bb0ba94b..4e97ab2756a6883b9f42557067fabaabb2966980 100755
--- a/packed/epm.sh
+++ b/packed/epm.sh
@@ -166,6 +166,13 @@ sudocmd_foreach()
 	done
 }
 
+if ! which realpath 2>/dev/null >/dev/null ; then
+realpath()
+{
+	readlink -f "$@"
+}
+fi
+
 get_firstarg()
 {
 	echon "$1"
@@ -451,14 +458,14 @@ case $DISTRNAME in
 	ArchLinux)
 		CMD="pacman"
 		;;
-	Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific)
+	Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific|GosLinux)
 		CMD="yum-rpm"
 		which dnf 2>/dev/null >/dev/null && test -d /var/lib/dnf/yumdb && CMD=dnf-rpm
 		;;
 	Slackware)
 		CMD="slackpkg"
 		;;
-	SUSE|SLED|SLES)
+	SUSE|SLED|SLES|Tumbleweed)
 		CMD="zypper-rpm"
 		;;
 	ForesightLinux|rPathLinux)
@@ -507,20 +514,57 @@ is_active_systemd()
 	[ -x "$SYSTEMCTL" ] || return
 	[ -d "$SYSTEMD_CGROUP_DIR" ] || return
 	a= mountpoint -q "$SYSTEMD_CGROUP_DIR" || return
+	readlink /sbin/init | grep -q 'systemd' || return
 	# some hack
-	ps ax | grep -q '[s]ystemd' >/dev/null
+	ps ax | grep '[s]ystemd' | grep -q -v 'systemd-udev'
 }
 
 # File bin/epm-addrepo:
 
 epm_addrepo()
 {
-local repo="$(eval echo $quoted_args)"
-case $PMTYPE in
-	apt-rpm)
+local repo="$(eval echo "$quoted_args")"
+
+case $DISTRNAME in
+	ALTLinux)
+		case "$repo" in
+			etersoft)
+				info "add etersoft repo"
+				epm install --skip-installed apt-conf-etersoft-common apt-conf-etersoft-hold || fatal
+				local branch="$DISTRVERSION/branch"
+				[ "$DISTRVERSION" = "Sisyphus" ] && branch="$DISTRVERSION"
+				# FIXME
+				[ -n "$DISTRVERSION" ] || fatal "Empty DISTRVERSION"
+				local arch=$(uname -m)
+				[ "$arch" = "i686" ] && arch="i586"
+				echo "" | sudocmd tee -a /etc/apt/sources.list
+				echo "# added with eepm addrepo etersoft" | sudocmd tee -a /etc/apt/sources.list
+				echo "rpm [etersoft] http://download.etersoft.ru/pub/Etersoft LINUX@Etersoft/$branch/$arch addon" | sudocmd tee -a /etc/apt/sources.list
+				if [ "$arch" = "x86_64" ] ; then
+					echo "rpm [etersoft] http://download.etersoft.ru/pub/Etersoft LINUX@Etersoft/$branch/$arch-i586 addon" | sudocmd tee -a /etc/apt/sources.list
+				fi
+				echo "rpm [etersoft] http://download.etersoft.ru/pub/Etersoft LINUX@Etersoft/$branch/noarch addon" | sudocmd tee -a /etc/apt/sources.list
+				repo="$DISTRVERSION"
+				return 0
+				;;
+			autoimports)
+				[ -n "$DISTRVERSION" ] || fatal "Empty DISTRVERSION"
+				repo="$repo.$(echo "$DISTRVERSION" | tr "[A-Z]" "[a-z]")"
+		esac
+
 		assure_exists apt-repo
+		if [ -z "$repo" ] ; then
+			docmd apt-repo add branch
+			echo "etersoft"
+			return
+		fi
 		sudocmd apt-repo add "$repo"
+		return
 		;;
+esac
+
+
+case $PMTYPE in
 	apt-dpkg|aptitude-dpkg)
 		info "You need manually add repo to /etc/apt/sources.list"
 		;;
@@ -708,13 +752,14 @@ case $PMTYPE in
 	#	;;
 	yum-rpm)
 		showcmd package-cleanup --orphans
-		local PKGLIST=$(package-cleanup --orphans | grep -v "^eepm$")
+		local PKGLIST=$(package-cleanup -q --orphans | grep -v "^eepm-")
 		docmd epm remove $PKGLIST
 		;;
 	dnf-rpm)
 		# TODO: dnf list extras
+		# TODO: Yum-utils package has been deprecated, use dnf instead.
 		showcmd package-cleanup --orphans
-		local PKGLIST=$(package-cleanup --orphans | grep -v "^eepm$")
+		local PKGLIST=$(package-cleanup -q --orphans | grep -v "^eepm-")
 		docmd epm remove $PKGLIST
 		;;
 	urpm-rpm)
@@ -760,44 +805,75 @@ esac
 
 # File bin/epm-autoremove:
 
-__epm_autoremove_altrpm()
+__epm_autoremove_altrpm_pp()
 {
-	local pkg
-	assure_exists /etc/buildreqs/files/ignore.d/apt-scripts apt-scripts
+	local pkgs
+
+	info "Removing unused python/perl modules..."
+	#[ -n "$force" ] || info "You can run with --force for more deep removing"
+	local force=force
+
+	local flag=
+	[ -n "$force" ] || libexclude=$libexclude'[^-]*$'
+
+	libexclude='^(python-module-|python3-module-|python-modules-|python3-modules|perl-)'
+	[ -n "$force" ] || libexclude=$libexclude'[^-]*$'
+	showcmd "apt-cache list-nodeps | grep -E -- \"$libexclude\""
+	pkgs=$(apt-cache list-nodeps | grep -E -- "$libexclude" )
+	[ -n "$pkgs" ] && sudocmd rpm -v -e $pkgs && flag=1
+
+	if [ -n "$flag" ] ; then
+		info ""
+		info "call again for next cycle until all modules will be removed"
+		__epm_autoremove_altrpm_pp
+	fi
+
+	return 0
+}
+
+__epm_autoremove_altrpm_lib()
+{
+	local pkgs
+
 	info
 	info "Removing all non -devel/-debuginfo libs packages not need by anything..."
 	#[ -n "$force" ] || info "You can run with --force for more deep removing"
 	local force=force
 
 	local flag=
-	local libexclude='^lib'
+	local libexclude='^(lib|i586-lib)'
 	[ -n "$force" ] || libexclude=$libexclude'[^-]*$'
 
 	# https://www.altlinux.org/APT_в_ALT_Linux/Советы_по_использованию#apt-cache_list-nodeps
 	showcmd "apt-cache list-nodeps | grep -- \"$libexclude\""
-	pkgs=$(apt-cache list-nodeps | grep -- "$libexclude" \
-		| grep -E -v -- "-(devel|debuginfo)$" \
+	pkgs=$(apt-cache list-nodeps | grep -E -- "$libexclude" \
+		| sed -e "s/[-\.]32bit$//g" \
+		| grep -E -v -- "-(devel|devel-static|debuginfo)$" \
 		| grep -E -v -- "-(util|utils|tool|tools|plugin|daemon|help)$" \
-		| sed -e "s/\.32bit$//g" \
-		| grep -E -v -- "^(libsystemd|libreoffice|libnss|libvirt-client|libvirt-daemon|eepm)" )
-	[ -n "$pkgs" ] && sudocmd rpm -v -e $pkgs && flag=1
-
-	info "Removing unused python/perl modules..."
-	libexclude='^(python-module-|python3-module-|python-modules-|python3-modules|perl-)'
-	[ -n "$force" ] || libexclude=$libexclude'[^-]*$'
-	showcmd "apt-cache list-nodeps | grep -E -- \"$libexclude\""
-	pkgs=$(apt-cache list-nodeps | grep -E -- "$libexclude" )
+		| grep -E -v -- "^(libsystemd|libreoffice|libnss|libvirt-client|libvirt-daemon|libsasl2-plugin|eepm)" )
 	[ -n "$pkgs" ] && sudocmd rpm -v -e $pkgs && flag=1
 
 	if [ -n "$flag" ] ; then
 		info ""
 		info "call again for next cycle until all libs will be removed"
-		__epm_autoremove_altrpm
+		__epm_autoremove_altrpm_lib
 	fi
 
 	return 0
 }
 
+
+__epm_autoremove_altrpm()
+{
+	local pkg
+	assure_exists /etc/buildreqs/files/ignore.d/apt-scripts apt-scripts
+
+	__epm_autoremove_altrpm_pp
+	__epm_autoremove_altrpm_lib
+
+	return 0
+}
+
 epm_autoremove()
 {
 
@@ -830,7 +906,7 @@ case $PMTYPE in
 		while true ; do
 			docmd package-cleanup --leaves $(subst_option non_interactive --assumeyes)
 			# FIXME: package-cleanup have to use stderr for errors
-			local PKGLIST=$(package-cleanup --leaves | grep -v "Loaded plugins" | grep -v "Unable to" | grep -v "^eepm$")
+			local PKGLIST=$(package-cleanup -q --leaves | grep -v "^eepm-")
 			[ -n "$PKGLIST" ] || break
 			sudocmd yum remove $PKGLIST
 		done
@@ -1093,16 +1169,31 @@ esac
 epm_checkpkg()
 {
 	if [ -n "$pkg_names" ] ; then
+		# TODO: если есть / или расширение, это отсутствующий файл
 		info "Suggest $pkg_names are name(s) of installed packages"
 		__epm_check_installed_pkg $pkg_names
 		return
 	fi
 
+	# if possible, it will put pkg_urls into pkg_files or pkg_names
+	if [ -n "$pkg_urls" ] ; then
+		__handle_pkg_urls_to_checking
+	fi
+
 	[ -n "$pkg_files" ] || fatal "Checkpkg: missing file or package name(s)"
+
+	local RETVAL=0
+
 	local pkg
 	for pkg in $pkg_files ; do
-		check_pkg_integrity $pkg || fatal "Broken package $pkg"
+		check_pkg_integrity $pkg || RETVAL=1
 	done
+
+	# TODO: reinvent
+	[ -n "$to_remove_pkg_files" ] && rm -fv $to_remove_pkg_files
+
+	#fatal "Broken package $pkg"
+	return $RETVAL
 }
 
 # File bin/epm-checksystem:
@@ -1166,15 +1257,15 @@ __is_repo_info_downloaded()
 __is_repo_info_uptodate()
 {
     case $PMTYPE in
-        apt-rpm)
+        apt-*)
             # apt-deb do not update lock file date
-            if $SUDO test -r /var/lib/apt/lists ; then
-                local LOCKFILE=/var/lib/apt/lists/lock
+            #if $SUDO test -r /var/lib/apt/lists ; then
+                local LOCKFILE=/var/lib/apt/lists
                 $SUDO test -r $LOCKFILE || return
                 # if repo older than 1 day, return false
                 # find print string if file is obsoleted
-                test -z "$($SUDO find $LOCKFILE -mtime +1)" || return
-            fi
+                test -z "$(find $LOCKFILE -maxdepth 0 -mtime +1)" || return
+            #fi
             ;;
         *)
             ;;
@@ -1429,10 +1520,18 @@ epm_downgrade()
 		;;
 	yum-rpm)
 		# can do update repobase automagically
-		sudocmd yum downgrade $pkg_filenames
+		if [ -n "$pkg_filenames" ] ; then
+			sudocmd yum downgrade $pkg_filenames
+		else
+			sudocmd yum distro-sync
+		fi
 		;;
 	dnf-rpm)
-		sudocmd dnf downgrade $pkg_filenames
+		if [ -n "$pkg_filenames" ] ; then
+			sudocmd dnf downgrade $pkg_filenames
+		else
+			sudocmd dnf distro-sync
+		fi
 		;;
 	urpm-rpm)
 		assure_exists urpm-reposync urpm-tools
@@ -1446,10 +1545,121 @@ epm_downgrade()
 
 # File bin/epm-download:
 
+__use_url_install()
+{
+	case $DISTRNAME in
+		"ALTLinux")
+			# not for https
+			echo "$pkg_urls" | grep -q "https://" && return 1
+			pkg_names="$pkg_names $pkg_urls"
+			return 0
+			;;
+	esac
+
+	case $PMTYPE in
+		#apt-rpm)
+		#	pkg_names="$pkg_names $pkg_urls"
+		#	;;
+		#deepsolver-rpm)
+		#	pkg_names="$pkg_names $pkg_urls"
+		#	;;
+		#urpm-rpm)
+		#	pkg_names="$pkg_names $pkg_urls"
+		#	;;
+		pacman)
+			pkg_names="$pkg_names $pkg_urls"
+			;;
+		yum-rpm|dnf-rpm)
+			pkg_names="$pkg_names $pkg_urls"
+			;;
+		#zypper-rpm)
+		#	pkg_names="$pkg_names $pkg_urls"
+		#	;;
+		*)
+			return 1
+			;;
+	esac
+	return 0
+}
+
+__download_pkg_urls()
+{
+	local url
+	[ -z "$pkg_urls" ] && return
+	for url in $pkg_urls ; do
+		# TODO: use some individual tmp dir
+		local new_file=/tmp/$(basename "$url")
+		if docmd eget -O $new_file $url && [ -s "$new_file" ] ; then
+			pkg_files="$pkg_files $new_file"
+			to_remove_pkg_files="$to_remove_pkg_files $new_file"
+		else
+			warning "Failed to download $url, ignoring"
+		fi
+	done
+	# restore
+	pkg_filenames=$(strip_spaces "$pkg_files $pkg_names")
+}
+
+__handle_pkg_urls_to_install()
+{
+	#[ -n "$pkg_urls" ] || return
+
+	# TODO: do it correctly
+	to_remove_pkg_files=
+	# FIXME: check type of pkg_urls separately?
+	if [ "$(get_package_type "$pkg_urls")" != $PKGFORMAT ] || ! __use_url_install ; then
+		# use workaround with eget: download and put in pkg_files
+		__download_pkg_urls
+	fi
+
+	pkg_urls=
+}
+
+__handle_pkg_urls_to_checking()
+{
+	#[ -n "$pkg_urls" ] || return
+
+	# TODO: do it correctly
+	to_remove_pkg_files=
+	
+	# use workaround with eget: download and put in pkg_files
+	__download_pkg_urls
+
+	pkg_urls=
+}
+
+
+__epm_get_altpkg_url()
+{
+	info "TODO: https://packages.altlinux.org/api/branches"
+	local arch=$(paoapi packages/$1 | get_pao_var arch)
+	# FIXME: arch can be list
+	[ "$arch" = "noarch" ] || arch=$(arch)
+	# HACK: filename can be list
+	local filename=$(paoapi packages/$1 | get_pao_var filename | grep $arch)
+	[ -n "$filename" ] || fatal "Can't get filename"
+	# fixme: get from /branches
+	local dv=$DISTRNAME/$DISTRVERSION/branch
+	[ "$DISTRVERSION" = "Sisyphus" ] && dv=$DISTRNAME/$DISTRVERSION
+	echo "http://ftp.basealt.ru/pub/distributions/$dv/$arch/RPMS.classic/$filename"
+}
+
 epm_download()
 {
 	local CMD
 
+	case $DISTRNAME in
+		ALTLinux)
+			local pkg
+			for pkg in $pkg_filenames ; do
+				local url=$(__epm_get_altpkg_url $pkg)
+				[ -n "$url" ] || warning "Can't get url for $pkg"
+				docmd eget $url
+			done
+			return
+			;;
+	esac
+
 	case $PMTYPE in
 	dnf-rpm)
 		sudocmd dnf download $pkg_filenames
@@ -1465,6 +1675,9 @@ epm_download()
 	dnf-rpm)
 		sudocmd dnf download $pkg_filenames
 		;;
+	urpm-rpm)
+		sudocmd urpmi --no-install $URPMOPTIONS $@
+		;;
 	tce)
 		sudocmd tce-load -w $pkg_filenames
 		;;
@@ -1503,7 +1716,7 @@ __alt_local_content_filelist()
 
     {
         [ -n "$USETTY" ] && info "Search in $CI for $1..."
-        grep -h -- ".*$1$" $CI | sed -e "s|\(.*\)\t\(.*\)|\1|g"
+        __local_ercat $CI | grep -h -- ".*$1$" | sed -e "s|\(.*\)\t\(.*\)|\1|g"
     } | $OUTCMD
 }
 
@@ -1530,7 +1743,7 @@ __epm_filelist_remote()
 			docmd_foreach __deb_local_content_filelist $@
 			;;
 		*)
-			fatal "Query filelist for non installed packages does not realized"
+			fatal "Query filelist for non installed packages is not implemented yet."
 			;;
 	esac
 }
@@ -1600,7 +1813,7 @@ __epm_filelist_name()
 			return
 			;;
 		slackpkg)
-			is_installed $@ || fatal "Query filelist for non installed packages does not realized"
+			is_installed $@ || fatal "Query filelist for non installed packages is not implemented yet"
 			docmd awk 'BEGIN{desk=1}{if(/^FILE LIST:$/){desk=0} else if (desk==0) {print}}' /var/log/packages/${pkg_filenames}* | less
 			return
 			;;
@@ -1641,6 +1854,10 @@ __epm_info_rpm_low()
 epm_info()
 {
 
+if [ -n "$pkg_urls" ] ; then
+    __handle_pkg_urls_to_checking
+fi
+
 [ -n "$pkg_filenames" ] || fatal "Info: missing package(s) name"
 
 case $PMTYPE in
@@ -1725,6 +1942,11 @@ case $PMTYPE in
 		;;
 esac
 
+local RETVAL=$?
+
+[ -n "$to_remove_pkg_files" ] && rm -fv $to_remove_pkg_files
+
+return $RETVAL
 }
 
 # File bin/epm-install:
@@ -2013,7 +2235,6 @@ __epm_check_if_try_install_rpm()
 	cd $TDIR
 	for pkg in $rpmpkgs ; do
 		showcmd_store_output fakeroot alien -d -k --scripts "$pkg"
-		clean_store_output
 		local DEBCONVERTED=$(grep "deb generated" $RC_STDOUT | sed -e "s| generated||g")
 		clean_store_output
 		epm install $DEBCONVERTED
@@ -2024,6 +2245,22 @@ __epm_check_if_try_install_rpm()
 	return 0
 }
 
+__handle_direct_install()
+{
+    case "$DISTRNAME" in
+        "ALTLinux")
+            local pkg url
+            for pkg in $pkg_names ; do
+                url=$(__epm_get_altpkg_url $pkg)
+                [ -n "$url" ] || continue
+                # TODO: use estrlist
+                pkg_urls="$pkg_urls $url"
+            done
+            # FIXME: need remove
+            pkg_names=""
+            ;;
+    esac
+}
 
 epm_install_files()
 {
@@ -2206,64 +2443,6 @@ epm_print_install_command()
     esac
 }
 
-download_pkg_urls()
-{
-	local url
-	[ -z "$pkg_urls" ] && return
-	for url in $pkg_urls ; do
-		# TODO: use some individual tmp dir
-		local new_file=/tmp/$(basename "$url")
-		if eget -O $new_file $url && [ -s "$new_file" ] ; then
-			pkg_files="$pkg_files $new_file"
-			to_remove_pkg_files="$to_remove_pkg_files $new_file"
-		else
-			warning "Failed to download $url, ignoring"
-		fi
-	done
-}
-
-__use_url_install()
-{
-	case $PMTYPE in
-		apt-rpm)
-			# ALT Linux really?
-			pkg_names="$pkg_names $pkg_urls"
-			;;
-		#deepsolver-rpm)
-		#	pkg_names="$pkg_names $pkg_urls"
-		#	;;
-		#urpm-rpm)
-		#	pkg_names="$pkg_names $pkg_urls"
-		#	;;
-		pacman)
-			pkg_names="$pkg_names $pkg_urls"
-			;;
-		yum-rpm|dnf-rpm)
-			pkg_names="$pkg_names $pkg_urls"
-			;;
-		#zypper-rpm)
-		#	pkg_names="$pkg_names $pkg_urls"
-		#	;;
-		*)
-			return 1
-			;;
-	esac
-	return 0
-}
-
-__handle_pkg_urls()
-{
-	[ -n "$pkg_urls" ] || return
-
-	# TODO: do it correctly
-	to_remove_pkg_files=
-	
-	if [ "$(get_package_type "$pkg")" != $PKGFORMAT ] || ! __use_url_install ; then
-		# use workaround with eget: download and put in pkg_files
-		download_pkg_urls
-	fi
-	pkg_urls=
-}
 
 epm_install()
 {
@@ -2272,8 +2451,14 @@ epm_install()
         return
     fi
 
-    # in any case it will put pkg_urls into pkg_files or pkg_names
-    __handle_pkg_urls
+    if [ -n "$direct" ] ; then
+        __handle_direct_install
+    fi
+
+    # if possible, it will put pkg_urls into pkg_files or pkg_names
+    if [ -n "$pkg_urls" ] ; then
+        __handle_pkg_urls_to_install
+    fi
 
     [ -z "$pkg_files$pkg_names" ] && info "Skip empty install list" && return 22
 
@@ -2282,17 +2467,18 @@ epm_install()
 
     [ -z "$files$names" ] && info "Skip empty install list" && return 22
 
-    if [ -z "$files" ] ; then
+    if [ -z "$files" ] && [ -z "$direct" ] ; then
         # it is useful for first time running
         update_repo_if_needed
     fi
 
     epm_install_names $names || return
     epm_install_files $files
+    local RETVAL=$?
 
     # TODO: reinvent
-    local RETVAL=$?
     [ -n "$to_remove_pkg_files" ] && rm -fv $to_remove_pkg_files
+
     return $RETVAL
 }
 
@@ -2465,7 +2651,7 @@ case $PMTYPE in
 		docmd dpkg-query -W --showformat="\${Size}.\${Package}-\${Version}\n" $pkg_filenames | sort -n
 		;;
 	*)
-		fatal "Sorted package list are not realized for $PMTYPE"
+		fatal "Sorted package list function is not implemented for $PMTYPE"
 		;;
 esac
 }
@@ -2620,6 +2806,8 @@ epm_policy()
 
 [ -n "$pkg_names" ] || fatal "Info: missing package(s) name"
 
+pkg_names=$(__epm_get_hilevel_name $pkg_names)
+
 case $PMTYPE in
 	apt-rpm)
 		docmd apt-cache policy $pkg_names
@@ -3023,11 +3211,11 @@ __epm_get_hilevel_nameform()
 			echo $pkg
 			return
 			;;
-		yum-rpm)
+		yum-rpm|dnf-rpm)
 			# just use strict version with Epoch and Serial
 			local pkg
-			pkg=$(rpm -q --queryformat "%{EPOCH}:%{NAME}%{VERSION}-%{RELEASE}.${ARCH}\n" $1)
-			echo $pkg | grep -q "(none)" && pkg=$(rpm -q --queryformat "%{NAME}-%{VERSION}-%{RELEASE}.${ARCH}\n" $1)
+			pkg=$(rpm -q --queryformat "%{EPOCH}:%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n" $1)
+			echo $pkg | grep -q "(none)" && pkg=$(rpm -q --queryformat "%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n" $1)
 			echo $pkg
 			return
 			;;
@@ -3200,13 +3388,26 @@ epm_query()
 # File bin/epm-query_file:
 
 
+__abs_filename()
+{
+	if echo "$1" | grep -q "/" ; then
+		echo "$1"
+		return
+	fi
+	if [ -e "$1" ] ; then
+		echo "$(pwd)/$1"
+		return
+	fi
+	echo "$1"
+}
+
 __do_query_real_file()
 {
 	local TOFILE
 	
 	# get canonical path
 	if [ -e "$1" ] ; then
-		TOFILE="$1"
+		TOFILE="$(__abs_filename "$1")"
 	else
 		TOFILE=$(which "$1" 2>/dev/null || echo "$1")
 		if [ "$TOFILE" != "$1" ] ; then
@@ -3285,7 +3486,7 @@ __do_query()
             ;;
         aptcyg)
             #CMD="apt-cyg packageof"
-            # do not realized locally
+            # is not implemented locally
             return 1
             ;;
         *)
@@ -3386,6 +3587,9 @@ epm_reinstall_names()
 		aptitude-dpkg)
 			sudocmd aptitude reinstall $@
 			return ;;
+		yum-rpm)
+			sudocmd yum reinstall $@
+			return ;;
 		dnf-rpm)
 			sudocmd dnf reinstall $@
 			return ;;
@@ -3535,7 +3739,7 @@ __update_to_the_distro()
 			;;
 		Sisyphus)
 			docmd epm update || fatal
-			docmd epm install apt rpm apt-conf-sisyphus altlinux-release-sisyphus || fatal "Check an error and run again"
+			docmd epm install apt rpm librpm7 librpm apt-conf-sisyphus altlinux-release-sisyphus || fatal "Check an error and run again"
 			docmd epm upgrade || fatal "Check an error and run epm release-upgrade again"
 			;;
 		*)
@@ -3650,9 +3854,11 @@ epm_release_upgrade()
 		assure_exists dnf-plugin-system-upgrade
 		sudocmd dnf system-upgrade
 		local RELEASEVER="$pkg_filenames"
-		[ -n "$RELEASEVER" ] || fatal "Run me with new version"
+		[ -n "$RELEASEVER" ] || RELEASEVER=$(($DISTRVERSION + 1))
+		#[ -n "$RELEASEVER" ] || fatal "Run me with new version"
+		info "Upgrate to $DISTRNAME/$RELEASEVER"
 		sudocmd dnf system-upgrade download --refresh --releasever=$RELEASEVER
-		sudocmd dnf system-upgrade
+		sudocmd dnf distro-sync --releasever=$RELEASEVER
 		info "Run epm autoorphans to remove orphaned packages"
 		;;
 	urpm-rpm)
@@ -3972,11 +4178,24 @@ epm_remove_old_kernels()
 epm_removerepo()
 {
 local repo="$(eval echo $quoted_args)"
-case $PMTYPE in
-	apt-rpm)
+
+case $DISTRNAME in
+	ALTLinux)
+		case "$repo" in
+			autoimports)
+				info "remove autoimports repo"
+				[ -n "$DISTRVERSION" ] || fatal "Empty DISTRVERSION"
+				repo="$repo.$(echo "$DISTRVERSION" | tr "[A-Z]" "[a-z]")"
+				;;
+		esac
+
 		assure_exists apt-repo
 		sudocmd apt-repo rm "$repo"
+		return
 		;;
+esac;
+
+case $PMTYPE in
 	apt-dpkg|aptitude-dpkg)
 		info "You need remove repo from /etc/apt/sources.list"
 		;;
@@ -4022,8 +4241,24 @@ __repofix_check_vendor()
 	return 1
 }
 
+__try_fix_apt_source_list()
+{
+	local list="$1"
+	local br="$2"
+	local path="$3"
+	if grep -q -e "^[^#].*$path" $list ; then
+		if __repofix_check_vendor $br ; then
+			regexp_subst "/$path/s/^rpm[[:space:]]*([fhr])/rpm [$br] \1/" $list
+		else
+			warning "Skip set $br vendor key (it misssed) for $list"
+			regexp_subst "/$path/s/^rpm[[:space:]]*\[$br\][[:space:]]*([fhr])/rpm \1/" $list
+		fi
+	fi
+}
+
 __fix_apt_sources_list()
 {
+	# for beauty spaces
 	local SUBST_ALT_RULE='s!^(.*)[/ ](ALTLinux|LINUX\@Etersoft)[/ ](Sisyphus|p8[/ ]branch|p7[/ ]branch|p6[/ ]branch)[/ ](x86_64|i586|x86_64-i586|noarch) !\1 \2/\3/\4 !gi'
 	local i
 	assure_root
@@ -4035,33 +4270,14 @@ __fix_apt_sources_list()
 		regexp_subst "/^ *#/! $SUBST_ALT_RULE" $i
 
 		# Sisyphus uses 'alt' vendor key
-		if __repofix_check_vendor alt ; then
-			regexp_subst "/ALTLinux\/Sisyphus\//s/^rpm *([fhr])/rpm [alt] \1/" $i
-		else
-			warning "Skip set alt vendor key (it misssed)"
-		fi
+		__try_fix_apt_source_list $i alt "ALTLinux\/Sisyphus"
 
 		# skip branch replacement for ALT Linux Sisyphus
 		[ "$DISTRVERSION" = "Sisyphus" ] && continue
 
 		# add signs for branches
-		local br
-		for br in $DISTRVERSION ; do
-			if ! __repofix_check_vendor $br ; then
-				warning "Skip set $br vendor key (it misssed)"
-				continue
-			fi
-			regexp_subst "/ALTLinux\/$br\/branch/s/^rpm *([fhr])/rpm [$br] \1/" $i
-		done
-
-		for br in $DISTRVERSION ; do
-			#if is_installed apt-conf-etersoft-common ; then
-			if ! __repofix_check_vendor etersoft ; then
-				warning "Skip set etersoft vendor key (it misssed)"
-				continue
-			fi
-			regexp_subst "/Etersoft\/$br\/branch/s/^rpm *([fhr])/rpm [etersoft] \1/" $i
-		done
+		__try_fix_apt_source_list $i $DISTRVERSION "ALTLinux\/$DISTRVERSION\/branch"
+		__try_fix_apt_source_list $i etersoft "Etersoft\/$DISTRVERSION\/branch"
 	done
 }
 
@@ -4125,7 +4341,7 @@ case $PMTYPE in
 		print_apt_sources_list /etc/apt/sources.list /etc/apt/sources.list.d/*.list
 		;;
 	yum-rpm)
-		docmd yum repolist
+		docmd yum repolist -v
 		;;
 	dnf-rpm)
 		docmd dnf repolist -v
@@ -4435,20 +4651,30 @@ epm_search()
 
 # File bin/epm-search_file:
 
+
+__alt_search_file_output()
+{
+    # grep only on left part (filename), then revert order and grep with color
+    __local_ercat $1 | grep -h -- ".*$2.*[[:space:]]" | sed -e "s|\(.*\)\t\(.*\)|\2: \1|g" $3
+}
+
 __alt_local_content_search()
 {
 
+    info "Locate contents index file(s) ..."
     local CI="$(get_local_alt_contents_index)"
+    # TODO use something like
     [ -n "$CI" ] || fatal "Have no local contents index"
-    #local OUTCMD="less"
-    #[ -n "$USETTY" ] || OUTCMD="cat"
-    OUTCMD="cat"
 
-    {
-        [ -n "$USETTY" ] && info "Search in $CI for $1..."
-        # note! tabulation below!
-        grep -h -- ".*$1.*	" $CI | sed -e "s|\(.*\)\t\(.*\)|\2: \1|g"
-    } | $OUTCMD
+    info "Searching in"
+    echo "$CI"
+    echo "for $1... "
+
+    # FIXME: do it better
+    local MGS
+    MGS=$(eval __epm_search_make_grep $quoted_args)
+    showcmd "$ cat contents_index $MGS"
+    eval "__alt_search_file_output \"$CI\" \"$(eval get_firstarg $quoted_args)\" $MGS"
 }
 
 epm_search_file()
@@ -4467,12 +4693,12 @@ case $PMTYPE in
 		return ;;
 	yum-rpm)
 		# TODO
-		info "Search by full packages list does not realized"
+		info "Search by full packages list is not implemented yet"
 		CMD="yum provides"
 		;;
 	dnf-rpm)
 		# TODO
-		info "Search by full packages list does not realized"
+		info "Search by full packages list is not implemented yet"
 		CMD="dnf provides"
 		;;
 	urpm-rpm)
@@ -4508,18 +4734,90 @@ docmd $CMD $pkg_filenames
 
 # File bin/epm-sh-altlinux:
 
+
+get_local_alt_mirror_path()
+{
+    local DN1=$(dirname "$1")
+    local DN2=$(dirname $DN1)
+    local DN3=$(dirname $DN2)
+
+    local BN0=$(basename "$1") # arch
+    local BN1=$(basename $DN1) # branch/Sisyphus
+    local BN2=$(basename $DN2) # p8/ALTLinux
+    local BN3=$(basename $DN3) # ALTLinux/
+
+    [ "$BN1" = "branch" ] && echo "/tmp/eepm/$BN3/$BN2/$BN1/$BN0" || echo "/tmp/eepm/$BN2/$BN1/$BN0"
+}
+
+__local_ercat()
+{
+   local i
+   for i in $* ; do
+       case "$i" in
+           *.xz)
+               a= xzcat $i
+               ;;
+           *.lz4)
+               a= lz4cat $i
+               ;;
+           *.failed)
+               # just ignore
+               ;;
+           *)
+               cat $i
+               ;;
+       esac
+   done
+}
+
+compress_file_inplace()
+{
+    local OFILE="$1"
+    if epm assure lz4 </dev/null ; then
+        docmd lz4 --rm "$OFILE" "$OFILE.lz4" || return
+    else
+        epm assure xz </dev/null || return
+        docmd xz "$OFILE" || return
+    fi
+    return 0
+}
+
+download_alt_contents_index()
+{
+    local URL="$1"
+    local TD="$2"
+    local OFILE="$TD/$(basename "$URL")"
+
+    local DONE=$(echo $OFILE*)
+    # TODO: check if too old
+    if [ -r "$DONE" ] ; then
+        return
+    fi
+
+    mkdir -p "$TD"
+
+    if echo "$URL" | grep -q "^file:/" ; then
+        URL=$(echo "$URL" | sed -e "s|^file:||")
+        [ -s "$URL" ] || { touch $OFILE.failed ; return 1; }
+        ln -s "$URL" "$OFILE" || { touch $OFILE.failed ; return 1; }
+    else
+        docmd eget -O "$OFILE" "$URL" || { rm -fv $OFILE ; touch $OFILE.failed ; return 1; }
+    fi
+
+    compress_file_inplace "$OFILE"
+}
+
 get_local_alt_contents_index()
 {
 
-    epm_repolist | grep "rpm.*file:/" | sed -e "s|^rpm.*file:||g" | while read URL ARCH other ; do
-        test -d "$URL/$ARCH" || continue # fatal "Local mirror is not accessible via $URL/$ARCH"
-        FILE="$URL/$ARCH/base/contents_index"
-        if [ -r "$FILE" ] ; then
-            echo "$FILE"
-        else
-            info "TODO for girar server: There is no $(basename $FILE) file in $(dirname $FILE)"
-        fi
+    local LOCALPATH
+
+    epm_repolist | grep -E "rpm.*(ftp://|http://|https://|file:/)" | sed -e "s@^rpm.*\(ftp://\|http://\|https://\|file:\)@\1@g" | while read URL ARCH other ; do
+        LOCALPATH=$(get_local_alt_mirror_path "$URL/$ARCH")
+        download_alt_contents_index $URL/$ARCH/base/contents_index $LOCALPATH || continue
+        echo "$LOCALPATH/contents_index*"
     done
+
 }
 
 # File bin/epm-simulate:
@@ -4660,6 +4958,23 @@ epm_simulate()
 
 PAOURL="https://packages.altlinux.org"
 
+paoapi()
+{
+	# http://petstore.swagger.io/?url=http://packages.altlinux.org/api/docs
+	epm assure curl || return 1
+	showcmd curl "$PAOURL/api/$1"
+	a= curl -s --header "Accept: application/json" "$PAOURL/api/$1"
+}
+
+get_pao_var()
+{
+	local FIELD="$1"
+	#grep '"$FIELD"' | sed -e 's|.*"$FIELD":"||g' | sed -e 's|".*||g'
+	internal_tools_json -b | egrep "\[.*\"$FIELD\"\]" | sed -e 's|.*[[:space:]]"\(.*\)"|\1|g'
+	return 0
+}
+
+
 run_command_if_exists()
 {
 	local CMD="$1"
@@ -4681,14 +4996,9 @@ open_browser()
 
 __query_package_hl_url()
 {
-	local PAOAPI="$PAOURL/api"
 	case $DISTRNAME in
 		ALTLinux)
-			# http://petstore.swagger.io/?url=http://packages.altlinux.org/api/docs
-			epm assure curl || return 1
-			showcmd curl "$PAOAPI/srpms/$1"
-			a= curl -s --header "Accept: application/json" "$PAOAPI/srpms/$1" | grep '"url"' | sed -e 's|.*"url":"||g' | sed -e 's|".*||g'
-			return 0
+			paoapi srpms/$1 | get_pao_var url
 			;;
 	esac
 	return 1
@@ -4857,7 +5167,7 @@ epm_upgrade()
 {
 	local CMD
 
-	[ -z "$pkg_filenames" ] || fatal "No arguments are allowed here"
+	#[ -z "$pkg_filenames" ] || fatal "No arguments are allowed here"
 
 	# it is useful for first time running
 	update_repo_if_needed
@@ -4876,18 +5186,18 @@ epm_upgrade()
 	yum-rpm)
 		local OPTIONS="$(subst_option non_interactive -y)"
 		# can do update repobase automagically
-		CMD="yum $OPTIONS update"
+		CMD="yum $OPTIONS update $pkg_filenames"
 		;;
 	dnf-rpm)
 		local OPTIONS="$(subst_option non_interactive -y)"
-		CMD="dnf $OPTIONS distro-sync"
+		CMD="dnf $OPTIONS distro-sync $pkg_filenames"
 		;;
 	snappy)
 		CMD="snappy update"
 		;;
 	urpm-rpm)
 		# or --auto-select --replace-files
-		CMD="urpmi --update --auto-select"
+		CMD="urpmi --update --auto-select $pkg_filenames"
 		;;
 	zypper-rpm)
 		CMD="zypper dist-upgrade"
@@ -4961,6 +5271,7 @@ epm_Upgrade()
 # File bin/epm-whatdepends:
 
 
+
 epm_whatdepends()
 {
 	local CMD
@@ -4985,6 +5296,7 @@ case $PMTYPE in
 		CMD="urpmq --whatrequires"
 		;;
 	dnf-rpm)
+		# check command: dnf repoquery --whatrequires
 		CMD="repoquery --whatrequires"
 		;;
 	emerge)
@@ -5112,7 +5424,7 @@ pkgtype()
 		debian|ubuntu|mint|runtu|mcst|astra) echo "deb" ;;
 		alt|asplinux|suse|mandriva|rosa|mandrake|pclinux|sled|sles)
 			echo "rpm" ;;
-		fedora|redhat|scientific|centos|rhel)
+		fedora|redhat|scientific|centos|rhel|goslinux)
 			echo "rpm" ;;
 		*)  echo "rpm" ;;
 	esac
@@ -5120,8 +5432,8 @@ pkgtype()
 
 get_var()
 {
-	grep -i "^$1 *=" | head -n 1 | sed -e "s/^[^=]*[ \t]*=[ \t]*//"
-
+	# get first variable and print it out, drop quotes if exists
+	grep -i "^$1 *=" | head -n 1 | sed -e "s/^[^=]*[ \t]*=[ \t]*//" | sed -e "s/^[\'\"]\(.*\)[\'\"]/\1/"
 }
 
 # 2010.1 -> 2010
@@ -5148,6 +5460,7 @@ if distro altlinux-release ; then
 	if has Sisyphus ; then DISTRIB_RELEASE="Sisyphus"
 	elif has "ALT Linux 7." ; then DISTRIB_RELEASE="p7"
 	elif has "ALT Linux 8." ; then DISTRIB_RELEASE="p8"
+	elif has "ALT .*8.[0-9]" ; then DISTRIB_RELEASE="p8"
 	elif has "Simply Linux 6." ; then DISTRIB_RELEASE="p6"
 	elif has "Simply Linux 7." ; then DISTRIB_RELEASE="p7"
 	elif has "Simply Linux 8." ; then DISTRIB_RELEASE="p8"
@@ -5292,6 +5605,8 @@ elif distro redhat-release ; then
 		DISTRIB_ID="CentOS"
 	elif has Scientific ; then
 		DISTRIB_ID="Scientific"
+	elif has GosLinux ; then
+		DISTRIB_ID="GosLinux"
 	fi
 	if has Beryllium ; then
 		DISTRIB_ID="Scientific"
@@ -5349,7 +5664,13 @@ elif [ `uname -o 2>/dev/null` = "Cygwin" ] ; then
 # try use standart LSB info by default
 elif distro lsb-release && [ -n "$DISTRIB_RELEASE" ]; then
 	# use LSB
-	true
+
+	# fix distro name
+	case "$DISTRIB_ID" in
+		"openSUSE Tumbleweed")
+			DISTRIB_ID="Tumbleweed"
+			;;
+	esac
 fi
 
 case $1 in
@@ -5391,7 +5712,7 @@ case $1 in
 		exit 0
 		;;
 	-V)
-		echo "20160822"
+		echo "20161212"
 		exit 0
 		;;
 	*)
@@ -5447,7 +5768,7 @@ fi
 
 # If ftp protocol or have no asterisk, just download
 # TODO: use has()
-if echo "$1" | grep -q "\(^ftp://\|[^*]$\)" ; then
+if echo "$1" | grep -q "\(^ftp://\|[^*]\)" ; then
     $WGET $WGET_OPTION_TARGET "$1"
     return
 fi
@@ -5495,6 +5816,220 @@ download_files || echo "There was some download errors" >&2
 rm -rf "$MYTMPDIR"
 }
 
+internal_tools_json()
+{
+
+# License: MIT or Apache
+# Homepage: http://github.com/dominictarr/JSON.sh
+
+throw() {
+  echo "$*" >&2
+  exit 1
+}
+
+BRIEF=0
+LEAFONLY=0
+PRUNE=0
+NO_HEAD=0
+NORMALIZE_SOLIDUS=0
+
+usage() {
+  echo
+  echo "Usage: JSON.sh [-b] [-l] [-p] [-s] [-h]"
+  echo
+  echo "-p - Prune empty. Exclude fields with empty values."
+  echo "-l - Leaf only. Only show leaf nodes, which stops data duplication."
+  echo "-b - Brief. Combines 'Leaf only' and 'Prune empty' options."
+  echo "-n - No-head. Do not show nodes that have no path (lines that start with [])."
+  echo "-s - Remove escaping of the solidus symbol (straight slash)."
+  echo "-h - This help text."
+  echo
+}
+
+parse_options() {
+  set -- "$@"
+  local ARGN=$#
+  while [ "$ARGN" -ne 0 ]
+  do
+    case $1 in
+      -h) usage
+          exit 0
+      ;;
+      -b) BRIEF=1
+          LEAFONLY=1
+          PRUNE=1
+      ;;
+      -l) LEAFONLY=1
+      ;;
+      -p) PRUNE=1
+      ;;
+      -n) NO_HEAD=1
+      ;;
+      -s) NORMALIZE_SOLIDUS=1
+      ;;
+      ?*) echo "ERROR: Unknown option."
+          usage
+          exit 0
+      ;;
+    esac
+    shift 1
+    ARGN=$((ARGN-1))
+  done
+}
+
+awk_egrep () {
+  local pattern_string=$1
+
+  gawk '{
+    while ($0) {
+      start=match($0, pattern);
+      token=substr($0, start, RLENGTH);
+      print token;
+      $0=substr($0, start+RLENGTH);
+    }
+  }' pattern="$pattern_string"
+}
+
+tokenize () {
+  local GREP
+  local ESCAPE
+  local CHAR
+
+  if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1
+  then
+    GREP='egrep -ao --color=never'
+  else
+    GREP='egrep -ao'
+  fi
+
+  if echo "test string" | egrep -o "test" >/dev/null 2>&1
+  then
+    ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
+    CHAR='[^[:cntrl:]"\\]'
+  else
+    GREP=awk_egrep
+    ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
+    CHAR='[^[:cntrl:]"\\\\]'
+  fi
+
+  local STRING="\"$CHAR*($ESCAPE$CHAR*)*\""
+  local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
+  local KEYWORD='null|false|true'
+  local SPACE='[[:space:]]+'
+
+  # Force zsh to expand $A into multiple words
+  local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$')
+  if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi
+  $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$"
+  if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi
+}
+
+parse_array () {
+  local index=0
+  local ary=''
+  read -r token
+  case "$token" in
+    ']') ;;
+    *)
+      while :
+      do
+        parse_value "$1" "$index"
+        index=$((index+1))
+        ary="$ary""$value" 
+        read -r token
+        case "$token" in
+          ']') break ;;
+          ',') ary="$ary," ;;
+          *) throw "EXPECTED , or ] GOT ${token:-EOF}" ;;
+        esac
+        read -r token
+      done
+      ;;
+  esac
+  [ "$BRIEF" -eq 0 ] && value=$(printf '[%s]' "$ary") || value=
+  :
+}
+
+parse_object () {
+  local key
+  local obj=''
+  read -r token
+  case "$token" in
+    '}') ;;
+    *)
+      while :
+      do
+        case "$token" in
+          '"'*'"') key=$token ;;
+          *) throw "EXPECTED string GOT ${token:-EOF}" ;;
+        esac
+        read -r token
+        case "$token" in
+          ':') ;;
+          *) throw "EXPECTED : GOT ${token:-EOF}" ;;
+        esac
+        read -r token
+        parse_value "$1" "$key"
+        obj="$obj$key:$value"        
+        read -r token
+        case "$token" in
+          '}') break ;;
+          ',') obj="$obj," ;;
+          *) throw "EXPECTED , or } GOT ${token:-EOF}" ;;
+        esac
+        read -r token
+      done
+    ;;
+  esac
+  [ "$BRIEF" -eq 0 ] && value=$(printf '{%s}' "$obj") || value=
+  :
+}
+
+parse_value () {
+  local jpath="${1:+$1,}$2" isleaf=0 isempty=0 print=0
+  case "$token" in
+    '{') parse_object "$jpath" ;;
+    '[') parse_array  "$jpath" ;;
+    # At this point, the only valid single-character tokens are digits.
+    ''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;;
+    *) value=$token
+       # if asked, replace solidus ("\/") in json strings with normalized value: "/"
+       [ "$NORMALIZE_SOLIDUS" -eq 1 ] && value=$(echo "$value" | sed 's#\\/#/#g')
+       isleaf=1
+       [ "$value" = '""' ] && isempty=1
+       ;;
+  esac
+  [ "$value" = '' ] && return
+  [ "$NO_HEAD" -eq 1 ] && [ -z "$jpath" ] && return
+
+  [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 0 ] && print=1
+  [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && [ $PRUNE -eq 0 ] && print=1
+  [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 1 ] && [ "$isempty" -eq 0 ] && print=1
+  [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && \
+    [ $PRUNE -eq 1 ] && [ $isempty -eq 0 ] && print=1
+  [ "$print" -eq 1 ] && printf "[%s]\t%s\n" "$jpath" "$value"
+  :
+}
+
+parse () {
+  read -r token
+  parse_value
+  read -r token
+  case "$token" in
+    '') ;;
+    *) throw "EXPECTED EOF GOT $token" ;;
+  esac
+}
+
+if ([ "$0" = "$BASH_SOURCE" ] || ! [ -n "$BASH_SOURCE" ]);
+then
+  parse_options "$@"
+  tokenize | parse
+fi
+
+# vi: expandtab sw=2 ts=2
+}
+
 #PATH=$PATH:/sbin:/usr/sbin
 
 set_pm_type
@@ -5519,9 +6054,9 @@ $(get_help HELPOPT)
 
 print_version()
 {
-        echo "EPM package manager version 1.9.6"
+        echo "EPM package manager version 2.0.5"
         echo "Running on $($DISTRVENDOR) ('$PMTYPE' package manager uses '$PKGFORMAT' package format)"
-        echo "Copyright (c) Etersoft 2012-2016"
+        echo "Copyright (c) Etersoft 2012-2017"
         echo "This program may be freely redistributed under the terms of the GNU AGPLv3."
 }
 
@@ -5536,6 +6071,7 @@ nodeps=
 noremove=
 force=
 short=
+direct=
 sort=
 non_interactive=
 skip_installed=
@@ -5791,6 +6327,9 @@ check_option()
     --short)              # HELPOPT: short output (just 'package' instead 'package-version-release')
         short="--short"
         ;;
+    --direct)              # HELPOPT: direct install package file from ftp (not via hilevel repository manager)
+        direct="--direct"
+        ;;
     --sort)               # HELPOPT: sort output, f.i. --sort=size (supported only for packages command)
         # TODO: how to read arg?
         sort="$1"
@@ -5858,7 +6397,9 @@ pkg_filenames=$(strip_spaces "$pkg_files $pkg_names")
 if [ -z "$epm_cmd" ] ; then
     print_version
     echo
-    fatal "Unknown command $@. Run $ $PROGNAME --help for get help"
+    fatstr="Unknown command in $@ arg(s)"
+    [ -n "$*" ] || fatstr="That program needs be running with some command"
+    fatal "$fatstr. Run $ $PROGNAME --help to get help."
 fi
 
 # Use eatmydata for write specific operations
diff --git a/packed/serv.sh b/packed/serv.sh
index f0f4d963ab9a1624cacfe9f524ba1216d0bb3639..e03901b34831b941f287c325de312677a311b6ab 100755
--- a/packed/serv.sh
+++ b/packed/serv.sh
@@ -159,6 +159,13 @@ sudocmd_foreach()
 	done
 }
 
+if ! which realpath 2>/dev/null >/dev/null ; then
+realpath()
+{
+	readlink -f "$@"
+}
+fi
+
 get_firstarg()
 {
 	echon "$1"
@@ -444,14 +451,14 @@ case $DISTRNAME in
 	ArchLinux)
 		CMD="pacman"
 		;;
-	Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific)
+	Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific|GosLinux)
 		CMD="yum-rpm"
 		which dnf 2>/dev/null >/dev/null && test -d /var/lib/dnf/yumdb && CMD=dnf-rpm
 		;;
 	Slackware)
 		CMD="slackpkg"
 		;;
-	SUSE|SLED|SLES)
+	SUSE|SLED|SLES|Tumbleweed)
 		CMD="zypper-rpm"
 		;;
 	ForesightLinux|rPathLinux)
@@ -500,8 +507,9 @@ is_active_systemd()
 	[ -x "$SYSTEMCTL" ] || return
 	[ -d "$SYSTEMD_CGROUP_DIR" ] || return
 	a= mountpoint -q "$SYSTEMD_CGROUP_DIR" || return
+	readlink /sbin/init | grep -q 'systemd' || return
 	# some hack
-	ps ax | grep -q '[s]ystemd' >/dev/null
+	ps ax | grep '[s]ystemd' | grep -q -v 'systemd-udev'
 }
 
 # File bin/serv-common:
@@ -1056,7 +1064,7 @@ pkgtype()
 		debian|ubuntu|mint|runtu|mcst|astra) echo "deb" ;;
 		alt|asplinux|suse|mandriva|rosa|mandrake|pclinux|sled|sles)
 			echo "rpm" ;;
-		fedora|redhat|scientific|centos|rhel)
+		fedora|redhat|scientific|centos|rhel|goslinux)
 			echo "rpm" ;;
 		*)  echo "rpm" ;;
 	esac
@@ -1064,8 +1072,8 @@ pkgtype()
 
 get_var()
 {
-	grep -i "^$1 *=" | head -n 1 | sed -e "s/^[^=]*[ \t]*=[ \t]*//"
-
+	# get first variable and print it out, drop quotes if exists
+	grep -i "^$1 *=" | head -n 1 | sed -e "s/^[^=]*[ \t]*=[ \t]*//" | sed -e "s/^[\'\"]\(.*\)[\'\"]/\1/"
 }
 
 # 2010.1 -> 2010
@@ -1092,6 +1100,7 @@ if distro altlinux-release ; then
 	if has Sisyphus ; then DISTRIB_RELEASE="Sisyphus"
 	elif has "ALT Linux 7." ; then DISTRIB_RELEASE="p7"
 	elif has "ALT Linux 8." ; then DISTRIB_RELEASE="p8"
+	elif has "ALT .*8.[0-9]" ; then DISTRIB_RELEASE="p8"
 	elif has "Simply Linux 6." ; then DISTRIB_RELEASE="p6"
 	elif has "Simply Linux 7." ; then DISTRIB_RELEASE="p7"
 	elif has "Simply Linux 8." ; then DISTRIB_RELEASE="p8"
@@ -1236,6 +1245,8 @@ elif distro redhat-release ; then
 		DISTRIB_ID="CentOS"
 	elif has Scientific ; then
 		DISTRIB_ID="Scientific"
+	elif has GosLinux ; then
+		DISTRIB_ID="GosLinux"
 	fi
 	if has Beryllium ; then
 		DISTRIB_ID="Scientific"
@@ -1293,7 +1304,13 @@ elif [ `uname -o 2>/dev/null` = "Cygwin" ] ; then
 # try use standart LSB info by default
 elif distro lsb-release && [ -n "$DISTRIB_RELEASE" ]; then
 	# use LSB
-	true
+
+	# fix distro name
+	case "$DISTRIB_ID" in
+		"openSUSE Tumbleweed")
+			DISTRIB_ID="Tumbleweed"
+			;;
+	esac
 fi
 
 case $1 in
@@ -1335,7 +1352,7 @@ case $1 in
 		exit 0
 		;;
 	-V)
-		echo "20160822"
+		echo "20161212"
 		exit 0
 		;;
 	*)
@@ -1391,7 +1408,7 @@ fi
 
 # If ftp protocol or have no asterisk, just download
 # TODO: use has()
-if echo "$1" | grep -q "\(^ftp://\|[^*]$\)" ; then
+if echo "$1" | grep -q "\(^ftp://\|[^*]\)" ; then
     $WGET $WGET_OPTION_TARGET "$1"
     return
 fi
@@ -1439,6 +1456,220 @@ download_files || echo "There was some download errors" >&2
 rm -rf "$MYTMPDIR"
 }
 
+internal_tools_json()
+{
+
+# License: MIT or Apache
+# Homepage: http://github.com/dominictarr/JSON.sh
+
+throw() {
+  echo "$*" >&2
+  exit 1
+}
+
+BRIEF=0
+LEAFONLY=0
+PRUNE=0
+NO_HEAD=0
+NORMALIZE_SOLIDUS=0
+
+usage() {
+  echo
+  echo "Usage: JSON.sh [-b] [-l] [-p] [-s] [-h]"
+  echo
+  echo "-p - Prune empty. Exclude fields with empty values."
+  echo "-l - Leaf only. Only show leaf nodes, which stops data duplication."
+  echo "-b - Brief. Combines 'Leaf only' and 'Prune empty' options."
+  echo "-n - No-head. Do not show nodes that have no path (lines that start with [])."
+  echo "-s - Remove escaping of the solidus symbol (straight slash)."
+  echo "-h - This help text."
+  echo
+}
+
+parse_options() {
+  set -- "$@"
+  local ARGN=$#
+  while [ "$ARGN" -ne 0 ]
+  do
+    case $1 in
+      -h) usage
+          exit 0
+      ;;
+      -b) BRIEF=1
+          LEAFONLY=1
+          PRUNE=1
+      ;;
+      -l) LEAFONLY=1
+      ;;
+      -p) PRUNE=1
+      ;;
+      -n) NO_HEAD=1
+      ;;
+      -s) NORMALIZE_SOLIDUS=1
+      ;;
+      ?*) echo "ERROR: Unknown option."
+          usage
+          exit 0
+      ;;
+    esac
+    shift 1
+    ARGN=$((ARGN-1))
+  done
+}
+
+awk_egrep () {
+  local pattern_string=$1
+
+  gawk '{
+    while ($0) {
+      start=match($0, pattern);
+      token=substr($0, start, RLENGTH);
+      print token;
+      $0=substr($0, start+RLENGTH);
+    }
+  }' pattern="$pattern_string"
+}
+
+tokenize () {
+  local GREP
+  local ESCAPE
+  local CHAR
+
+  if echo "test string" | egrep -ao --color=never "test" >/dev/null 2>&1
+  then
+    GREP='egrep -ao --color=never'
+  else
+    GREP='egrep -ao'
+  fi
+
+  if echo "test string" | egrep -o "test" >/dev/null 2>&1
+  then
+    ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
+    CHAR='[^[:cntrl:]"\\]'
+  else
+    GREP=awk_egrep
+    ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
+    CHAR='[^[:cntrl:]"\\\\]'
+  fi
+
+  local STRING="\"$CHAR*($ESCAPE$CHAR*)*\""
+  local NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
+  local KEYWORD='null|false|true'
+  local SPACE='[[:space:]]+'
+
+  # Force zsh to expand $A into multiple words
+  local is_wordsplit_disabled=$(unsetopt 2>/dev/null | grep -c '^shwordsplit$')
+  if [ $is_wordsplit_disabled != 0 ]; then setopt shwordsplit; fi
+  $GREP "$STRING|$NUMBER|$KEYWORD|$SPACE|." | egrep -v "^$SPACE$"
+  if [ $is_wordsplit_disabled != 0 ]; then unsetopt shwordsplit; fi
+}
+
+parse_array () {
+  local index=0
+  local ary=''
+  read -r token
+  case "$token" in
+    ']') ;;
+    *)
+      while :
+      do
+        parse_value "$1" "$index"
+        index=$((index+1))
+        ary="$ary""$value" 
+        read -r token
+        case "$token" in
+          ']') break ;;
+          ',') ary="$ary," ;;
+          *) throw "EXPECTED , or ] GOT ${token:-EOF}" ;;
+        esac
+        read -r token
+      done
+      ;;
+  esac
+  [ "$BRIEF" -eq 0 ] && value=$(printf '[%s]' "$ary") || value=
+  :
+}
+
+parse_object () {
+  local key
+  local obj=''
+  read -r token
+  case "$token" in
+    '}') ;;
+    *)
+      while :
+      do
+        case "$token" in
+          '"'*'"') key=$token ;;
+          *) throw "EXPECTED string GOT ${token:-EOF}" ;;
+        esac
+        read -r token
+        case "$token" in
+          ':') ;;
+          *) throw "EXPECTED : GOT ${token:-EOF}" ;;
+        esac
+        read -r token
+        parse_value "$1" "$key"
+        obj="$obj$key:$value"        
+        read -r token
+        case "$token" in
+          '}') break ;;
+          ',') obj="$obj," ;;
+          *) throw "EXPECTED , or } GOT ${token:-EOF}" ;;
+        esac
+        read -r token
+      done
+    ;;
+  esac
+  [ "$BRIEF" -eq 0 ] && value=$(printf '{%s}' "$obj") || value=
+  :
+}
+
+parse_value () {
+  local jpath="${1:+$1,}$2" isleaf=0 isempty=0 print=0
+  case "$token" in
+    '{') parse_object "$jpath" ;;
+    '[') parse_array  "$jpath" ;;
+    # At this point, the only valid single-character tokens are digits.
+    ''|[!0-9]) throw "EXPECTED value GOT ${token:-EOF}" ;;
+    *) value=$token
+       # if asked, replace solidus ("\/") in json strings with normalized value: "/"
+       [ "$NORMALIZE_SOLIDUS" -eq 1 ] && value=$(echo "$value" | sed 's#\\/#/#g')
+       isleaf=1
+       [ "$value" = '""' ] && isempty=1
+       ;;
+  esac
+  [ "$value" = '' ] && return
+  [ "$NO_HEAD" -eq 1 ] && [ -z "$jpath" ] && return
+
+  [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 0 ] && print=1
+  [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && [ $PRUNE -eq 0 ] && print=1
+  [ "$LEAFONLY" -eq 0 ] && [ "$PRUNE" -eq 1 ] && [ "$isempty" -eq 0 ] && print=1
+  [ "$LEAFONLY" -eq 1 ] && [ "$isleaf" -eq 1 ] && \
+    [ $PRUNE -eq 1 ] && [ $isempty -eq 0 ] && print=1
+  [ "$print" -eq 1 ] && printf "[%s]\t%s\n" "$jpath" "$value"
+  :
+}
+
+parse () {
+  read -r token
+  parse_value
+  read -r token
+  case "$token" in
+    '') ;;
+    *) throw "EXPECTED EOF GOT $token" ;;
+  esac
+}
+
+if ([ "$0" = "$BASH_SOURCE" ] || ! [ -n "$BASH_SOURCE" ]);
+then
+  parse_options "$@"
+  tokenize | parse
+fi
+
+# vi: expandtab sw=2 ts=2
+}
+
 INITDIR=/etc/init.d
 
 PATH=$PATH:/sbin:/usr/sbin
@@ -1465,7 +1696,7 @@ case $DISTRNAME in
 	ALTLinux)
 		CMD="service-chkconfig"
 		;;
-	Ubuntu|Debian|Mint)
+	Ubuntu|Debian|Mint|AstraLinux)
 		CMD="service-update"
 		;;
 	Mandriva|ROSA)
@@ -1480,7 +1711,7 @@ case $DISTRNAME in
 #	ArchLinux)
 #		CMD="pacman"
 #		;;
-	Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific)
+	Fedora|LinuxXP|ASPLinux|CentOS|RHEL|Scientific|GosLinux)
 		CMD="service-chkconfig"
 		;;
 	VoidLinux)
@@ -1489,7 +1720,7 @@ case $DISTRNAME in
 	Slackware)
 		CMD="service-initd"
 		;;
-	SUSE|SLED|SLES)
+	SUSE|SLED|SLES|Tumbleweed)
 		CMD="service-chkconfig"
 		;;
 #	Windows)
@@ -1536,7 +1767,7 @@ $(get_help HELPOPT)
 
 print_version()
 {
-        echo "Service manager version 1.9.6"
+        echo "Service manager version 2.0.5"
         echo "Running on $($DISTRVENDOR) with $SERVICETYPE"
         echo "Copyright (c) Etersoft 2012, 2013, 2016"
         echo "This program may be freely redistributed under the terms of the GNU AGPLv3."
diff --git a/tests/etc/lsb-release b/tests/etc/lsb-release
new file mode 100644
index 0000000000000000000000000000000000000000..64d8b14880e362f8c5c6f39f41af9ee0a2508d06
--- /dev/null
+++ b/tests/etc/lsb-release
@@ -0,0 +1,5 @@
+LSB_VERSION="core-2.0-noarch:core-3.2-noarch:core-4.0-noarch:core-2.0-x86_64:core-3.2-x86_64:core-4.0-x86_64"
+DISTRIB_ID="openSUSE Tumbleweed"
+DISTRIB_RELEASE="20161014"
+DISTRIB_CODENAME=""
+DISTRIB_DESCRIPTION="openSUSE Tumbleweed"