diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4898989
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/yum-utils-1.1.31.tar.gz
diff --git a/.yum-utils.metadata b/.yum-utils.metadata
new file mode 100644
index 0000000..43c6fd2
--- /dev/null
+++ b/.yum-utils.metadata
@@ -0,0 +1 @@
+aa96ccb97ad3a7c53a47c1bda418ce2604b77f1e SOURCES/yum-utils-1.1.31.tar.gz
diff --git a/README.md b/README.md
deleted file mode 100644
index 0e7897f..0000000
--- a/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-The master branch has no content
- 
-Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6
- 
-If you find this file in a distro specific branch, it means that no content has been checked in yet
diff --git a/SOURCES/BZ-1002491-remove-security-plugin.patch b/SOURCES/BZ-1002491-remove-security-plugin.patch
new file mode 100644
index 0000000..98648e1
--- /dev/null
+++ b/SOURCES/BZ-1002491-remove-security-plugin.patch
@@ -0,0 +1,1182 @@
+commit a5c7a3011bb9d2497c980791111389d226445281
+Author: Zdenek Pavlas <zpavlas@redhat.com>
+Date:   Thu Oct 3 14:15:11 2013 +0200
+
+    remove yum-plugin-security. BZ 1002491
+    
+    This functionality is now implemented in core (yum updateinfo).
+
+diff --git a/docs/Makefile b/docs/Makefile
+index acb8559..481f0f3 100644
+--- a/docs/Makefile
++++ b/docs/Makefile
+@@ -5,7 +5,7 @@ DOCS = repoquery package-cleanup repo-rss yumdownloader yum-builddep yum-changel
+        find-repos-of-install needs-restarting repo-graph repoclosure \
+        repomanage repotrack verifytree yum-config-manager
+ DOCS5 = yum-changelog.conf yum-versionlock.conf yum-fs-snapshot.conf
+-DOCS8 = yum-security yum-complete-transaction yumdb
++DOCS8 = yum-complete-transaction yumdb
+ 
+ all:
+ 	echo "Nothing to do"
+diff --git a/docs/yum-security.8 b/docs/yum-security.8
+deleted file mode 100644
+index c7d9c8b..0000000
+--- a/docs/yum-security.8
++++ /dev/null
+@@ -1,190 +0,0 @@
+-.\" yum security plugin
+-.TH "yum-security" "8" "12 April 2007" "James Antill" ""
+-.SH "NAME"
+-yum security plugin
+-.SH "SYNOPSIS"
+-\fByum\fP [options] [command] [package ...]
+-.SH "DESCRIPTION"
+-.PP 
+-This plugin extends \fByum\fP to allow lists and updates to be limited using security relevant criteria.
+-.PP 
+-Added yum \fIcommand\fPs are:
+-.br 
+-.I \fR yum update-minimal
+-.PP 
+-This works like the update command, but if you have the package foo-1
+-installed and have foo-2 and foo-3 available with updateinfo.xml then
+-update-minimal will update you to foo-3.
+-.br 
+-.I \fR yum updateinfo info
+-.br 
+-.I \fR yum updateinfo list
+-.br 
+-.I \fR yum updateinfo summary
+-.PP 
+-All of the last three take these \fIsub-command\fPs:
+-.br 
+-.I \fR yum updateinfo * all
+-.br 
+-.I \fR yum updateinfo * available
+-.br 
+-.I \fR yum updateinfo * installed
+-.br 
+-.I \fR yum updateinfo * updates
+-.PP 
+-and then:
+-.br 
+-.I \fR * <advisory> [advisory...]
+-.br 
+-.I \fR * <package>
+-.br 
+-.I \fR * bugzillas
+-.br 
+-.I \fR * cves
+-.br 
+-.I \fR * enhancement
+-.br 
+-.I \fR * security
+-.br 
+-.I \fR * new-packages
+-.br 
+-.br 
+-.PP
+-.IP "\fBall\fP"
+-Is used to display information about both install and available advisories.
+-.PP
+-.IP "\fBavailable\fP"
+-Is used to display information about just available advisories. This is the
+-default.
+-.PP
+-.IP "\fBinstalled\fP"
+-Is used to display information about just install advisories.
+-.PP
+-.IP "\fBupdates\fP"
+-This is mostly the same as "available" but it only shows advisory information
+-for packages that can be updated to.
+-.PP
+-.IP "\fB<advisory> [advisory...]\fP"
+-Is used to display information about one or more advisories.
+-.PP 
+-.IP "\fB<package> [package...]\fP"
+-Is used to display information about one or more packages.
+-.PP 
+-.IP "\fBlist\fP"
+-Is used to list all of the relevant errata notice information, from the
+-updateinfo.xml data in yum. This includes bugzillas, CVEs, security updates and
+-new.
+-.PP 
+-.IP "\fBinfo\fP"
+-Is used to show all the errata notice information, from the
+-updateinfo.xml data in yum. This includes bugzillas, CVEs, security updates and
+-new.
+-.PP 
+-.IP "\fBlist\fP"
+-Is used to list all of the relevant errata notice information, from the
+-updateinfo.xml data in yum. This includes bugzillas, CVEs, security updates and
+-new.
+-.IP 
+-.IP "\fBbugzillas / bzs\fP"
+-Is the subset of the updateinfo information, pertaining to the bugzillas.
+-.IP 
+-.IP "\fBcves\fP"
+-Is the subset of the updateinfo information, pertaining to the CVEs.
+-.IP 
+-.IP "\fBsecurity / sec\fP"
+-Is the subset of the updateinfo information, pertaining to security.
+-.IP "\fBbugfix\fP"
+-Is the subset of the updateinfo information, pertaining to bugfixes.
+-.IP "\fBenhancement\fP"
+-Is the subset of the updateinfo information, pertaining to enhancements.
+-.IP "\fBrecommended\fP"
+-Is the subset of the updateinfo information, pertaining to recommended updates.
+-.IP "\fBnew-packages\fP"
+-Is the subset of the updateinfo information, pertaining to new packages. These
+-are packages which weren't available at the initial release of your
+-distribution.
+-.IP
+-.PP
+-.SH "GENERAL OPTIONS"
+-There are four options added to yum that are available in the "list updates", "info updates", "check-update" and "update" commands. They are:
+-.PP 
+-.IP "\fB\-\-advisory\fP"
+-This option includes packages corresponding to the advisory ID, Eg. FEDORA-2201-123.
+-.IP "\fB\-\-bz\fP"
+-This option includes packages that say they fix a Bugzilla ID, Eg. 123.
+-.IP "\fB\-\-cve\fP"
+-This option includes packages that say they fix a CVE - Common Vulnerabilities and Exposures ID (http://cve.mitre.org/about/), Eg. CVE-2201-0123.
+-.IP "\fB\-\-bugfixes\fP"
+-This option includes packages that say they fix a bugfix issue.
+-.IP "\fB\-\-security\fP"
+-This option includes packages that say they fix a security issue.
+-.PP
+-.PP
+-
+-.SH "EXAMPLES"
+-.PP
+-To list all updates that are security relevant, and get a return code on whether there are security updates use:
+-.IP
+-yum \-\-security check-update
+-.PP
+-To upgrade packages that have security errata (upgrades to the latest
+-available package) use:
+-.IP
+-yum \-\-security update
+-.PP
+-To upgrade packages that have security errata (upgrades to the last
+-security errata package) use:
+-.IP
+-yum \-\-security update-minimal
+-.PP
+-To get a list of all BZs that are fixed for packages you have installed use:
+-.IP
+-yum updateinfo list bugzillas
+-.PP
+-To get a list of all security advisories, including the ones you have already
+-installed use:
+-.IP
+-yum updateinfo list all security
+-.PP
+-To get the information on advisory FEDORA-2707-4567 use:
+-.IP
+-yum updateinfo info FEDORA-2707-4567
+-.PP
+-To update packages to the latest version which contain fixes for Bugzillas 123, 456 and 789; and all security updates use:
+-.IP
+-yum \-\-bz 123 \-\-bz 456 \-\-bz 789 \-\-security update
+-.PP
+-To update to the packages which just update Bugzillas 123, 456 and 789; and all security updates use:
+-.IP
+-yum \-\-bz 123 \-\-bz 456 \-\-bz 789 \-\-security update-minimal
+-.PP
+-To get an info list of the latest packages which contain fixes for Bugzilla 123; CVEs CVE-2207-0123 and CVE-2207-3210; and Fedora advisories FEDORA-2707-4567 and FEDORA-2707-7654 use:
+-.IP
+-yum \-\-bz 123 \-\-cve CVE-2207-0123 \-\-cve CVE-2207-3210 \-\-advisory FEDORA-2707-4567 \-\-advisory FEDORA-2707-7654 info updates
+-.PP
+-To get a list of packages which are "new".
+-.IP
+-yum updateinfo list new
+-.PP
+-To get a summary of advisories you haven't installed yet use:
+-.IP
+-yum updateinfo summary
+-
+-
+-.SH "SEE ALSO"
+-.nf
+-.I yum (8)
+-.I yum.conf (5)
+-.fi
+-
+-.SH "AUTHORS"
+-.nf
+-James Antill <james.antill@redhat.com>.
+-.fi
+-
+-.SH "BUGS"
+-The update-minimal command ignores the \-\-obsoletes flag.
+-
+-The update-minimal command can only directly affect things atm., so if you update pkgA minimally but that requires an update to pkgB then pkgB will be updated to the newest version by the depsolver. Also the above will happen even if you've also minimally updated pkgB, if either the direct (minimal) update for pkgB happens after or if the minimal update for pkgB doesn't satisfy the requirements of pkgA.
+-
+-The main "problem" is that if the data is not correct the plugin cannot work correctly. For instance "\-\-bz 123" will not fix BZ 123 if a package is updated to fix that BZ without referencing that it does so in the updateinfo.xml.
+diff --git a/plugins/security/security.conf b/plugins/security/security.conf
+deleted file mode 100644
+index 8e4d76c..0000000
+--- a/plugins/security/security.conf
++++ /dev/null
+@@ -1,2 +0,0 @@
+-[main]
+-enabled=1
+diff --git a/plugins/security/security.py b/plugins/security/security.py
+deleted file mode 100755
+index a60cf9b..0000000
+--- a/plugins/security/security.py
++++ /dev/null
+@@ -1,892 +0,0 @@
+-#! /usr/bin/python -tt
+-# This program is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
+-# (at your option) any later version.
+-#
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+-#
+-#
+-# Copyright Red Hat Inc. 2007, 2008
+-#
+-# Author: James Antill <james.antill@redhat.com>
+-#
+-# Examples:
+-#
+-#  yum --security info updates
+-#  yum --security list updates
+-#  yum --security check-update
+-#  yum --security update
+-#
+-# yum --cve CVE-2007-1667      <cmd>
+-# yum --bz  235374 --bz 234688 <cmd>
+-# yum --advisory FEDORA-2007-420 --advisory FEDORA-2007-346 <cmd>
+-#
+-# yum list-updateinfo
+-# yum list-updateinfo bugzillas / bzs
+-# yum list-updateinfo cves
+-# yum list-updateinfo security / sec
+-# yum list-updateinfo new
+-#
+-# yum summary-updateinfo
+-#
+-# yum update-minimal --security
+-
+-import yum
+-import fnmatch
+-from yum.plugins import TYPE_INTERACTIVE
+-from yum.update_md import UpdateMetadata
+-import logging # for commands
+-
+-from yum.constants import *
+-
+-import rpmUtils.miscutils
+-
+-requires_api_version = '2.5'
+-plugin_type = (TYPE_INTERACTIVE,)
+-__package_name__ = "yum-plugin-security"
+-
+-# newpackages is weird, in that we'll never display that because we filter to
+-# things relevant to installed pkgs...
+-__update_info_types__ = ("security", "bugfix", "enhancement",
+-                         "recommended", "newpackage")
+-
+-def _rpm_tup_vercmp(tup1, tup2):
+-    """ Compare two "std." tuples, (n, a, e, v, r). """
+-    return rpmUtils.miscutils.compareEVR((tup1[2], tup1[3], tup1[4]),
+-                                         (tup2[2], tup2[3], tup2[4]))
+-
+-class CliError(yum.Errors.YumBaseError):
+-
+-    """
+-    Command line interface related Exception.
+-    """
+-
+-    def __init__(self, args=''):
+-        yum.Errors.YumBaseError.__init__(self)
+-        self.args = args
+-
+-def ysp_gen_metadata(repos):
+-    """ Generate the info. from the updateinfo.xml files. """
+-    md_info = UpdateMetadata()
+-    for repo in repos:
+-        if not repo.enabled:
+-            continue
+-        
+-        try: # attempt to grab the updateinfo.xml.gz from the repodata
+-            md_info.add(repo)
+-        except yum.Errors.RepoMDError:
+-            continue # No metadata found for this repo
+-    return md_info
+-
+-def ysp__safe_refs(refs):
+-    """ Sometimes refs == None, if so return the empty list here. 
+-        So we don't have to check everywhere. """
+-    if refs == None:
+-        return []
+-    return refs
+-
+-def _match_sec_cmd(sec_cmds, pkgname, notice):
+-    for i in sec_cmds:
+-        if fnmatch.fnmatch(pkgname, i):
+-            return i
+-        if notice['update_id'] == i:
+-            return i
+-    return None
+-
+-def _has_id(used_map, refs, ref_type, ref_ids):
+-    ''' Check if the given ID is a match. '''
+-    for ref in ysp__safe_refs(refs):
+-        if ref['type'] != ref_type:
+-            continue
+-        if ref['id'] not in ref_ids:
+-            continue
+-        used_map[ref_type][ref['id']] = True
+-        return ref
+-    return None
+-    
+-def ysp_should_filter_pkg(opts, pkgname, notice, used_map):
+-    """ Do the package filtering for should_show and should_keep. """
+-    
+-    rcmd = _match_sec_cmd(opts.sec_cmds, pkgname, notice)
+-    if rcmd:
+-        used_map['cmd'][rcmd] = True
+-        return True
+-    elif opts.advisory and notice['update_id'] in opts.advisory:
+-        used_map['id'][notice['update_id']] = True
+-        return True
+-    elif (opts.severity and notice['type'] == 'security' and
+-          notice['severity'] in opts.severity):
+-        used_map['sev'][notice['severity']] = True
+-        return True
+-    elif opts.cve and _has_id(used_map, notice['references'], "cve", opts.cve):
+-        return True
+-    elif opts.bz and _has_id(used_map, notice['references'],"bugzilla",opts.bz):
+-        return True
+-    # FIXME: Add opts for enhancement/etc.? -- __update_info_types__
+-    elif (opts.security and notice['type'] == 'security' and
+-          (not opts.severity or 'severity' not in notice or
+-           not notice['severity'])):
+-        return True
+-    elif opts.bugfixes and notice['type'] == 'bugfix':
+-        return True
+-    elif not (opts.advisory or opts.cve or opts.bz or
+-              opts.security or opts.bugfixes or opts.sec_cmds or opts.severity):
+-        return True # This is only possible from should_show_pkg
+-    return False
+-
+-def ysp_has_info_md(rname, md):
+-    if rname in __update_info_types__:
+-        if md['type'] == rname:
+-            return md
+-    for ref in ysp__safe_refs(md['references']):
+-        if ref['type'] != rname:
+-            continue
+-        return md
+-
+-def ysp_gen_used_map(opts):
+-    used_map = {'bugzilla' : {}, 'cve' : {}, 'id' : {}, 'cmd' : {}, 'sev' : {}}
+-    for i in opts.sec_cmds:
+-        used_map['cmd'][i] = False
+-    for i in opts.advisory:
+-        used_map['id'][i] = False
+-    for i in opts.bz:
+-        used_map['bugzilla'][i] = False
+-    for i in opts.cve:
+-        used_map['cve'][i] = False
+-    for i in opts.severity:
+-        used_map['sev'][i] = False
+-    return used_map
+-
+-def ysp_chk_used_map(used_map, msg):
+-    for i in used_map['cmd']:
+-        if not used_map['cmd'][i]:
+-            msg('No update information found for \"%s\"' % i)
+-    for i in used_map['id']:
+-        if not used_map['id'][i]:
+-            msg('Advisory \"%s\" not found applicable for this system' % i)
+-    for i in used_map['bugzilla']:
+-        if not used_map['bugzilla'][i]:
+-            msg('BZ \"%s\" not found applicable for this system' % i)
+-    for i in used_map['cve']:
+-        if not used_map['cve'][i]:
+-            msg('CVE \"%s\" not found applicable for this system' % i)
+-    for i in used_map['sev']:
+-        if not used_map['sev'][i]:
+-            msg('Severity \"%s\" not found applicable for this system' % i)
+-
+-class UpdateinfoCommand:
+-    # Old command names...
+-    direct_cmds = {'list-updateinfo'    : 'list',
+-                   'list-security'      : 'list',
+-                   'list-sec'           : 'list',
+-                   'info-updateinfo'    : 'info',
+-                   'info-security'      : 'info',
+-                   'info-sec'           : 'info',
+-                   'summary-updateinfo' : 'summary'}
+-
+-    #  Note that this code (instead of using inheritance and multiple
+-    # cmd classes) means that "yum help" only displays the updateinfo command.
+-    # Which is what we want, because the other commands are just backwards
+-    # compatible gunk we don't want the user using).
+-    def getNames(self):
+-        return ['updateinfo'] + sorted(self.direct_cmds.keys())
+-
+-    def getUsage(self):
+-        return "[info|list|...] [security|...] [installed|available|all] [pkgs|id]"
+-
+-    def getSummary(self):
+-        return "Acts on repository update information"
+-
+-    def doCheck(self, base, basecmd, extcmds):
+-        pass
+-
+-    def list_show_pkgs(self, base, md_info, list_type, show_type,
+-                       iname2tup, data, msg):
+-        n_maxsize = 0
+-        r_maxsize = 0
+-        t_maxsize = 0
+-        for (notice, pkgtup, pkg) in data:
+-            n_maxsize = max(len(notice['update_id']), n_maxsize)
+-            tn = notice['type']
+-            if tn == 'security' and notice['severity']:
+-                tn = notice['severity'] + '/Sec.'
+-            t_maxsize = max(len(tn),                  t_maxsize)
+-            if show_type:
+-                for ref in ysp__safe_refs(notice['references']):
+-                    if ref['type'] != show_type:
+-                        continue
+-                    r_maxsize = max(len(str(ref['id'])), r_maxsize)
+-
+-        for (notice, pkgtup, pkg) in data:
+-            mark = ''
+-            if list_type == 'all':
+-                mark = '  '
+-                if _rpm_tup_vercmp(iname2tup[pkgtup[0]], pkgtup) >= 0:
+-                    mark = 'i '
+-            tn = notice['type']
+-            if tn == 'security' and notice['severity']:
+-                tn = notice['severity'] + '/Sec.'
+-
+-            if show_type and ysp_has_info_md(show_type, notice):
+-                for ref in ysp__safe_refs(notice['references']):
+-                    if ref['type'] != show_type:
+-                        continue
+-                    msg("%s %-*s %-*s %s" % (mark, r_maxsize, str(ref['id']),
+-                                             t_maxsize, tn, pkg))
+-            elif hasattr(pkg, 'name'):
+-                print base.fmtKeyValFill("%s: " % pkg.name,
+-                                         base._enc(pkg.summary))
+-            else:
+-                msg("%s%-*s %-*s %s" % (mark, n_maxsize, notice['update_id'],
+-                                        t_maxsize, tn, pkg))
+-
+-    def info_show_pkgs(self, base, md_info, list_type, show_type,
+-                       iname2tup, data, msg):
+-        show_pkg_info_done = {}
+-        for (notice, pkgtup, pkg) in data:
+-            if notice['update_id'] in show_pkg_info_done:
+-                continue
+-            show_pkg_info_done[notice['update_id']] = notice
+-
+-            if hasattr(notice, 'text'):
+-                debug_log_lvl = yum.logginglevels.DEBUG_3
+-                vlog = logging.getLogger("yum.verbose.main")
+-                if vlog.isEnabledFor(debug_log_lvl):
+-                    obj = notice.text(skip_data=[])
+-                else:
+-                    obj = notice.text()
+-            else:
+-                # Python-2.4.* doesn't understand str(x) returning unicode
+-                obj = notice.__str__()
+-
+-            if list_type == 'all':
+-                if _rpm_tup_vercmp(iname2tup[pkgtup[0]], pkgtup) >= 0:
+-                    obj = obj + "\n  Installed : true"
+-                else:
+-                    obj = obj + "\n  Installed : false"
+-            msg(obj)
+-
+-    def summary_show_pkgs(self, base, md_info, list_type, show_type,
+-                          iname2tup, data, msg):
+-        def _msg(x):
+-            print x
+-        counts = {}
+-        sev_counts = {}
+-        show_pkg_info_done = {}
+-        for (notice, pkgtup, pkg) in data:
+-            if notice['update_id'] in show_pkg_info_done:
+-                continue
+-            show_pkg_info_done[notice['update_id']] = notice
+-            counts[notice['type']] = counts.get(notice['type'], 0) + 1
+-            if notice['type'] == 'security':
+-                sev = notice['severity']
+-                if sev is None:
+-                    sev = ''
+-                sev_counts[sev] = sev_counts.get(sev, 0) + 1
+-
+-        maxsize = 0
+-        for T in ('newpackage', 'security', 'bugfix', 'enhancement'):
+-            if T not in counts:
+-                continue
+-            size = len(str(counts[T]))
+-            if maxsize < size:
+-                maxsize = size
+-        if not maxsize:
+-            _check_running_kernel(base, md_info, _msg)
+-            return
+-
+-        outT = {'newpackage' : 'New Package',
+-                'security' : 'Security',
+-                'bugfix' : 'Bugfix',
+-                'enhancement' : 'Enhancement'}
+-        print "Updates Information Summary:", list_type
+-        for T in ('newpackage', 'security', 'bugfix', 'enhancement'):
+-            if T not in counts:
+-                continue
+-            n = outT[T]
+-            if T == 'security' and len(sev_counts) == 1:
+-                sn = sev_counts.keys()[0]
+-                if sn != '':
+-                    n = sn + " " + n
+-            print "    %*u %s notice(s)" % (maxsize, counts[T], n)
+-            if T == 'security' and len(sev_counts) != 1:
+-                def _sev_sort_key(key):
+-                    # We want these in order, from "highest" to "lowest".
+-                    # Anything unknown is "higher". meh.
+-                    return {'Critical' : "zz1",
+-                            'Important': "zz2",
+-                            'Moderate' : "zz3",
+-                            'Low'      : "zz4",
+-                            }.get(key, key)
+-
+-                for sn in sorted(sev_counts, key=_sev_sort_key):
+-                    args = (maxsize, sev_counts[sn],sn or '?', outT['security'])
+-                    print "        %*u %s %s notice(s)" % args
+-        _check_running_kernel(base, md_info, _msg)
+-        self.show_pkg_info_done = {}
+-
+-    def _get_new_pkgs(self, md_info):
+-        for notice in md_info.notices:
+-            if notice['type'] != "newpackage":
+-                continue
+-            for upkg in notice['pkglist']:
+-                for pkg in upkg['packages']:
+-                    pkgtup = (pkg['name'], pkg['arch'], pkg['epoch'] or '0',
+-                              pkg['version'], pkg['release'])
+-                    yield (notice, pkgtup)
+-
+-    _cmd2filt = {"bugzillas" : "bugzilla",
+-                 "bugzilla" : "bugzilla",
+-                 "bzs" : "bugzilla",
+-                 "bz" : "bugzilla",
+-
+-                 "sec" : "security",
+-
+-                 "cves" : "cve",
+-                 "cve" : "cve",
+-
+-                 "newpackages" : "newpackage",
+-                 "new-packages" : "newpackage",
+-                 "newpackage" : "newpackage",
+-                 "new-package" : "newpackage",
+-                 "new" : "newpackage"}
+-    for filt_type in __update_info_types__:
+-        _cmd2filt[filt_type] = filt_type
+-
+-    def doCommand(self, base, basecmd, extcmds):
+-        if basecmd in self.direct_cmds:
+-            subcommand = self.direct_cmds[basecmd]
+-        elif extcmds and extcmds[0] in ('list', 'info', 'summary'):
+-            subcommand = extcmds[0]
+-            extcmds = extcmds[1:]
+-        elif extcmds and extcmds[0] in self._cmd2filt:
+-            subcommand = 'list'
+-        elif extcmds:
+-            subcommand = 'info'
+-        else:
+-            subcommand = 'summary'
+-
+-        if subcommand == 'list':
+-            return self.doCommand_li(base, 'updateinfo list', extcmds,
+-                                     self.list_show_pkgs)
+-        if subcommand == 'info':
+-            return self.doCommand_li(base, 'updateinfo info', extcmds,
+-                                     self.info_show_pkgs)
+-
+-        if subcommand == 'summary':
+-            return self.doCommand_li(base, 'updateinfo summary', extcmds,
+-                                     self.summary_show_pkgs)
+-
+-    def doCommand_li_new(self, base, list_type, extcmds, md_info, msg,
+-                         show_pkgs):
+-        done_pkgs = set()
+-        data = []
+-        for (notice, pkgtup) in sorted(self._get_new_pkgs(md_info),
+-                                       key=lambda x: x[1][0]):
+-            if extcmds and not _match_sec_cmd(extcmds, pkgtup[0], notice):
+-                continue
+-            n = pkgtup[0]
+-            if n in done_pkgs:
+-                continue
+-            ipkgs = list(reversed(sorted(base.rpmdb.searchNames([n]))))
+-            if list_type in ('installed', 'updates') and not ipkgs:
+-                done_pkgs.add(n)
+-                continue
+-            if list_type == 'available' and ipkgs:
+-                done_pkgs.add(n)
+-                continue
+-
+-            pkgs = base.pkgSack.searchPkgTuple(pkgtup)
+-            if not pkgs:
+-                continue
+-            if list_type == "updates" and pkgs[0].verLE(ipkgs[0]):
+-                done_pkgs.add(n)
+-                continue
+-            done_pkgs.add(n)
+-            data.append((notice, pkgtup, pkgs[0]))
+-        show_pkgs(base, md_info, list_type, None, {}, data, msg)
+-
+-    def _parse_extcmds(self, extcmds):
+-        filt_type = None
+-        show_type = None
+-        if len(extcmds) >= 1:
+-            filt_type = None
+-            
+-            if extcmds[0] in self._cmd2filt:
+-                filt_type = self._cmd2filt[extcmds.pop(0)]
+-            show_type = filt_type
+-            if filt_type and filt_type in __update_info_types__:
+-                show_type = None
+-        return extcmds, show_type, filt_type
+-
+-    def doCommand_li(self, base, basecmd, extcmds, show_pkgs):
+-        self.repos = base.repos
+-        md_info = ysp_gen_metadata(self.repos.listEnabled())
+-        def msg(x):
+-            #  Don't use: logger.log(logginglevels.INFO_2, x)
+-            # or -q deletes everything.
+-            print x
+-
+-        opts, cmdline = base.plugins.cmdline
+-        extcmds, show_type, filt_type = self._parse_extcmds(extcmds)
+-
+-        list_type = "available"
+-        if extcmds and extcmds[0] in ("updates","available","installed", "all"):
+-            list_type = extcmds.pop(0)
+-
+-        if filt_type == "newpackage":
+-            # No filtering here, as we want what isn't installed...
+-            self.doCommand_li_new(base, list_type, extcmds, md_info, msg,
+-                                  show_pkgs)
+-            return 0, [basecmd + ' new done']
+-
+-        opts.sec_cmds = extcmds
+-        used_map = ysp_gen_used_map(opts)
+-        iname2tup = {}
+-        if False: pass
+-        elif list_type in ('installed', 'all'):
+-            name2tup = _get_name2allpkgtup(base)
+-            iname2tup = _get_name2instpkgtup(base)
+-        elif list_type == 'updates':
+-            name2tup = _get_name2oldpkgtup(base)
+-        elif list_type == 'available':
+-            name2tup = _get_name2instpkgtup(base)
+-
+-        def _show_pkgtup(pkgtup):
+-            name = pkgtup[0]
+-            notices = reversed(md_info.get_applicable_notices(pkgtup))
+-            for (pkgtup, notice) in notices:
+-                if filt_type and not ysp_has_info_md(filt_type, notice):
+-                    continue
+-
+-                if list_type == 'installed':
+-                    # Remove any that are newer than what we have installed
+-                    if _rpm_tup_vercmp(iname2tup[name], pkgtup) < 0:
+-                        continue
+-
+-                if ysp_should_filter_pkg(opts, name, notice, used_map):
+-                    yield (pkgtup, notice)
+-
+-        data = []
+-        for pkgname in sorted(name2tup):
+-            for (pkgtup, notice) in _show_pkgtup(name2tup[pkgname]):
+-                d = {}
+-                (d['n'], d['a'], d['e'], d['v'], d['r']) = pkgtup
+-                if d['e'] == '0':
+-                    d['epoch'] = ''
+-                else:
+-                    d['epoch'] = "%s:" % d['e']
+-                data.append((notice, pkgtup,
+-                            "%(n)s-%(epoch)s%(v)s-%(r)s.%(a)s" % d))
+-        show_pkgs(base, md_info, list_type, show_type, iname2tup, data, msg)
+-
+-        ysp_chk_used_map(used_map, msg)
+-
+-        return 0, [basecmd + ' done']
+-            
+-
+-# "Borrowed" from yumcommands.py
+-def yumcommands_checkRootUID(base):
+-    """
+-    Verify that the program is being run by the root user.
+-
+-    @param base: a YumBase object.
+-    """
+-    if base.conf.uid != 0:
+-        base.logger.critical('You need to be root to perform this command.')
+-        raise CliError
+-def yumcommands_checkGPGKey(base):
+-    if not base.gpgKeyCheck():
+-        for repo in base.repos.listEnabled():
+-            if repo.gpgcheck != 'false' and repo.gpgkey == '':
+-                msg = """
+-You have enabled checking of packages via GPG keys. This is a good thing. 
+-However, you do not have any GPG public keys installed. You need to download
+-the keys for packages you wish to install and install them.
+-You can do that by running the command:
+-    rpm --import public.gpg.key
+-
+-
+-Alternatively you can specify the url to the key you would like to use
+-for a repository in the 'gpgkey' option in a repository section and yum 
+-will install it for you.
+-
+-For more information contact your distribution or package provider.
+-"""
+-                base.logger.critical(msg)
+-                raise CliError
+-
+-def _get_name2pkgtup(base, pkgtups):
+-    name2tup = {}
+-    for pkgtup in pkgtups:
+-        # Get the latest "old" pkgtups
+-        if (pkgtup[0] in name2tup and
+-            _rpm_tup_vercmp(name2tup[pkgtup[0]], pkgtup) > 0):
+-            continue
+-        name2tup[pkgtup[0]] = pkgtup
+-    return name2tup
+-def _get_name2oldpkgtup(base):
+-    """ Get the pkgtups for all installed pkgs. which have an update. """
+-    oupdates = map(lambda x: x[1], base.up.getUpdatesTuples())
+-    return _get_name2pkgtup(base, oupdates)
+-def _get_name2instpkgtup(base):
+-    """ Get the pkgtups for all installed pkgs. """
+-    return _get_name2pkgtup(base, base.rpmdb.simplePkgList())
+-def _get_name2allpkgtup(base):
+-    """ Get the pkgtups for all installed pkgs. and munge that to be the
+-        first possible pkgtup. """
+-    ofirst = [(pt[0], pt[1], '0','0','0') for pt in base.rpmdb.simplePkgList()]
+-    return _get_name2pkgtup(base, ofirst)
+-
+-
+-
+-class SecurityUpdateCommand:
+-    def getNames(self):
+-        return ['update-minimal']
+-
+-    def getUsage(self):
+-        return "[PACKAGE-wildcard]"
+-
+-    def getSummary(self):
+-        return "Works like update, but goes to the 'newest' package match which fixes a problem that affects your system"
+-
+-    def doCheck(self, base, basecmd, extcmds):
+-        yumcommands_checkRootUID(base)
+-        yumcommands_checkGPGKey(base)
+-
+-    def doCommand(self, base, basecmd, extcmds):
+-        if hasattr(base, 'run_with_package_names'):
+-            base.run_with_package_names.add(__package_name__)
+-        md_info       = ysp_gen_metadata(base.repos.listEnabled())
+-        opts          = base.plugins.cmdline[0]
+-        opts.sec_cmds = []
+-        used_map      = ysp_gen_used_map(opts)
+-
+-        ndata = not (opts.security or opts.bugfixes or
+-                     opts.advisory or opts.bz or opts.cve or opts.severity)
+-
+-        # NOTE: Not doing obsoletes processing atm. ... maybe we should? --
+-        # Also worth pointing out we don't go backwards for obsoletes in the:
+-        # update --security case etc.
+-
+-        # obsoletes = base.up.getObsoletesTuples(newest=False)
+-        # for (obsoleting, installed) in sorted(obsoletes, key=lambda x: x[0]):
+-        #   pass
+-
+-        # Tuples == (n, a, e, v, r)
+-        oupdates  = map(lambda x: x[1], base.up.getUpdatesTuples())
+-        for oldpkgtup in sorted(oupdates):
+-            data = md_info.get_applicable_notices(oldpkgtup)
+-            if ndata: # No options means pick the oldest update
+-                data.reverse()
+-
+-            for (pkgtup, notice) in data:
+-                name = pkgtup[0]
+-                if extcmds and not _match_sec_cmd(extcmds, name, notice):
+-                    continue
+-                if (not ndata and
+-                    not ysp_should_filter_pkg(opts, name, notice, used_map)):
+-                    continue
+-                base.update(name=pkgtup[0], arch=pkgtup[1], epoch=pkgtup[2],
+-                            version=pkgtup[3], release=pkgtup[4])
+-                break
+-
+-        if len(base.tsInfo) > 0:
+-            msg = '%d packages marked for minimal Update' % len(base.tsInfo)
+-            return 2, [msg]
+-        else:
+-            return 0, ['No Packages marked for minimal Update']
+-
+-def config_hook(conduit):
+-    '''
+-    Yum Plugin Config Hook: 
+-    Setup the option parser with the '--advisory', '--bz', '--cve',
+-    '--security' and '--severity' command line options. Also the 'updateinfo'
+-    and 'update-minimal' commands.
+-    '''
+-
+-    parser = conduit.getOptParser()
+-    if not parser:
+-        return
+-
+-    if hasattr(parser, 'plugin_option_group'):
+-        parser = parser.plugin_option_group
+-
+-    conduit.registerCommand(UpdateinfoCommand())
+-    conduit.registerCommand(SecurityUpdateCommand())
+-    def osec(opt, key, val, parser):
+-         # CVE is a subset of --security on RHEL, but not on Fedora
+-        parser.values.security = True
+-    def obug(opt, key, val, parser):
+-        parser.values.bugfixes = True
+-    def ocve(opt, key, val, parser):
+-        parser.values.cve.extend(val.split(','))
+-    def obz(opt, key, val, parser):
+-        parser.values.bz.append(str(val))
+-    def oadv(opt, key, val, parser):
+-        parser.values.advisory.extend(val.split(','))
+-    def osev(opt, key, val, parser):
+-        parser.values.severity.extend(val.split(','))
+-            
+-    parser.add_option('--security', action="callback",
+-                      callback=osec, dest='security', default=False,
+-                      help='Include security relevant packages')
+-    parser.add_option('--bugfixes', action="callback",
+-                      callback=obug, dest='bugfixes', default=False,
+-                      help='Include bugfix relevant packages')
+-    parser.add_option('--cve', action="callback", type="string",
+-                      callback=ocve, dest='cve', default=[],
+-                      help='Include packages needed to fix the given CVE')
+-    parser.add_option('--bz', action="callback",
+-                      callback=obz, dest='bz', default=[], type="int",
+-                      help='Include packages needed to fix the given BZ')
+-    parser.add_option('--sec-severity', action="callback",
+-                      callback=osev, dest='severity', default=[], type="string",
+-                      help='Include security relevant packages, of this severity')
+-    parser.add_option('--advisory', action="callback",
+-                      callback=oadv, dest='advisory', default=[], type="string",
+-                      help='Include packages needed to fix the given advisory')
+-
+-#  You might think we'd just use the exclude_hook, and call delPackage
+-# and indeed that works for list updates etc.
+-#
+-# __but__ that doesn't work for dependancies on real updates
+-#
+-#  So to fix deps. we need to do it at the preresolve stage and take the
+-# "transaction package list" and then remove packages from that.
+-#
+-# __but__ that doesn't work for lists ... so we do it two ways
+-#
+-def ysp_should_keep_pkg(opts, pkgtup, md_info, used_map):
+-    """ Do we want to keep this package to satisfy the security limits. """
+-    name = pkgtup[0]
+-    for (pkgtup, notice) in md_info.get_applicable_notices(pkgtup):
+-        if ysp_should_filter_pkg(opts, name, notice, used_map):
+-            return True
+-    return False
+-
+-def ysp_check_func_enter(conduit):
+-    """ Stuff we need to do in both list and update modes. """
+-    
+-    opts, args = conduit.getCmdLine()
+-
+-    ndata = not (opts.security or opts.bugfixes or
+-                 opts.advisory or opts.bz or opts.cve or opts.severity)
+-    
+-    ret = None
+-    if len(args) >= 2:
+-        if ((args[0] == "list") and (args[1] in ("obsoletes", "updates"))):
+-            ret = {"skip": ndata, "list_cmd": True}
+-        if ((args[0] == "info") and (args[1] in ("obsoletes", "updates"))):
+-            ret = {"skip": ndata, "list_cmd": True}
+-    if len(args):
+-
+-        # All the args. stuff is done in our command:
+-        if (args[0] == "update-minimal"):
+-            return (opts, {"skip": True, "list_cmd": False, "msg": True})
+-            
+-        if (args[0] == "check-update"):
+-            ret = {"skip": ndata, "list_cmd": True}
+-        if (args[0] in ["update", "upgrade"]):
+-            ret = {"skip": ndata, "list_cmd": False}
+-        if args[0] == 'updateinfo':
+-            return (opts, {"skip": True, "list_cmd": True})
+-        if (args[0] in UpdateinfoCommand.direct_cmds):
+-            return (opts, {"skip": True, "list_cmd": True})
+-
+-    if ret:
+-        return (opts, ret)
+-    
+-    if not ndata:
+-        conduit.error(2, 'Skipping security plugin, other command')
+-    return (opts, {"skip": True, "list_cmd": False, "msg": True})
+-
+-def exclude_hook(conduit):
+-    '''
+-    Yum Plugin Exclude Hook:
+-    Check and remove packages that don\'t align with the security config.
+-    '''
+-    
+-    opts, info = ysp_check_func_enter(conduit)
+-    if info["skip"]:
+-        return
+-
+-    if not info["list_cmd"]:
+-        return
+-    
+-    if hasattr(conduit, 'registerPackageName'):
+-        conduit.registerPackageName(__package_name__)
+-    conduit.info(2, 'Limiting package lists to security relevant ones')
+-    
+-    md_info = ysp_gen_metadata(conduit.getRepos().listEnabled())
+-
+-    def ysp_del_pkg(pkg):
+-        """ Deletes a package from all trees that yum knows about """
+-        conduit.info(3," --> %s from %s excluded (non-security)" %
+-                     (pkg,pkg.repoid))
+-        conduit.delPackage(pkg)
+-
+-    opts.sec_cmds = []
+-    used_map = ysp_gen_used_map(opts)
+-
+-    # The official API is:
+-    #
+-    # pkgs = conduit.getPackages()
+-    #
+-    # ...however that is _extremely_ slow, deleting all packages. So we ask
+-    # for the list of update packages, which is all we care about.    
+-    upds = conduit._base.doPackageLists(pkgnarrow='updates')
+-    pkgs = upds.updates
+-    # In theory we don't need to do this in some cases, but meh.
+-    upds = conduit._base.doPackageLists(pkgnarrow='obsoletes')
+-    pkgs += upds.obsoletes
+-
+-    name2tup = _get_name2oldpkgtup(conduit._base)
+-    
+-    tot = 0
+-    cnt = 0
+-    for pkg in pkgs:
+-        tot += 1
+-        name = pkg.name
+-        if (name not in name2tup or
+-            not ysp_should_keep_pkg(opts, name2tup[name], md_info, used_map)):
+-            ysp_del_pkg(pkg)
+-            continue
+-        cnt += 1
+-
+-    ysp_chk_used_map(used_map, lambda x: conduit.error(2, x))
+-    if cnt:
+-        conduit.info(2, '%d package(s) needed for security, out of %d available' % (cnt, tot))
+-    else:
+-        conduit.info(2, 'No packages needed for security; %d packages available' % tot)
+-
+-    _check_running_kernel(conduit._base, md_info, lambda x: conduit.info(2, x))
+-
+-def _check_running_kernel(yb, md_info, msg):
+-    if not hasattr(yum.misc, 'get_running_kernel_pkgtup'):
+-        return # Back compat.
+-
+-    kern_pkgtup = yum.misc.get_running_kernel_pkgtup(yb.ts)
+-    if kern_pkgtup[0] is None:
+-        return
+-
+-    found_sec = False
+-    for (pkgtup, notice) in md_info.get_applicable_notices(kern_pkgtup):
+-        if found_sec or notice['type'] != 'security':
+-            continue
+-        found_sec = True
+-        ipkg = yb.rpmdb.searchPkgTuple(pkgtup)
+-        if not ipkg:
+-            continue # Not installed
+-        ipkg = ipkg[0]
+-
+-        e = ''
+-        if kern_pkgtup[2] != '0':
+-            e = '%s:' % kern_pkgtup[2]
+-        rpkg = '%s-%s%s-%s.%s' % (kern_pkgtup[0], e,
+-                                  kern_pkgtup[3], kern_pkgtup[4],
+-                                  kern_pkgtup[1])
+-
+-        msg('Security: %s is an installed security update' % ipkg)
+-        msg('Security: %s is the currently running version' % rpkg)
+-        break
+-
+-
+-def preresolve_hook(conduit):
+-    '''
+-    Yum Plugin PreResolve Hook:
+-    Check and remove packages that don\'t align with the security config.
+-    '''
+-
+-    opts, info = ysp_check_func_enter(conduit)
+-    if info["skip"]:
+-        return
+-
+-    if info["list_cmd"]:
+-        return
+-    
+-    if hasattr(conduit, 'registerPackageName'):
+-        conduit.registerPackageName(__package_name__)
+-    conduit.info(2, 'Limiting packages to security relevant ones')
+-
+-    md_info = ysp_gen_metadata(conduit.getRepos().listEnabled())
+-
+-    def ysp_del_pkg(tspkg):
+-        """ Deletes a package within a transaction. """
+-        conduit.info(3," --> %s from %s excluded (non-security)" %
+-                     (tspkg.po,tspkg.po.repoid))
+-        tsinfo.remove(tspkg.pkgtup)
+-
+-    tot = 0
+-    cnt = 0
+-    opts.sec_cmds = []
+-    used_map = ysp_gen_used_map(opts)
+-    tsinfo = conduit.getTsInfo()
+-    tspkgs = tsinfo.getMembers()
+-    #  Ok, here we keep any pkgs that pass "ysp" tests, then we keep all
+-    # related pkgs ... Ie. "installed" version marked for removal.
+-    keep_pkgs = set()
+-
+-    count_states = set(TS_INSTALL_STATES + [TS_ERASE])
+-    count_pkgs = set()
+-    for tspkg in tspkgs:
+-        if tspkg.output_state in count_states:
+-            count_pkgs.add(tspkg.po)
+-
+-    name2tup = _get_name2oldpkgtup(conduit._base)
+-    for tspkg in tspkgs:
+-        if tspkg.output_state in count_states:
+-            tot += 1
+-        name = tspkg.po.name
+-        if (name not in name2tup or
+-            not ysp_should_keep_pkg(opts, name2tup[name], md_info, used_map)):
+-            continue
+-        if tspkg.output_state in count_states:
+-            cnt += 1
+-        keep_pkgs.add(tspkg.po)
+-
+-    scnt = cnt
+-    mini_depsolve_again = True
+-    while mini_depsolve_again:
+-        mini_depsolve_again = False
+-
+-        for tspkg in tspkgs:
+-            if tspkg.po in keep_pkgs:
+-                # Find any related pkgs, and add them:
+-                for (rpkg, reason) in tspkg.relatedto:
+-                    if rpkg not in keep_pkgs:
+-                        if rpkg in count_pkgs:
+-                            cnt += 1
+-                        keep_pkgs.add(rpkg)
+-                        mini_depsolve_again = True
+-            else:
+-                # If related to any keep pkgs, add us
+-                for (rpkg, reason) in tspkg.relatedto:
+-                    if rpkg in keep_pkgs:
+-                        if rpkg in count_pkgs:
+-                            cnt += 1
+-                        keep_pkgs.add(tspkg.po)
+-                        mini_depsolve_again = True
+-                        break
+-
+-    for tspkg in tspkgs:
+-        if tspkg.po not in keep_pkgs:
+-            ysp_del_pkg(tspkg)
+-
+-    ysp_chk_used_map(used_map, lambda x: conduit.error(2, x))
+-    
+-    if cnt:
+-        conduit.info(2, '%d package(s) needed (+%d related) for security, out of %d available' % (scnt, cnt - scnt, tot))
+-    else:
+-        conduit.info(2, 'No packages needed for security; %d packages available' % tot)
+-
+-if __name__ == '__main__':
+-    print "This is a plugin that is supposed to run from inside YUM"
+diff --git a/po/POTFILES.in b/po/POTFILES.in
+index d85030c..2f12118 100644
+--- a/po/POTFILES.in
++++ b/po/POTFILES.in
+@@ -34,7 +34,6 @@ plugins/merge-conf/merge-conf.py
+ plugins/aliases/aliases.py
+ plugins/protectbase/protectbase.py
+ plugins/versionlock/versionlock.py
+-plugins/security/security.py
+ plugins/nofsync/nofsync.py
+ plugins/tmprepo/tmprepo.py
+ plugins/priorities/priorities.py
+diff --git a/yum-utils.spec b/yum-utils.spec
+index 6d6d699..de6fbfd 100644
+--- a/yum-utils.spec
++++ b/yum-utils.spec
+@@ -155,20 +155,6 @@ This yum plugin adds the "--merge-conf" command line option. With this option,
+ Yum will ask you what to do with config files which have changed on updating a
+ package.
+ 
+-%package -n yum-plugin-security
+-Summary: Yum plugin to enable security filters
+-Group: System Environment/Base
+-Provides: yum-security = %{version}-%{release}
+-Obsoletes: yum-security < 1.1.20-0
+-Conflicts: yum-security < 1.1.20-0
+-Requires: yum >= 3.2.18
+-
+-%description -n yum-plugin-security
+-This plugin adds the options --security, --cve, --bz and --advisory flags
+-to yum and the list-security and info-security commands.
+-The options make it possible to limit list/upgrade of packages to specific
+-security relevant ones. The commands give you the security information.
+-
+ %package -n yum-plugin-upgrade-helper
+ Summary: Yum plugin to help upgrades to the next distribution version
+ Group: System Environment/Base
+@@ -396,7 +382,6 @@ plugins="\
+  tsflags \
+  priorities \
+  merge-conf \
+- security \
+  upgrade-helper \
+  aliases \
+  list-data \
+@@ -565,13 +550,6 @@ fi
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/merge-conf.conf
+ %{pluginhome}/merge-conf.*
+ 
+-%files -n yum-plugin-security
+-%defattr(-, root, root)
+-%doc COPYING
+-%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/security.conf
+-%{pluginhome}/security.*
+-%{_mandir}/man8/yum-security.8.*
+-
+ %files -n yum-plugin-upgrade-helper
+ %defattr(-, root, root)
+ %doc COPYING
diff --git a/SOURCES/BZ-1024070-yum-builddep-requires-source-repos-disabled.patch b/SOURCES/BZ-1024070-yum-builddep-requires-source-repos-disabled.patch
new file mode 100644
index 0000000..0a439b4
--- /dev/null
+++ b/SOURCES/BZ-1024070-yum-builddep-requires-source-repos-disabled.patch
@@ -0,0 +1,66 @@
+commit 8d1f2b4a8ba6306152c25591ab6b14b6ad9915bd
+Author: Zdenek Pavlas <zpavlas@redhat.com>
+Date:   Fri Jan 17 14:45:46 2014 +0100
+
+    yum-builddep: Use srpms in already enabled repos. BZ 1024070
+    
+    Enable "src" arch first, then source repos, then init sacks.
+    Fixes BZ and we don't have to disable/enable to change arches.
+
+diff --git a/yum-builddep.py b/yum-builddep.py
+index b9e682a..216066e 100755
+--- a/yum-builddep.py
++++ b/yum-builddep.py
+@@ -92,6 +92,10 @@ class YumBuildDep(YumUtilBase):
+             self.logger.error("Error: You must be root to install packages")
+             sys.exit(1)
+ 
++        # Use source rpms
++        self.arch.archlist.append('src')
++        self.setupSourceRepos()
++
+         # Setup yum (Ts, RPM db, Repo & Sack)
+         self.doUtilYumSetup()
+         # Do the real action
+@@ -122,7 +126,6 @@ class YumBuildDep(YumUtilBase):
+         
+     def setupSourceRepos(self):
+         # enable the -source repos for enabled primary repos
+-        archlist = rpmUtils.arch.getArchList() + ['src']    
+         for repo in self.repos.listEnabled():
+             issource_repo = repo.id.endswith('-source')
+             if rhn_source_repos and repo.id.endswith('-source-rpms'):
+@@ -133,24 +136,13 @@ class YumBuildDep(YumUtilBase):
+             elif not issource_repo:
+                 srcrepo = '%s-source' % repo.id
+             else:
+-                # Need to change the arch.
+-                repo.close()
+-                self.repos.disableRepo(repo.id)
+-                srcrepo = repo.id
++                continue
+             
+             for r in self.repos.findRepos(srcrepo):
+                 if r in self.repos.listEnabled():
+                     continue
+                 self.logger.info('Enabling %s repository' % r.id)
+                 r.enable()
+-                # Setup the repo, without a cache
+-                r.setup(0)
+-                # Setup pkgSack with 'src' in the archlist
+-                try:
+-                    self._getSacks(archlist=archlist,thisrepo=r.id)
+-                except yum.Errors.RepoError, e:
+-                    print "Could not setup repo %s: %s" % (r.id, e)
+-                    sys.exit(1)
+ 
+     def install_deps(self, deplist):
+         errors = set()
+@@ -213,7 +205,6 @@ class YumBuildDep(YumUtilBase):
+ 
+         toActOn = []     
+         if srcnames:
+-            self.setupSourceRepos()
+             pkgs = self.pkgSack.returnPackages(patterns=srcnames)
+             exact, match, unmatch = yum.packages.parsePackages(pkgs, srcnames, casematch=1)
+             srpms += exact + match
diff --git a/SOURCES/BZ-1050218-YumBaseError-not-defined.patch b/SOURCES/BZ-1050218-YumBaseError-not-defined.patch
new file mode 100644
index 0000000..87224df
--- /dev/null
+++ b/SOURCES/BZ-1050218-YumBaseError-not-defined.patch
@@ -0,0 +1,12 @@
+diff -up yum-utils-1.1.31/repoquery.py.old yum-utils-1.1.31/repoquery.py
+--- yum-utils-1.1.31/repoquery.py.old	2014-01-10 11:43:02.213877563 +0100
++++ yum-utils-1.1.31/repoquery.py	2014-01-10 11:45:52.755169727 +0100
+@@ -1412,7 +1412,7 @@ def main(args):
+     repoq.preconf.root = opts.installroot
+     try:
+         repoq.conf
+-    except YumBaseError, e:
++    except yum.Errors.YumBaseError, e:
+         repoq.logger.error(e)
+         sys.exit(1)
+ 
diff --git a/SOURCES/BZ-1052871-debuginfo-install-wrong-repo-suffix.patch b/SOURCES/BZ-1052871-debuginfo-install-wrong-repo-suffix.patch
new file mode 100644
index 0000000..ca3ce5f
--- /dev/null
+++ b/SOURCES/BZ-1052871-debuginfo-install-wrong-repo-suffix.patch
@@ -0,0 +1,16 @@
+diff --git a/debuginfo-install.py b/debuginfo-install.py
+index 0f026f1..bb61a1d 100755
+--- a/debuginfo-install.py
++++ b/debuginfo-install.py
+@@ -86,7 +86,10 @@ class DebugInfoInstall(YumUtilBase):
+         for repo in self.repos.listEnabled():
+             repos[repo.id] = repo
+         for repoid in repos:
+-            di = '%s-debuginfo' % repoid
++            if repoid.endswith('-rpms'):
++                di = repoid[:-5] + '-debug-rpms'
++            else:
++                di = '%s-debuginfo' % repoid
+             if di in repos:
+                 continue
+             repo = repos[repoid]
diff --git a/SOURCES/BZ-1060702-reposync-nonexistent-repo.patch b/SOURCES/BZ-1060702-reposync-nonexistent-repo.patch
new file mode 100644
index 0000000..33f71e4
--- /dev/null
+++ b/SOURCES/BZ-1060702-reposync-nonexistent-repo.patch
@@ -0,0 +1,30 @@
+commit fbdc19f411ee31bf18af242e7b3b39947ed28f2d
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Thu Feb 13 15:30:23 2014 +0100
+
+     Fix 'reposync -r nosuchrepo' behaviour. BZ 1060702
+    
+    Show a warning if user-provided repoid was not found and
+    exit(1) if none of user-provided repoids were found.
+
+diff --git a/reposync.py b/reposync.py
+index b1ee285..e7c98a3 100755
+--- a/reposync.py
++++ b/reposync.py
+@@ -179,7 +179,15 @@ def main():
+         
+         # find the ones we want
+         for glob in opts.repoid:
+-            myrepos.extend(my.repos.findRepos(glob))
++            add_repos = my.repos.findRepos(glob)
++            if not add_repos:
++                print >> sys.stderr, "Warning: cannot find repository %s" % glob
++                continue
++            myrepos.extend(add_repos)
++
++        if not myrepos:
++            print >> sys.stderr, "No repositories found"
++            sys.exit(1)
+         
+         # disable them all
+         for repo in my.repos.repos.values():
diff --git a/SOURCES/BZ-1075708-yum-config-manager-config-file-update.patch b/SOURCES/BZ-1075708-yum-config-manager-config-file-update.patch
new file mode 100644
index 0000000..c85ce91
--- /dev/null
+++ b/SOURCES/BZ-1075708-yum-config-manager-config-file-update.patch
@@ -0,0 +1,37 @@
+commit 2b617b86358aeedd3ed83fad0719cb0fada3241c
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Tue May 26 09:08:37 2015 +0200
+
+    yum-config-manager: update config file specified using -c option. BZ#1075708
+
+diff --git a/README b/README
+index 8abe805..0c01d0e 100644
+--- a/README
++++ b/README
+@@ -67,3 +67,5 @@ Author of the update on boot init scripts
+ - Tim Lauridsen
+ Maintainer of yum-utils - fixer of a lot of misc utils.
+ 
++- Valentina Mukhamedzhanova
++Maintainer of yum-utils.
+diff --git a/yum-config-manager.py b/yum-config-manager.py
+index 380a54f..708c33f 100755
+--- a/yum-config-manager.py
++++ b/yum-config-manager.py
+@@ -155,10 +155,13 @@ if (not args and not opts.addrepo) or 'main' in args:
+     print yb.fmtSection('main')
+     print yb.conf.dump()
+     if opts.save and hasattr(yb, 'main_setopts') and yb.main_setopts:
+-        fn = '/etc/yum/yum.conf'
++        fn = opts.conffile
+         if not os.path.exists(fn):
+-            # Try the old default
+-            fn = '/etc/yum.conf'
++            if fn == '/etc/yum/yum.conf':
++                # Try the old default
++                fn = '/etc/yum.conf'
++            else:
++                raise yum.Errors.ConfigError("Error accessing file for config %s" % fn)
+         ybc = yb.conf
+         writeRawConfigFile(fn, 'main', ybc.yumvar,
+                            ybc.cfg.options, ybc.iteritems, ybc.optionobj,
diff --git a/SOURCES/BZ-1082050-source-repos.patch b/SOURCES/BZ-1082050-source-repos.patch
new file mode 100644
index 0000000..6727a14
--- /dev/null
+++ b/SOURCES/BZ-1082050-source-repos.patch
@@ -0,0 +1,32 @@
+Index: /yum-builddep.py
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- /yum-builddep.py	(revision )
++++ /yum-builddep.py	(revision )
+@@ -27,7 +27,7 @@
+ import rpmUtils
+ import rpm
+ 
+-rhn_source_repos = False
++rhn_source_repos = True
+ 
+ # Copied from yumdownloader (need a yum-utils python module ;)
+ # This is to fix Bug 469
+Index: /yumdownloader.py
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- /yumdownloader.py	(revision )
++++ /yumdownloader.py	(revision )
+@@ -32,7 +32,7 @@
+ import rpmUtils
+ import logging
+ 
+-rhn_source_repos = False
++rhn_source_repos = True
+ 
+ # This is to fix Bug 469
+ # To convert from a pkg to a source pkg, we have a problem in that all we have
diff --git a/SOURCES/BZ-1091698-fs-snapshot-obsolete-btrfsctl.patch b/SOURCES/BZ-1091698-fs-snapshot-obsolete-btrfsctl.patch
new file mode 100644
index 0000000..ed21715
--- /dev/null
+++ b/SOURCES/BZ-1091698-fs-snapshot-obsolete-btrfsctl.patch
@@ -0,0 +1,36 @@
+commit 92fd923f75f1f42d246e925f1c4526f36f6fd88d
+Author: Stephen Degler <stephen@degler.net>
+Date:   Tue Sep 24 17:06:14 2013 +0200
+
+    fs-snapshot: btrfsctl is obsolete, use btrfs. BZ 1010974
+
+diff --git a/plugins/fs-snapshot/fs-snapshot.py b/plugins/fs-snapshot/fs-snapshot.py
+index 4f99b6a..786b0c1 100644
+--- a/plugins/fs-snapshot/fs-snapshot.py
++++ b/plugins/fs-snapshot/fs-snapshot.py
+@@ -198,9 +198,8 @@ def _create_btrfs_snapshot(conduit, snapshot_tag, volume):
+     """
+     Runs the commands necessary for a snapshot.  Basically its just
+ 
+-    btrfsctl -c /dir/to/snapshot    #this syncs the fs
+-    btrfsctl -s /dir/to/snapshot/${snapshot_tag}
+-                /dir/to/snapshot
++    btrfs filesystem sync /dir/to/snapshot    #this syncs the fs
++    btrfs subvolume snapshot /dir/to/snapshot /dir/to/snapshot/${snapshot_tag}
+ 
+     and then we're done.
+     """
+@@ -212,11 +211,11 @@ def _create_btrfs_snapshot(conduit, snapshot_tag, volume):
+ 
+     snapname = mntpnt + snapshot_tag
+     conduit.info(1, "fs-snapshot: snapshotting " + mntpnt + ": " + snapname)
+-    p = Popen(["/sbin/btrfsctl", "-c", mntpnt], stdout=PIPE, stderr=PIPE)
++    p = Popen(["/sbin/btrfs", "filesystem", "sync", mntpnt], stdout=PIPE, stderr=PIPE)
+     err = p.wait()
+     if err:
+         return 1
+-    p = Popen(["/sbin/btrfsctl", "-s", snapname, mntpnt], stdout=PIPE, stderr=PIPE)
++    p = Popen(["/sbin/btrfs", "subvolume", "snapshot", mntpnt, snapname], stdout=PIPE, stderr=PIPE)
+     err = p.wait()
+     if err:
+         return 1
diff --git a/SOURCES/BZ-1095150-needs-restarting-fixes.patch b/SOURCES/BZ-1095150-needs-restarting-fixes.patch
new file mode 100644
index 0000000..cf1a294
--- /dev/null
+++ b/SOURCES/BZ-1095150-needs-restarting-fixes.patch
@@ -0,0 +1,54 @@
+diff -up yum-utils-1.1.31/needs-restarting.py.old yum-utils-1.1.31/needs-restarting.py
+--- yum-utils-1.1.31/needs-restarting.py.old	2014-09-04 14:19:27.000000000 +0200
++++ yum-utils-1.1.31/needs-restarting.py	2014-09-04 14:29:47.825438668 +0200
+@@ -44,6 +44,8 @@ import yum.misc
+ import glob
+ import stat
+ from optparse import OptionParser
++sys.path.insert(0,'/usr/share/yum-cli')
++import utils
+ 
+ def parseargs(args):
+     usage = """
+@@ -77,7 +79,8 @@ def get_open_files(pid):
+     files = []
+     smaps = '/proc/%s/smaps' % pid
+     try:
+-        maps = open(smaps, 'r').readlines()
++        with open(smaps, 'r') as maps_f:
++            maps = maps_f.readlines()
+     except (IOError, OSError), e:
+         print "Could not open %s" % smaps
+         return files
+@@ -88,7 +91,7 @@ def get_open_files(pid):
+             continue
+         line = line.replace('\n', '')
+         filename = line[slash:]
+-        #filename = filename.replace('(deleted)', '') #only mildly retarded
++        filename = filename.split(';')[0]
+         filename = filename.strip()
+         if filename not in files:
+             files.append(filename)
+@@ -109,10 +112,11 @@ def main(args):
+     
+     needing_restart = set()
+ 
++    boot_time = utils.get_boot_time()
+     for pid in return_running_pids(uid=myuid):
+         try:
+-            pid_start = os.stat('/proc/' + pid)[stat.ST_CTIME]
+-        except OSError, e:
++            pid_start = utils.get_process_time(int(pid), boot_time)['start_time']
++        except (OSError, IOError), e:
+             continue
+         found_match = False
+         for fn in get_open_files(pid):
+@@ -158,7 +162,7 @@ def main(args):
+     for pid in needing_restart:
+         try:
+             cmdline = open('/proc/' +pid+ '/cmdline', 'r').read()
+-        except OSError, e:
++        except (OSError, IOError), e:
+             print "Couldn't access process information for %s: %s" % (pid, str(e))
+             continue
+         # proc cmdline is null-delimited so clean that up
diff --git a/SOURCES/BZ-1104995-yumdownloader-redownloading-existing-rpms.patch b/SOURCES/BZ-1104995-yumdownloader-redownloading-existing-rpms.patch
new file mode 100644
index 0000000..02cba4f
--- /dev/null
+++ b/SOURCES/BZ-1104995-yumdownloader-redownloading-existing-rpms.patch
@@ -0,0 +1,38 @@
+commit 682227430bb2124fb2897371fa5bc5261099064a
+Author: Zdenek Pavlas <zpavlas@redhat.com>
+Date:   Mon Sep 9 15:15:35 2013 +0200
+
+    yumdownloader: make --destdir less of a hack. BZ 1004089
+    
+    Instead of changing po.localpath, use the conf.downloaddir option
+    already used to override repo.pkgdir(s).
+
+diff --git a/yumdownloader.py b/yumdownloader.py
+index 4c5eefb..b491c7f 100755
+--- a/yumdownloader.py
++++ b/yumdownloader.py
+@@ -96,6 +96,9 @@ class YumDownloader(YumUtilBase):
+         if not self.setCacheDir():
+             self.logger.error("Error: Could not make cachedir, exiting")
+             sys.exit(50)
++
++        # override all pkgdirs
++        self.conf.downloaddir = opts.destdir
+             
+         # Setup yum (Ts, RPM db, Repo & Sack)
+         self.doUtilYumSetup(opts)
+@@ -202,14 +205,8 @@ class YumDownloader(YumUtilBase):
+                 print urljoin(pkg.repo.urls[0], pkg.relativepath)
+             return 0
+ 
+-        # create dest dir
+-        if not os.path.exists(opts.destdir):
+-            os.makedirs(opts.destdir)
+-
+         # set localpaths
+         for pkg in toDownload:
+-            rpmfn = os.path.basename(pkg.remote_path)
+-            pkg.localpath = os.path.join(opts.destdir, rpmfn)
+             pkg.repo.copy_local = True
+             pkg.repo.cache = 0
+ 
diff --git a/SOURCES/BZ-1107658-needs-restarting-graceful-error.patch b/SOURCES/BZ-1107658-needs-restarting-graceful-error.patch
new file mode 100644
index 0000000..611ea6f
--- /dev/null
+++ b/SOURCES/BZ-1107658-needs-restarting-graceful-error.patch
@@ -0,0 +1,39 @@
+diff -up yum-utils-1.1.31/needs-restarting.py.old yum-utils-1.1.31/needs-restarting.py
+--- yum-utils-1.1.31/needs-restarting.py.old	2014-09-18 10:17:13.000000000 +0200
++++ yum-utils-1.1.31/needs-restarting.py	2014-09-18 10:22:41.596236067 +0200
+@@ -44,6 +44,7 @@ import yum.misc
+ import glob
+ import stat
+ from optparse import OptionParser
++from yum.Errors import RepoError
+ sys.path.insert(0,'/usr/share/yum-cli')
+ import utils
+ 
+@@ -82,7 +83,7 @@ def get_open_files(pid):
+         with open(smaps, 'r') as maps_f:
+             maps = maps_f.readlines()
+     except (IOError, OSError), e:
+-        print "Could not open %s" % smaps
++        print >>sys.stderr, "Could not open %s" % smaps
+         return files
+ 
+     for line in maps:
+@@ -164,7 +165,7 @@ def main(args):
+         try:
+             cmdline = open('/proc/' +pid+ '/cmdline', 'r').read()
+         except (OSError, IOError), e:
+-            print "Couldn't access process information for %s: %s" % (pid, str(e))
++            print >>sys.stderr, "Couldn't access process information for %s: %s" % (pid, str(e))
+             continue
+         # proc cmdline is null-delimited so clean that up
+         cmdline = cmdline.replace('\000', ' ')
+@@ -173,4 +174,8 @@ def main(args):
+     return 0
+     
+ if __name__ == "__main__":
+-    sys.exit(main(sys.argv))
++    try:
++        sys.exit(main(sys.argv))
++    except RepoError, e:
++        print >>sys.stderr, e
++        sys.exit(1)
diff --git a/SOURCES/BZ-1113391-yumdownloader-depsolving-errors.patch b/SOURCES/BZ-1113391-yumdownloader-depsolving-errors.patch
new file mode 100644
index 0000000..cd90499
--- /dev/null
+++ b/SOURCES/BZ-1113391-yumdownloader-depsolving-errors.patch
@@ -0,0 +1,23 @@
+commit 36280feaee2b0cfb83d8af134f6aff3bcc976af1
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Wed Apr 9 15:30:21 2014 +0200
+
+    Print depsolving errors in yumdownloader instead of ignoring them. BZ 998892
+
+diff --git a/yumdownloader.py b/yumdownloader.py
+index 1b57777..1b95e8d 100755
+--- a/yumdownloader.py
++++ b/yumdownloader.py
+@@ -197,7 +197,11 @@ class YumDownloader(YumUtilBase):
+                 self.tsInfo.addInstall(po)
+                 self.localPackages.append(po)
+             # Resolve dependencies
+-            self.resolveDeps()
++            result, resultmsgs = self.resolveDeps()
++            if result == 1:
++                for msg in resultmsgs:
++                    self.logger.critical(msg)
++                self.logger.critical('Dependency resolution failed, some packages will not be downloaded.')
+             # Add newly added packages to the toDownload list
+             for pkg in self.tsInfo.getMembers():
+                 if pkg.ts_state in ('i', 'u') and pkg.po not in toDownload:
diff --git a/SOURCES/BZ-1121714-reposync-manpage-missing-switches.patch b/SOURCES/BZ-1121714-reposync-manpage-missing-switches.patch
new file mode 100644
index 0000000..b74d0d2
--- /dev/null
+++ b/SOURCES/BZ-1121714-reposync-manpage-missing-switches.patch
@@ -0,0 +1,44 @@
+From 4833f65fd4b9bd06a9a5e00fb8bc986ad33273e4 Mon Sep 17 00:00:00 2001
+From: Jan Chaloupka <jchaloup@redhat.com>
+Date: Mon, 25 Aug 2014 08:57:22 +0200
+Subject: [PATCH] reposync.1 missing options
+
+---
+ docs/reposync.1 | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/docs/reposync.1 b/docs/reposync.1
+index 29043fb..d6d245a 100644
+--- a/docs/reposync.1
++++ b/docs/reposync.1
+@@ -20,10 +20,18 @@ Also download .src.rpm files.
+ .IP "\fB\-r REPOID, \-\-repoid=REPOID\fP"
+ Specify repo ids to query, can be specified multiple times (default is
+ all enabled).
++.IP "\fB\-e\ CACHEDIR, \-\-cachedir CACHEDIR\fP"
++Directory in which to store metadata.
+ .IP "\fB\-t, \-\-tempcache\fP"
+ Use a temp dir for storing/accessing yum-cache.
++.IP "\fB\-d, \-\-delete\fP"
++Delete local packages no longer present in repository.
+ .IP "\fB\-p DESTDIR, \-\-download_path=DESTDIR\fP"
+ Path to download packages to: defaults to current directory.
++.IP "\fB\-\-norepopath\fP"
++Don't add the reponame to the download path.
++Can only be used when syncing a single repository (default is
++to add the reponame).
+ .IP "\fB\-g, \-\-gpgcheck\fP"
+ Remove packages that fail GPG signature checking after downloading.
+ exit status is '1' if at least one package was removed.
+@@ -31,6 +39,8 @@ exit status is '1' if at least one package was removed.
+ Just list urls of what would be downloaded, don't download.
+ .IP "\fB\-l, \-\-plugins\fP"
+ Enable yum plugin support.
++.IP "\fB\-m, \-\-downloadcomps\fP"
++Also download comps.xml.
+ .IP "\fB\-n, \-\-newest\-only\fP"
+ Download only newest packages per-repo.
+ .IP "\fB\-q, \-\-quiet\fP"
+-- 
+1.9.3
+
diff --git a/SOURCES/BZ-1127782-post-transaction-action.patch b/SOURCES/BZ-1127782-post-transaction-action.patch
new file mode 100644
index 0000000..bed3880
--- /dev/null
+++ b/SOURCES/BZ-1127782-post-transaction-action.patch
@@ -0,0 +1,60 @@
+commit d317fd0d8f56eb352c7dbb78bc283c208da9a561
+Author: Zdenek Pavlas <zpavlas@redhat.com>
+Date:   Tue Jan 14 12:08:43 2014 +0100
+
+    post-transaction-actions: fix filename matching. BZ 1045494
+    
+    I believe the code now works as origanally intended. When installing
+    packages, txmbr.po is AvailablePackage instance and .filelist access
+    may trigger filelist metadata download.
+    
+    Since this runs after the transaction, we may look the package up
+    in rpmdb instead.  On removals, thispo is RPMInstalledPackage already.
+    Thanks to Robert Tomczyk <robert.x.tomczyk@gmail.com> for reporting
+    and testing this.
+
+diff --git a/plugins/post-transaction-actions/post-transaction-actions.py b/plugins/post-transaction-actions/post-transaction-actions.py
+index b4da1ce..804af9c 100644
+--- a/plugins/post-transaction-actions/post-transaction-actions.py
++++ b/plugins/post-transaction-actions/post-transaction-actions.py
+@@ -129,8 +129,10 @@ def posttrans_hook(conduit):
+ 
+             for txmbr in pkgset:
+                 matched = False
+-                #print '%s - %s' % txmbr.name, txmbr.ts_state
+-                if txmbr.po.state in TS_INSTALL_STATES:
++                thispo = txmbr.po
++                if txmbr.output_state in TS_INSTALL_STATES:
++                    # thispo is AvailablePackage; filelist access could trigger download
++                    # of the filelist.  Since it's installed now, use rpmdb data instead.
+                     thispo = _get_installed_po(rpmdb, txmbr.pkgtup)
+         
+                 if not yum.misc.re_glob(a_k):
+commit 78cfff9b48608ad246a8898d002937d9b6ffcc5d
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Wed Aug 20 17:31:16 2014 +0200
+
+    post-transaction-actions: preload filelists for packages to be removed. BZ 1127782
+
+diff --git a/plugins/post-transaction-actions/post-transaction-actions.py b/plugins/post-transaction-actions/post-transaction-actions.py
+index 804af9c..4d015c1 100644
+--- a/plugins/post-transaction-actions/post-transaction-actions.py
++++ b/plugins/post-transaction-actions/post-transaction-actions.py
+@@ -93,6 +93,17 @@ def _convert_vars(txmbr, command):
+     result = varReplace(command, vardict)
+     return result
+             
++
++def pretrans_hook(conduit):
++    # Prefetch filelist for packages to be removed,
++    # otherwise for updated packages headers will not be available
++    ts = conduit.getTsInfo()
++    removes = ts.getMembersWithState(output_states=TS_REMOVE_STATES)
++
++    for txmbr in removes:
++        txmbr.po.filelist
++
++
+ def posttrans_hook(conduit):
+     # we have provides/requires for everything
+     # we do not have filelists for erasures
diff --git a/SOURCES/BZ-1127783-transaction-actions-fix-file-globs.patch b/SOURCES/BZ-1127783-transaction-actions-fix-file-globs.patch
new file mode 100644
index 0000000..718c55c
--- /dev/null
+++ b/SOURCES/BZ-1127783-transaction-actions-fix-file-globs.patch
@@ -0,0 +1,83 @@
+diff -up yum-utils-1.1.31/plugins/post-transaction-actions/post-transaction-actions.py.orig yum-utils-1.1.31/plugins/post-transaction-actions/post-transaction-actions.py
+--- yum-utils-1.1.31/plugins/post-transaction-actions/post-transaction-actions.py.orig	2017-11-03 16:26:49.762703946 +0100
++++ yum-utils-1.1.31/plugins/post-transaction-actions/post-transaction-actions.py	2017-11-03 16:26:53.607688349 +0100
+@@ -139,7 +139,6 @@ def posttrans_hook(conduit):
+                 c_string = re.compile(restring)
+ 
+             for txmbr in pkgset:
+-                matched = False
+                 thispo = txmbr.po
+                 if txmbr.output_state in TS_INSTALL_STATES:
+                     # thispo is AvailablePackage; filelist access could trigger download
+@@ -150,17 +149,13 @@ def posttrans_hook(conduit):
+                     if a_k in thispo.filelist + thispo.dirlist + thispo.ghostlist:
+                         thiscommand = _convert_vars(txmbr, a_c)
+                         commands_to_run[thiscommand] = 1
+-                        matched = True
++                        break
+                 else:
+                     for name in thispo.filelist + thispo.dirlist + thispo.ghostlist:
+                         if c_string.match(name):
+                             thiscommand = _convert_vars(txmbr, a_c)
+                             commands_to_run[thiscommand] = 1
+-                            matched = True
+                             break
+-                
+-                if matched:
+-                    break
+             continue
+         
+         if a_k.find('/') == -1: # pkgspec
+diff -up yum-utils-1.1.31/plugins/post-transaction-actions/sample.action.orig yum-utils-1.1.31/plugins/post-transaction-actions/sample.action
+--- yum-utils-1.1.31/plugins/post-transaction-actions/sample.action.orig	2011-08-10 17:20:19.000000000 +0200
++++ yum-utils-1.1.31/plugins/post-transaction-actions/sample.action	2017-11-03 16:26:53.607688349 +0100
+@@ -19,3 +19,8 @@ zsh:install:touch /tmp/zsh-installed-als
+ /bin/z*h:install:touch /tmp/bin-zsh-installed
+ z*h:any:touch /tmp/bin-zsh-any
+ 
++# each action is expanded once for each matching package, and no action is
++# executed twice per transaction, for example
++*:install:echo $repoid >>/tmp/repos
++# will write each repo only once to /tmp/repos, even if multiple packages from
++# the same repo were installed
+diff -up yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.py.orig yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.py
+--- yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.py.orig	2017-11-03 16:26:49.819703715 +0100
++++ yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.py	2017-11-03 16:26:53.609688341 +0100
+@@ -120,24 +120,19 @@ def pretrans_hook(conduit):
+                 c_string = re.compile(restring)
+ 
+             for txmbr in pkgset:
+-                matched = False
+                 thispo = txmbr.po
+         
+                 if not yum.misc.re_glob(a_k):
+                     if a_k in thispo.filelist + thispo.dirlist + thispo.ghostlist:
+                         thiscommand = _convert_vars(txmbr, a_c)
+                         commands_to_run[thiscommand] = 1
+-                        matched = True
++                        break
+                 else:
+                     for name in thispo.filelist + thispo.dirlist + thispo.ghostlist:
+                         if c_string.match(name):
+                             thiscommand = _convert_vars(txmbr, a_c)
+                             commands_to_run[thiscommand] = 1
+-                            matched = True
+                             break
+-                
+-                if matched:
+-                    break
+             continue
+         
+         if a_k.find('/') == -1: # pkgspec
+diff -up yum-utils-1.1.31/plugins/pre-transaction-actions/sample.action.orig yum-utils-1.1.31/plugins/pre-transaction-actions/sample.action
+--- yum-utils-1.1.31/plugins/pre-transaction-actions/sample.action.orig	2017-11-03 16:26:49.820703711 +0100
++++ yum-utils-1.1.31/plugins/pre-transaction-actions/sample.action	2017-11-03 16:26:53.609688341 +0100
+@@ -19,3 +19,8 @@ zsh:install:touch /tmp/zsh-installed-als
+ /bin/z*h:install:touch /tmp/bin-zsh-installed
+ z*h:any:touch /tmp/bin-zsh-any
+ 
++# each action is expanded once for each matching package, and no action is
++# executed twice per transaction, for example
++*:install:echo $repoid >>/tmp/repos
++# will write each repo only once to /tmp/repos, even if multiple packages from
++# the same repo are going to be installed
diff --git a/SOURCES/BZ-1129590-setopt-wildcards-save.patch b/SOURCES/BZ-1129590-setopt-wildcards-save.patch
new file mode 100644
index 0000000..33b4d45
--- /dev/null
+++ b/SOURCES/BZ-1129590-setopt-wildcards-save.patch
@@ -0,0 +1,32 @@
+diff -up yum-utils-1.1.31/yum-config-manager.py.old yum-utils-1.1.31/yum-config-manager.py
+--- yum-utils-1.1.31/yum-config-manager.py.old	2014-08-13 11:50:30.000000000 +0200
++++ yum-utils-1.1.31/yum-config-manager.py	2014-08-13 11:52:02.801755611 +0200
+@@ -7,6 +7,7 @@ import yum
+ sys.path.insert(0,'/usr/share/yum-cli')
+ from utils import YumUtilBase
+ import logging
++import fnmatch
+ 
+ from iniparse import INIConfig
+ 
+@@ -97,6 +98,11 @@ def writeRawConfigFile(filename, section
+     fp.write(str(ini))
+     fp.close()
+ 
++def match_repoid(repoid, repo_setopts):
++    for i in repo_setopts:
++        if fnmatch.fnmatch(repoid, i):
++            return True
++
+ NAME = 'yum-config-manager'
+ VERSION = '1.0'
+ USAGE = '"yum-config-manager [options] [section]'
+@@ -175,7 +181,7 @@ if not opts.addrepo:
+             repo.disable()
+         print repo.dump()
+         if (opts.save and
+-            (only or (hasattr(yb, 'repo_setopts') and repo.id in yb.repo_setopts))):
++            (only or (hasattr(yb, 'repo_setopts') and match_repoid(repo.id, yb.repo_setopts)))):
+             writeRawConfigFile(repo.repofile, repo.id, repo.yumvar,
+                                repo.cfg.options, repo.iteritems, repo.optionobj,
+                                only)
diff --git a/SOURCES/BZ-1133125-reposync-urls-for-all-repos.patch b/SOURCES/BZ-1133125-reposync-urls-for-all-repos.patch
new file mode 100644
index 0000000..3ec4edb
--- /dev/null
+++ b/SOURCES/BZ-1133125-reposync-urls-for-all-repos.patch
@@ -0,0 +1,19 @@
+commit 2cc8c240f6ea6ba7fae15721c9d7892024c65a8f
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Thu Aug 28 10:17:38 2014 +0200
+
+    reposync: show urls for all repos when using -u option. BZ 1133125
+
+diff --git a/reposync.py b/reposync.py
+index 6500db6..bb4c59d 100755
+--- a/reposync.py
++++ b/reposync.py
+@@ -283,7 +283,7 @@ def main():
+         if opts.urls:
+             for pkg in download_list:
+                 print urljoin(pkg.repo.urls[0], pkg.relativepath)
+-            return 0
++            continue
+ 
+         # create dest dir
+         if not os.path.exists(local_repo_path):
diff --git a/SOURCES/BZ-1134989-post-transaction-actions-allow-colons.patch b/SOURCES/BZ-1134989-post-transaction-actions-allow-colons.patch
new file mode 100644
index 0000000..3dcef1d
--- /dev/null
+++ b/SOURCES/BZ-1134989-post-transaction-actions-allow-colons.patch
@@ -0,0 +1,19 @@
+commit 8b046d7d18e0f582d9f703336d5c25a71cf02966
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Thu Aug 28 18:18:53 2014 +0200
+
+    yum-post-transaction-actions: allow colons in command part. BZ 1134989
+
+diff --git a/plugins/post-transaction-actions/post-transaction-actions.py b/plugins/post-transaction-actions/post-transaction-actions.py
+index 4d015c1..d59dc40 100644
+--- a/plugins/post-transaction-actions/post-transaction-actions.py
++++ b/plugins/post-transaction-actions/post-transaction-actions.py
+@@ -51,7 +51,7 @@ def parse_actions(ddir, conduit):
+                 line = line.strip()
+                 if line and line[0] != "#":
+                     try:
+-                        (a_key, a_state, a_command) = line.split(':')
++                        (a_key, a_state, a_command) = line.split(':', 2)
+                     except ValueError,e:
+                         conduit.error(2,'Bad Action Line: %s' % line)
+                         continue
diff --git a/SOURCES/BZ-1139032-reposync-directory-structure.patch b/SOURCES/BZ-1139032-reposync-directory-structure.patch
new file mode 100644
index 0000000..99c571f
--- /dev/null
+++ b/SOURCES/BZ-1139032-reposync-directory-structure.patch
@@ -0,0 +1,25 @@
+commit abdc5d04ca75357f7e2cf9852c4b6d3486cf8dd5
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Wed Sep 10 09:45:26 2014 +0200
+
+    reposync: preserve directory structure. BZ 1139032
+
+diff --git a/reposync.py b/reposync.py
+index bb4c59d..eb8ab21 100755
+--- a/reposync.py
++++ b/reposync.py
+@@ -291,10 +291,13 @@ def main():
+ 
+         # set localpaths
+         for pkg in download_list:
+-            rpmfn = os.path.basename(pkg.remote_path)
++            rpmfn = pkg.remote_path
+             pkg.localpath = os.path.join(local_repo_path, rpmfn)
+             pkg.repo.copy_local = True
+             pkg.repo.cache = 0
++            localdir = os.path.dirname(pkg.localpath)
++            if not os.path.exists(localdir):
++                os.makedirs(localdir)
+ 
+         # use downloader from YumBase
+         probs = my.downloadPkgs(download_list)
diff --git a/SOURCES/BZ-1140864-reposync-urls-option-ignores-downloaded.patch b/SOURCES/BZ-1140864-reposync-urls-option-ignores-downloaded.patch
new file mode 100644
index 0000000..477a40d
--- /dev/null
+++ b/SOURCES/BZ-1140864-reposync-urls-option-ignores-downloaded.patch
@@ -0,0 +1,15 @@
+diff -up yum-utils-1.1.31/reposync.py.old yum-utils-1.1.31/reposync.py
+--- yum-utils-1.1.31/reposync.py.old	2014-09-24 09:47:05.000000000 +0200
++++ yum-utils-1.1.31/reposync.py	2014-09-24 09:52:46.147944904 +0200
+@@ -293,7 +293,10 @@ def main():
+         download_list.sort(sortPkgObj)
+         if opts.urls:
+             for pkg in download_list:
+-                print urljoin(pkg.repo.urls[0], pkg.relativepath)
++                remote = pkg.returnSimple('relativepath')
++                local = os.path.join(local_repo_path, remote)
++                if not (os.path.exists(local) and my.verifyPkg(local, pkg, False)):
++                    print urljoin(pkg.repo.urls[0], pkg.relativepath)
+             continue
+ 
+         # create dest dir
diff --git a/SOURCES/BZ-1151154-yum-config-manager-disable-all-repos.patch b/SOURCES/BZ-1151154-yum-config-manager-disable-all-repos.patch
new file mode 100644
index 0000000..4609cf7
--- /dev/null
+++ b/SOURCES/BZ-1151154-yum-config-manager-disable-all-repos.patch
@@ -0,0 +1,23 @@
+commit b6e8afc8511262ca5405a084d806cdd5e52519c7
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Tue May 26 10:01:07 2015 +0200
+
+    yum-config-manager: require \* syntax to disable all repos. BZ#1151154
+
+diff --git a/yum-config-manager.py b/yum-config-manager.py
+index 708c33f..0531c72 100755
+--- a/yum-config-manager.py
++++ b/yum-config-manager.py
+@@ -146,8 +146,11 @@ if opts.enable and opts.disable:
+     logger.error("Error: Trying to enable and disable repos.")
+     opts.enable = opts.disable = False
+ if opts.enable and not args:
+-    logger.error("Error: Trying to enable already enabled repos.")
++    logger.error("Error: please specify repos to enable (\* to enable all).")
+     opts.enable = False
++if opts.disable and not args:
++    logger.error("Error: please specify repos to disable (\* to disable all).")
++    opts.disable = False
+ 
+ only = None
+ 
diff --git a/SOURCES/BZ-1156057-yum-builddep-manpage-arched-requires.patch b/SOURCES/BZ-1156057-yum-builddep-manpage-arched-requires.patch
new file mode 100644
index 0000000..825b27c
--- /dev/null
+++ b/SOURCES/BZ-1156057-yum-builddep-manpage-arched-requires.patch
@@ -0,0 +1,60 @@
+commit d9adda1589e131fa0d499432dcfc46b0a72ce519
+Author: Ville Skyttä <ville.skytta@iki.fi>
+Date:   Sat Feb 8 13:22:22 2014 +0200
+
+    yum-builddep: Note spec support in man page
+
+diff --git a/docs/yum-builddep.1 b/docs/yum-builddep.1
+index ac7601e..6cad8a6 100644
+--- a/docs/yum-builddep.1
++++ b/docs/yum-builddep.1
+@@ -9,7 +9,7 @@ yum-builddep \- install missing dependencies for building an RPM package
+ \fByum-builddep\fP is a program which installs the RPMs needed to build
+ the specified package.  The source RPM for the specified package must
+ be available in a Yum repository (which will be automatically enabled, if it is
+-disabled) or it can be a local source RPM file.
++disabled) or it can be a local source RPM or a spec file.
+ .PP 
+ .SH "EXAMPLES"
+ .IP "Download and install all the RPMs needed to build the kernel RPM:"
+commit c08a67e9923ea9c095d62ccb931c0b8a589e4b1e
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Tue Mar 1 18:08:32 2016 +0100
+
+    yum-builddep: mention the workaround for arched srpms in the man page. BZ#1156057
+
+diff --git a/docs/yum-builddep.1 b/docs/yum-builddep.1
+index 6cad8a6..fbe32bd 100644
+--- a/docs/yum-builddep.1
++++ b/docs/yum-builddep.1
+@@ -4,17 +4,28 @@
+ yum-builddep \- install missing dependencies for building an RPM package
+ .SH "SYNOPSIS"
+ \fByum-builddep\fP package
+-.SH "DESCRIPTION"
+ .PP 
++\fByum-builddep\fP /path/to/local/package.src.rpm
++.PP
++\fByum-builddep\fP /path/to/local/package.spec
++.SH "DESCRIPTION"
++.PP
+ \fByum-builddep\fP is a program which installs the RPMs needed to build
+ the specified package.  The source RPM for the specified package must
+ be available in a Yum repository (which will be automatically enabled, if it is
+ disabled) or it can be a local source RPM or a spec file.
+ .PP 
++Note, that only the BuildRequires information within the SRPM header information is used to determine build dependencies. This will specifically omit any dependencies that are required only for specific architectures.
++.PP
+ .SH "EXAMPLES"
+ .IP "Download and install all the RPMs needed to build the kernel RPM:"
+-\fByum-builddep kernel\fP
++\fByumdownloader --source kernel && rpm2cpio kernel*src.rpm | cpio -i kernel.spec && \\ \fP
++.br
++\fByum-builddep kernel.spec\fP
+ .PP 
++The kernel includes specific BuildRequires dependencies for different architectures. In order to make sure that those dependencies are downloaded and installed, the SRPM should be downloaded, the .spec file extracted from it and used to determine the full dependency list.
++.PP
++
+ .SH "FILES"
+ As yum-builddep uses YUM libraries for retrieving all the information, it
+ relies on YUM configuration for its default values like which repositories
diff --git a/SOURCES/BZ-1184912-yum-config-manager-fix-add-repo.patch b/SOURCES/BZ-1184912-yum-config-manager-fix-add-repo.patch
new file mode 100644
index 0000000..d5bd5dd
--- /dev/null
+++ b/SOURCES/BZ-1184912-yum-config-manager-fix-add-repo.patch
@@ -0,0 +1,33 @@
+--- yum-utils-1.1.31/yum-config-manager.py.orig	2016-02-04 13:54:28.339084020 +0100
++++ yum-utils-1.1.31/yum-config-manager.py	2016-02-04 13:55:02.427900621 +0100
+@@ -10,6 +10,8 @@
+ import fnmatch
+ 
+ from iniparse import INIConfig
++import yum.config
++import yum.yumRepo
+ 
+ from yum.parser import varReplace
+ 
+@@ -209,13 +211,16 @@
+         if url.endswith('.repo'): # this is a .repo file - fetch it, put it in our reposdir and enable it
+             destname = os.path.basename(url)
+             destname = myrepodir + '/' + destname
+-            # this sucks - but take the first repo we come to that's enabled
+-            # and steal it's grabber object - it could be proxy-laden but that's the risk we take
+-            # grumbledy grumble
+-            grabber = yb.repos.listEnabled()[0].grabfunc            
++
++            # dummy grabfunc, using [main] options
++            repo = yum.yumRepo.YumRepository('dummy')
++            repo.baseurl = ['http://dummy']
++            repo.populate(yum.config.ConfigParser(), None, yb.conf)
++            grabber = repo.grabfunc; del repo
++
+             print 'grabbing file %s to %s' % (url, destname)
+             try:
+-                result  = grabber.urlgrab(url, filename=destname, copy_local=True)
++                result  = grabber.urlgrab(url, filename=destname, copy_local=True, reget=None)
+             except (IOError, OSError, yum.Errors.YumBaseError), e:
+                 logger.error('Could not fetch/save url %s to file %s: %s'  % (url, destname, e))
+                 continue
diff --git a/SOURCES/BZ-1192946-needs-restarting-add-reboothint-opt.patch b/SOURCES/BZ-1192946-needs-restarting-add-reboothint-opt.patch
new file mode 100644
index 0000000..4ad9364
--- /dev/null
+++ b/SOURCES/BZ-1192946-needs-restarting-add-reboothint-opt.patch
@@ -0,0 +1,70 @@
+diff -up yum-utils-1.1.31/docs/needs-restarting.1.orig yum-utils-1.1.31/docs/needs-restarting.1
+--- yum-utils-1.1.31/docs/needs-restarting.1.orig	2016-08-04 12:17:58.638041851 +0200
++++ yum-utils-1.1.31/docs/needs-restarting.1	2016-08-04 12:18:37.479777824 +0200
+@@ -14,6 +14,8 @@ started running before they or some comp
+ Display a help message, and then quit.
+ .IP "\fB\-u, \-\-useronly\fP"
+ Show processes for my userid only.
++.IP "\fB\-r, \-\-reboothint\fP"
++Only report whether a full reboot is required (returns 1) or not (returns 0).
+ 
+ .PP
+ .SH "SEE ALSO"
+diff -up yum-utils-1.1.31/needs-restarting.py.orig yum-utils-1.1.31/needs-restarting.py
+--- yum-utils-1.1.31/needs-restarting.py.orig	2016-08-04 12:17:41.397159047 +0200
++++ yum-utils-1.1.31/needs-restarting.py	2016-08-04 12:19:22.944468776 +0200
+@@ -48,6 +48,11 @@ from yum.Errors import RepoError
+ sys.path.insert(0,'/usr/share/yum-cli')
+ import utils
+ 
++# For which package updates we should recommend a reboot
++# Taken from https://access.redhat.com/solutions/27943
++REBOOTPKGS = ['kernel', 'glibc', 'linux-firmware', 'systemd', 'udev',
++              'openssl-libs', 'gnutls', 'dbus']
++
+ def parseargs(args):
+     usage = """
+     needs-restarting: Report a list of process ids of programs that started 
+@@ -57,6 +62,9 @@ def parseargs(args):
+     
+     parser.add_option("-u", "--useronly", default=False, action="store_true",
+       help='show processes for my userid only')
++    parser.add_option("-r", "--reboothint", default=False, action="store_true",
++      help=('only report whether a full reboot is required (returns 1) or not '
++            '(returns 0)'))
+     
+     (opts, args) = parser.parse_args(args)
+     return (opts, args)
+@@ -111,9 +119,30 @@ def main(args):
+     if opts.useronly:
+         myuid = os.getuid()
+     
+-    needing_restart = set()
+-
+     boot_time = utils.get_boot_time()
++
++    if opts.reboothint:
++        needing_reboot = set()
++        for pkg in my.rpmdb.searchNames(REBOOTPKGS):
++            if float(pkg.installtime) > float(boot_time):
++                needing_reboot.add(pkg)
++        if needing_reboot:
++            print 'Core libraries or services have been updated:'
++            for pkg in needing_reboot:
++                print '  %s ->' % pkg.name, pkg.printVer()
++            print
++            print 'Reboot is required to ensure that your system benefits',
++            print 'from these updates.'
++            print
++            print 'More information:'
++            print 'https://access.redhat.com/solutions/27943'
++            return 1
++        else:
++            print 'No core libraries or services have been updated.'
++            print 'Reboot is probably not necessary.'
++            return 0
++
++    needing_restart = set()
+     for pid in return_running_pids(uid=myuid):
+         try:
+             pid_start = utils.get_process_time(int(pid), boot_time)['start_time']
diff --git a/SOURCES/BZ-1213602-overlayfs-workaround-plugin.patch b/SOURCES/BZ-1213602-overlayfs-workaround-plugin.patch
new file mode 100644
index 0000000..3dedb64
--- /dev/null
+++ b/SOURCES/BZ-1213602-overlayfs-workaround-plugin.patch
@@ -0,0 +1,480 @@
+commit 0c0b029122b476c269a4b560d9be558e69e054ae
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Thu Jun 25 12:09:52 2015 +0200
+
+    Add plugin for overlayfs issue workaround. Patch by Pavel Odvody. BZ#1213602
+
+diff --git a/plugins/ovl/ovl.conf b/plugins/ovl/ovl.conf
+new file mode 100644
+index 0000000..8e4d76c
+--- /dev/null
++++ b/plugins/ovl/ovl.conf
+@@ -0,0 +1,2 @@
++[main]
++enabled=1
+diff --git a/plugins/ovl/ovl.py b/plugins/ovl/ovl.py
+new file mode 100644
+index 0000000..de34081
+--- /dev/null
++++ b/plugins/ovl/ovl.py
+@@ -0,0 +1,48 @@
++# Copyright (C) 2015  Red Hat, Inc.
++#
++# Authors: Pavel Odvody <podvody@redhat.com>
++#
++# This copyrighted material is made available to anyone wishing to use,
++# modify, copy, or redistribute it subject to the terms and conditions of
++# the GNU General Public License v.2, or (at your option) any later version.
++# This program is distributed in the hope that it will be useful, but WITHOUT
++# ANY WARRANTY expressed or implied, including the implied warranties of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
++# Public License for more details.  You should have received a copy of the
++# GNU General Public License along with this program; if not, write to the
++# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
++# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
++# source code or documentation are not subject to the GNU General Public
++# License and may only be used or replicated with the express permission of
++# Red Hat, Inc.
++
++from yum.plugins import TYPE_CORE
++from os import utime, walk, path
++
++requires_api_version = '2.3'
++plugin_type = (TYPE_CORE,)
++base_dir = 'var/lib/rpm/'
++mtab = '/etc/mtab'
++
++def should_touch():
++        """ 
++        Touch the files only once we've verified that
++        we're on overlay mount
++        """
++        with open(mtab, 'r') as f:
++                line = f.readline()
++                return line and line.startswith('overlay /')
++        return False
++
++def init_hook(conduit):
++        if not should_touch():
++                return
++    ir = conduit.getConf().installroot
++        try:
++                for root, _, files in walk(path.join(ir, base_dir)):
++                        for f in files:
++                                p = path.join(root, f)
++                                with open(p, 'a'):
++                                        utime(p, None)
++        except Exception as e:
++                conduit.error(1, "Error while doing RPMdb copy-up:\n%s" % e)
+commit 1555cfa6465e6e31515a86f097c8993d89c0085e
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Thu Jun 25 12:30:13 2015 +0200
+
+    ovl plugin: fix indentation
+
+diff --git a/plugins/ovl/ovl.py b/plugins/ovl/ovl.py
+index de34081..eda784e 100644
+--- a/plugins/ovl/ovl.py
++++ b/plugins/ovl/ovl.py
+@@ -25,24 +25,24 @@ base_dir = 'var/lib/rpm/'
+ mtab = '/etc/mtab'
+ 
+ def should_touch():
+-        """ 
+-        Touch the files only once we've verified that
+-        we're on overlay mount
+-        """
+-        with open(mtab, 'r') as f:
+-                line = f.readline()
+-                return line and line.startswith('overlay /')
+-        return False
++    """ 
++    Touch the files only once we've verified that
++    we're on overlay mount
++    """
++    with open(mtab, 'r') as f:
++        line = f.readline()
++        return line and line.startswith('overlay /')
++    return False
+ 
+ def init_hook(conduit):
+-        if not should_touch():
+-                return
++    if not should_touch():
++        return
+     ir = conduit.getConf().installroot
+-        try:
+-                for root, _, files in walk(path.join(ir, base_dir)):
+-                        for f in files:
+-                                p = path.join(root, f)
+-                                with open(p, 'a'):
+-                                        utime(p, None)
+-        except Exception as e:
+-                conduit.error(1, "Error while doing RPMdb copy-up:\n%s" % e)
++    try:
++        for root, _, files in walk(path.join(ir, base_dir)):
++            for f in files:
++                p = path.join(root, f)
++                with open(p, 'a'):
++                    utime(p, None)
++    except Exception as e:
++        conduit.error(1, "Error while doing RPMdb copy-up:\n%s" % e)
+commit 617d2d90a553f9e5bc4dfd9ab2f9c194b956fcab
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Thu Jun 25 12:53:39 2015 +0200
+
+    ovl plugin: get rpmdbpath from conduit
+
+diff --git a/plugins/ovl/ovl.py b/plugins/ovl/ovl.py
+index eda784e..f2fbdd4 100644
+--- a/plugins/ovl/ovl.py
++++ b/plugins/ovl/ovl.py
+@@ -21,7 +21,6 @@ from os import utime, walk, path
+ 
+ requires_api_version = '2.3'
+ plugin_type = (TYPE_CORE,)
+-base_dir = 'var/lib/rpm/'
+ mtab = '/etc/mtab'
+ 
+ def should_touch():
+@@ -34,12 +33,12 @@ def should_touch():
+         return line and line.startswith('overlay /')
+     return False
+ 
+-def init_hook(conduit):
++def prereposetup_hook(conduit):
+     if not should_touch():
+         return
+-    ir = conduit.getConf().installroot
++    rpmdb_path = conduit.getRpmDB()._rpmdbpath
+     try:
+-        for root, _, files in walk(path.join(ir, base_dir)):
++        for root, _, files in walk(rpmdb_path):
+             for f in files:
+                 p = path.join(root, f)
+                 with open(p, 'a'):
+commit 5cd70d30bcdbd544e086a1aa3e7522c89bbd893a
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Tue Aug 4 12:00:37 2015 +0200
+
+    ovl plugin: change copy-up strategy, execute when root fs is mounted OverlayFS, add logging. Patch by Pavel Odvody.
+
+diff --git a/plugins/ovl/ovl.py b/plugins/ovl/ovl.py
+index f2fbdd4..8dd0a9e 100644
+--- a/plugins/ovl/ovl.py
++++ b/plugins/ovl/ovl.py
+@@ -1,47 +1,93 @@
+-# Copyright (C) 2015  Red Hat, Inc.
+-#
+-# Authors: Pavel Odvody <podvody@redhat.com>
+-#
+-# This copyrighted material is made available to anyone wishing to use,
+-# modify, copy, or redistribute it subject to the terms and conditions of
+-# the GNU General Public License v.2, or (at your option) any later version.
+-# This program is distributed in the hope that it will be useful, but WITHOUT
+-# ANY WARRANTY expressed or implied, including the implied warranties of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+-# Public License for more details.  You should have received a copy of the
+-# GNU General Public License along with this program; if not, write to the
+-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
+-# source code or documentation are not subject to the GNU General Public
+-# License and may only be used or replicated with the express permission of
+-# Red Hat, Inc.
+-
+ from yum.plugins import TYPE_CORE
+-from os import utime, walk, path
++from os import walk, path, fstat
+ 
+ requires_api_version = '2.3'
+ plugin_type = (TYPE_CORE,)
+ mtab = '/etc/mtab'
+ 
++
++def _stat_ino_fp(fp):
++    """
++    Get the inode number from file descriptor
++    """
++    return fstat(fp.fileno()).st_ino
++
++
++def get_file_list(rpmpath):
++    """
++    Enumerate all files in a directory
++    """
++    for root, _, files in walk(rpmpath):
++        for f in files:
++            yield path.join(root, f)
++
++
++def for_each_file(files, cb, m='rb'):
++    """
++    Open each file with mode specified in `m`
++    and invoke `cb` on each of the file objects
++    """
++    if not files or not cb:
++        return []
++    ret = []
++    for f in files:
++        with open(f, m) as fp:
++            ret.append(cb(fp))
++    return ret
++
++
++def do_detect_copy_up(files):
++    """
++    Open the files first R/O, then R/W and count unique
++    inode numbers
++    """
++    num_files = len(files)
++    lower = for_each_file(files, _stat_ino_fp, 'rb')
++    upper = for_each_file(files, _stat_ino_fp, 'ab')
++    diff = set(lower + upper)
++    return len(diff) - num_files
++
++
++def raw_copy_up(files):
++    """
++    Induce a copy-up by opening R/W
++    """
++    return for_each_file(files, _stat_ino_fp, 'ab')
++
++
++def should_be_verbose(cmd):
++    """
++    If the debuglevel is > 2 then be verbose
++    """
++    if not hasattr(cmd, 'debuglevel'):
++        return False
++    return cmd.debuglevel > 2
++
++
+ def should_touch():
+     """ 
+     Touch the files only once we've verified that
+     we're on overlay mount
+     """
++    if not path.exists(mtab):
++        return False
+     with open(mtab, 'r') as f:
+         line = f.readline()
+-        return line and line.startswith('overlay /')
++        return line.startswith('overlay / overlay')
+     return False
+ 
++
+ def prereposetup_hook(conduit):
+     if not should_touch():
+         return
++
+     rpmdb_path = conduit.getRpmDB()._rpmdbpath
++
+     try:
+-        for root, _, files in walk(rpmdb_path):
+-            for f in files:
+-                p = path.join(root, f)
+-                with open(p, 'a'):
+-                    utime(p, None)
++        files = list(get_file_list(rpmdb_path))
++        if should_be_verbose(conduit.getCmdLine()[0]):
++            conduit.info(1, "ovl: Copying up (%i) files from OverlayFS lower layer" % do_detect_copy_up(files))
++        else:
++            raw_copy_up(files)
+     except Exception as e:
+-        conduit.error(1, "Error while doing RPMdb copy-up:\n%s" % e)
++        conduit.error(1, "ovl: Error while doing RPMdb copy-up:\n%s" % e)
+commit 11e4a7386e2e351e0ff5f8d89663eb66220a6100
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Tue Aug 4 12:18:49 2015 +0200
+
+    ovl plugin: remove redundant debuglevel check
+
+diff --git a/plugins/ovl/ovl.py b/plugins/ovl/ovl.py
+index 8dd0a9e..400d3c7 100644
+--- a/plugins/ovl/ovl.py
++++ b/plugins/ovl/ovl.py
+@@ -4,6 +4,7 @@ from os import walk, path, fstat
+ requires_api_version = '2.3'
+ plugin_type = (TYPE_CORE,)
+ mtab = '/etc/mtab'
++VERBOSE_DEBUGLEVEL = 3
+ 
+ 
+ def _stat_ino_fp(fp):
+@@ -48,22 +49,6 @@ def do_detect_copy_up(files):
+     return len(diff) - num_files
+ 
+ 
+-def raw_copy_up(files):
+-    """
+-    Induce a copy-up by opening R/W
+-    """
+-    return for_each_file(files, _stat_ino_fp, 'ab')
+-
+-
+-def should_be_verbose(cmd):
+-    """
+-    If the debuglevel is > 2 then be verbose
+-    """
+-    if not hasattr(cmd, 'debuglevel'):
+-        return False
+-    return cmd.debuglevel > 2
+-
+-
+ def should_touch():
+     """ 
+     Touch the files only once we've verified that
+@@ -85,9 +70,7 @@ def prereposetup_hook(conduit):
+ 
+     try:
+         files = list(get_file_list(rpmdb_path))
+-        if should_be_verbose(conduit.getCmdLine()[0]):
+-            conduit.info(1, "ovl: Copying up (%i) files from OverlayFS lower layer" % do_detect_copy_up(files))
+-        else:
+-            raw_copy_up(files)
++        copied_num = do_detect_copy_up(files)
++        conduit.info(VERBOSE_DEBUGLEVEL, "ovl: Copying up (%i) files from OverlayFS lower layer" % copied_num)
+     except Exception as e:
+         conduit.error(1, "ovl: Error while doing RPMdb copy-up:\n%s" % e)
+commit 6f43c2e1aff0ee0746685778544f7b05d2ef78a1
+Author: Pavel Odvody <podvody@redhat.com>
+Date:   Thu Sep 3 18:09:58 2015 +0200
+
+    Add manpage, remove file-system check
+
+diff --git a/docs/yum-ovl.1 b/docs/yum-ovl.1
+new file mode 100644
+index 0000000..ddfbfab
+--- /dev/null
++++ b/docs/yum-ovl.1
+@@ -0,0 +1,22 @@
++.TH "yum\-ovl" "1" "September 2015" "Red Hat" "User Manual"
++.
++.SH "NAME"
++yum\-ovl \- Performs an initial copy\-up of yum(8) package database\.
++.
++.SH "OPTIONS"
++\fB\-d\fR \fIdebug\-level\fR If debug level is \fI2\fR and more, print out the number of files copied up from the lower layer
++.
++.SH "FILES"
++\fI/usr/lib/yum\-plugins/ovl\.py\fR Plugin itself
++.
++.P
++\fI/etc/yum/pluginconf\.d/ovl\.conf\fR Configuration file allowing to enable/disable the plugin
++.
++.SH "AUTHOR"
++Pavel Odvody \fIpodvody@redhat\.com\fR
++.
++.SH "LICENSE"
++2015, Red Hat, Licensed under GPLv2+
++.
++.SH "SEE ALSO"
++yum(1) yum(8)
+diff --git a/plugins/ovl/ovl.py b/plugins/ovl/ovl.py
+index 400d3c7..3d547ed 100644
+--- a/plugins/ovl/ovl.py
++++ b/plugins/ovl/ovl.py
+@@ -3,7 +3,6 @@ from os import walk, path, fstat
+ 
+ requires_api_version = '2.3'
+ plugin_type = (TYPE_CORE,)
+-mtab = '/etc/mtab'
+ VERBOSE_DEBUGLEVEL = 3
+ 
+ 
+@@ -49,23 +48,7 @@ def do_detect_copy_up(files):
+     return len(diff) - num_files
+ 
+ 
+-def should_touch():
+-    """ 
+-    Touch the files only once we've verified that
+-    we're on overlay mount
+-    """
+-    if not path.exists(mtab):
+-        return False
+-    with open(mtab, 'r') as f:
+-        line = f.readline()
+-        return line.startswith('overlay / overlay')
+-    return False
+-
+-
+ def prereposetup_hook(conduit):
+-    if not should_touch():
+-        return
+-
+     rpmdb_path = conduit.getRpmDB()._rpmdbpath
+ 
+     try:
+commit 3980742eb6477c5bd5366222fb033cfc5c95d260
+Author: Pavel Odvody <podvody@redhat.com>
+Date:   Fri Sep 4 10:38:32 2015 +0200
+
+    Added manpage description and reference to rpmdb
+
+diff --git a/docs/yum-ovl.1 b/docs/yum-ovl.1
+index ddfbfab..33e0dfb 100644
+--- a/docs/yum-ovl.1
++++ b/docs/yum-ovl.1
+@@ -6,6 +6,21 @@ yum\-ovl \- Performs an initial copy\-up of yum(8) package database\.
+ .SH "OPTIONS"
+ \fB\-d\fR \fIdebug\-level\fR If debug level is \fI2\fR and more, print out the number of files copied up from the lower layer
+ .
++.SH "DESCRIPTION"
++Opening a file on OverlayFS in read\-only mode causes the file from
++.br
++lower layer to be opened, then later on, if the same file is opened 
++.br
++in write mode, a copy-up into the upper    layer    takes    place, 
++.br
++resulting into a \fBnew\fR file being opened\.
++.br
++Since yum(8) needs to open the \fBRPMdb\fR first read-only, and then
++.br
++also with write access, we need to copy-up the files beforehand to 
++.br
++make sure that the access is consistent.
++.
+ .SH "FILES"
+ \fI/usr/lib/yum\-plugins/ovl\.py\fR Plugin itself
+ .
+@@ -19,4 +34,4 @@ Pavel Odvody \fIpodvody@redhat\.com\fR
+ 2015, Red Hat, Licensed under GPLv2+
+ .
+ .SH "SEE ALSO"
+-yum(1) yum(8)
++yum(1) yum(8) rpmdb(8)
+diff -up yum-utils-1.1.31/docs/Makefile.old yum-utils-1.1.31/docs/Makefile
+--- yum-utils-1.1.31/docs/Makefile.old	2015-09-04 17:10:03.460207371 +0200
++++ yum-utils-1.1.31/docs/Makefile	2015-09-04 17:10:19.167260413 +0200
+@@ -3,7 +3,7 @@ DOCS = repoquery package-cleanup repo-rs
+        yum-groups-manager debuginfo-install repodiff yum-fs-snapshot \
+        show-installed show-changed-rco yum-debug-restore \
+        find-repos-of-install needs-restarting repo-graph repoclosure \
+-       repomanage repotrack verifytree yum-config-manager
++       repomanage repotrack verifytree yum-config-manager yum-ovl
+ DOCS5 = yum-changelog.conf yum-versionlock.conf yum-fs-snapshot.conf
+ DOCS8 = yum-complete-transaction yumdb
+ 
+commit d03fce57c1fa3f9dff6fdd9867cbcaf66df9f841
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Fri Oct 9 15:16:33 2015 +0200
+
+    ovl plugin: run at init_hook stage
+
+diff --git a/plugins/ovl/ovl.py b/plugins/ovl/ovl.py
+index 3d547ed..fe27022 100644
+--- a/plugins/ovl/ovl.py
++++ b/plugins/ovl/ovl.py
+@@ -47,9 +47,8 @@ def do_detect_copy_up(files):
+     diff = set(lower + upper)
+     return len(diff) - num_files
+ 
+-
+-def prereposetup_hook(conduit):
+-    rpmdb_path = conduit.getRpmDB()._rpmdbpath
++def init_hook(conduit):
++    rpmdb_path = conduit._base.rpmdb._rpmdbpath
+ 
+     try:
+         files = list(get_file_list(rpmdb_path))
diff --git a/SOURCES/BZ-1245117-yum-config-manager-all-repos.patch b/SOURCES/BZ-1245117-yum-config-manager-all-repos.patch
new file mode 100644
index 0000000..c36458d
--- /dev/null
+++ b/SOURCES/BZ-1245117-yum-config-manager-all-repos.patch
@@ -0,0 +1,22 @@
+commit 84988d6ae0e3d6dad07cde3701a69f7717cf8962
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Fri May 13 12:19:33 2016 +0200
+
+    yum-config-manager: document syntax for enabling/disabling all repos.
+
+diff --git a/docs/yum-config-manager.1 b/docs/yum-config-manager.1
+index 81b895b..c130070 100644
+--- a/docs/yum-config-manager.1
++++ b/docs/yum-config-manager.1
+@@ -16,9 +16,9 @@ Display a help message, and then quit.
+ .IP "\fB\-\-save\fP"
+ Save the current options (useful with \-\-setopt).
+ .IP "\fB\-\-enable\fP"
+-Enable the specified repos (automatically saves).
++Enable the specified repos (automatically saves). To enable all repositories run 'yum-config-manager --enable \\*".
+ .IP "\fB\-\-disable\fP"
+-Disable the specified repos (automatically saves).
++Disable the specified repos (automatically saves). To disable all repositories run "yum-config-manager --disable \\*".
+ .IP "\fB\-\-add\-repo=ADDREPO\fP"
+ Add (and enable) the repo from the specified file or url.
+ .SH "ADDITIONAL OPTIONS"
diff --git a/SOURCES/BZ-1264774-archlist-docs.patch b/SOURCES/BZ-1264774-archlist-docs.patch
new file mode 100644
index 0000000..ecd40dd
--- /dev/null
+++ b/SOURCES/BZ-1264774-archlist-docs.patch
@@ -0,0 +1,19 @@
+commit ac1a9d171548057961ea040d7f1eaae61cb54bf1
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Tue Mar 11 17:40:48 2014 +0100
+
+    Fix description of --archlist in the manpage. BZ 1045871
+
+diff --git a/docs/yumdownloader.1 b/docs/yumdownloader.1
+index e290268..d2cb276 100644
+--- a/docs/yumdownloader.1
++++ b/docs/yumdownloader.1
+@@ -20,7 +20,7 @@ When downloading RPMs, resolve dependencies and also download the required packa
+ .IP "\fB\-\-source\fP"
+ Instead of downloading the binary RPMs, download the source RPMs.
+ .IP "\fB\-\-archlist=ARCH1[,ARCH2...]\fP"
+-Limit the query to packages of given architecture(s). Valid values are all
++Limit the query to packages of given and compatible architectures. Valid values are all
+ architectures known to rpm/yum such as 'i386' and 'src' for
+ source RPMS. Note that repoquery will now change yum's "arch" to the first
+ value in the archlist. So "\-\-archlist=i386,i686" will change yum's canonical
diff --git a/SOURCES/BZ-1269414-yum-plugin-priorities-obsoletes.patch b/SOURCES/BZ-1269414-yum-plugin-priorities-obsoletes.patch
new file mode 100644
index 0000000..c909262
--- /dev/null
+++ b/SOURCES/BZ-1269414-yum-plugin-priorities-obsoletes.patch
@@ -0,0 +1,19 @@
+commit 834a4ff4f2752631252cff4e3b2ba87bee62965b
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Thu Dec 10 16:24:18 2015 +0100
+
+    yum-plugin-priorities: get all obsoletes, not just the newest. BZ#1269414
+
+diff --git a/plugins/priorities/priorities.py b/plugins/priorities/priorities.py
+index ce98583..006c545 100644
+--- a/plugins/priorities/priorities.py
++++ b/plugins/priorities/priorities.py
+@@ -111,7 +111,7 @@ def exclude_hook(conduit):
+     if check_obsoletes and not conduit._base.conf.obsoletes:
+         check_obsoletes = False
+     if check_obsoletes:
+-        obsoletes = conduit._base.up.rawobsoletes
++        obsoletes = conduit._base.pkgSack.returnObsoletes()
+ 
+     # Build a dictionary with package priorities. Either with arch or
+     # archless, based on the user's settings.
diff --git a/SOURCES/BZ-1285750-repoquery-version.patch b/SOURCES/BZ-1285750-repoquery-version.patch
new file mode 100644
index 0000000..dd3395a
--- /dev/null
+++ b/SOURCES/BZ-1285750-repoquery-version.patch
@@ -0,0 +1,19 @@
+commit 624cf40406a2e8bacde8afde807d5efbf74ca4ab
+Author: James Antill <james@and.org>
+Date:   Thu Dec 5 16:43:04 2013 -0500
+
+    Remove -v from repoquery man page.
+
+diff --git a/docs/repoquery.1 b/docs/repoquery.1
+index 30fda8a..85b0047 100644
+--- a/docs/repoquery.1
++++ b/docs/repoquery.1
+@@ -14,7 +14,7 @@ similarly to rpm queries.
+ .SH "GENERAL OPTIONS"
+ .IP "\fB\-\-querytags\fP"
+ List valid queryformat tags and exit..
+-.IP "\fB\-v, \-\-version\fP" 
++.IP "\fB\-\-version\fP"
+ Report program version and exit.
+ .IP "\fB\-\-repoid=<repo>\fP"
+ Specify which repository to query. Using this option disables all repositories
diff --git a/SOURCES/BZ-1293707-debuginfo-installonly-latest-version.patch b/SOURCES/BZ-1293707-debuginfo-installonly-latest-version.patch
new file mode 100644
index 0000000..d93c064
--- /dev/null
+++ b/SOURCES/BZ-1293707-debuginfo-installonly-latest-version.patch
@@ -0,0 +1,52 @@
+commit 2f1605f65e6bc24d6a2515b99f1486085f281a49
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Tue Mar 1 16:18:39 2016 +0100
+
+    debuginfo-install: install debuginfo only for the latest installed version of installonly package. BZ#1293707
+
+diff --git a/debuginfo-install.py b/debuginfo-install.py
+index bb61a1d..19fe8b6 100755
+--- a/debuginfo-install.py
++++ b/debuginfo-install.py
+@@ -148,9 +148,12 @@ class DebugInfoInstall(YumUtilBase):
+         # add that debuginfo to the ts
+         # look through that pkgs' deps
+         # add all the debuginfos for the pkgs providing those deps
++        installonly_added = set()
+         for pkgglob in self.cmds:
+             e, m, u = self.rpmdb.matchPackageNames([pkgglob])
+-            for po in e + m:
++            for po in sorted(e + m, reverse=True):
++                if po.name in installonly_added:
++                    continue
+                 try:
+                     self.di_try_install(po)
+                 except yum.Errors.InstallError, e:
+@@ -167,6 +170,8 @@ class DebugInfoInstall(YumUtilBase):
+                                 self.di_try_install(deppo)
+                             except yum.Errors.InstallError, e:
+                                 self.logger.critical('Could not find debuginfo pkg for dependency package %s' % deppo)
++                if po.name in self.conf.installonlypkgs:
++                    installonly_added.add(po.name)
+ 
+         for pkgname in u:
+             self.logger.critical('Could not find a package for: %s' % pkgname)
+commit 8048d25bf3225b8ddd7d0a90b050bce2cc716e2a
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Tue Jun 21 14:24:12 2016 +0200
+
+    debuginfo-install: also respect provides when testing for installonly.
+
+diff --git a/debuginfo-install.py b/debuginfo-install.py
+index 19fe8b6..6053f62 100755
+--- a/debuginfo-install.py
++++ b/debuginfo-install.py
+@@ -170,7 +170,7 @@ class DebugInfoInstall(YumUtilBase):
+                                 self.di_try_install(deppo)
+                             except yum.Errors.InstallError, e:
+                                 self.logger.critical('Could not find debuginfo pkg for dependency package %s' % deppo)
+-                if po.name in self.conf.installonlypkgs:
++                if self.allowedMultipleInstalls(po):
+                     installonly_added.add(po.name)
+ 
+         for pkgname in u:
diff --git a/SOURCES/BZ-1296282-verifytree-fix-comps-schema.patch b/SOURCES/BZ-1296282-verifytree-fix-comps-schema.patch
new file mode 100644
index 0000000..5342d3d
--- /dev/null
+++ b/SOURCES/BZ-1296282-verifytree-fix-comps-schema.patch
@@ -0,0 +1,51 @@
+diff -up yum-utils-1.1.31/verifytree.py.orig yum-utils-1.1.31/verifytree.py
+--- yum-utils-1.1.31/verifytree.py.orig	2016-07-21 14:46:21.050199284 +0200
++++ yum-utils-1.1.31/verifytree.py	2016-07-21 14:46:43.277058501 +0200
+@@ -47,8 +47,22 @@ plan_number = 13
+ case_numbers = {'REPODATA': 56, 'CORE_PACKAGES': 57, 'COMPS': 58, 
+                 'BOOT_IMAGES': 59}
+ 
+-# URL for the RELAX NG schema for comps
+-SCHEMA = 'http://cvs.fedoraproject.org/viewcvs/*checkout*/comps/comps.rng'
++def get_schema_path():
++    """Return the local path to the RELAX NG comps schema."""
++    # Depending on whether our distro uses versioned or unversioned docdirs
++    # (the former is true for Fedora < 20, see bug 998579), the schema file
++    # should be provided by yum at either of the following locations:
++    paths = ['/usr/share/doc/yum%s/comps.rng' % s
++             for s in ('', '-' + yum.__version__)]
++    for path in paths:
++        # Better than os.path.exists() as this also ensures we can actually
++        # read the file
++        try:
++            with open(path):
++                return path
++        except IOError:
++            continue
++    raise IOError(paths)
+ 
+ def testopia_create_run(plan):
+     '''Create a run of the given test plan. Returns the run ID.'''
+@@ -230,9 +244,19 @@ def main():
+ 
+         if not (retval & BAD_COMPS):
+             print "  verifying comps.xml grammar with xmllint"
+-            comps = newrepo.getGroups()
+-            r = os.system("xmllint --noout --nowarning --relaxng %s %s" % 
+-                (SCHEMA,comps))
++            try:
++                schema = get_schema_path()
++            except IOError as e:
++                print '  could not read schema file, paths tried:'
++                for path in e.args[0]:
++                    print '    ' + path
++                print ('  make sure you have the latest version of yum '
++                       'properly installed')
++                r = 1
++            else:
++                comps = newrepo.getGroups()
++                r = os.system("xmllint --noout --nowarning --relaxng %s %s" %
++                    (schema, comps))
+             if r != 0:
+                 retval = retval | BAD_COMPS
+                 report('COMPS','FAILED')
diff --git a/SOURCES/BZ-1329649-reposync-download-metadata-manpage.patch b/SOURCES/BZ-1329649-reposync-download-metadata-manpage.patch
new file mode 100644
index 0000000..bf260e3
--- /dev/null
+++ b/SOURCES/BZ-1329649-reposync-download-metadata-manpage.patch
@@ -0,0 +1,19 @@
+commit cd96c21e6c323e4c73555bbc1360a60fa2b9ddeb
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Tue Oct 14 18:52:04 2014 +0200
+
+    reposync: add --download-metadata to the man page. BZ 1079435
+
+diff --git a/docs/reposync.1 b/docs/reposync.1
+index d6d245a..ea5653c 100644
+--- a/docs/reposync.1
++++ b/docs/reposync.1
+@@ -41,6 +41,8 @@ Just list urls of what would be downloaded, don't download.
+ Enable yum plugin support.
+ .IP "\fB\-m, \-\-downloadcomps\fP"
+ Also download comps.xml.
++.IP "\fB\-\-download-metadata\fP"
++Download all the non-default metadata.
+ .IP "\fB\-n, \-\-newest\-only\fP"
+ Download only newest packages per-repo.
+ .IP "\fB\-q, \-\-quiet\fP"
diff --git a/SOURCES/BZ-1333353-verifytree-fix-handling-no-comps.patch b/SOURCES/BZ-1333353-verifytree-fix-handling-no-comps.patch
new file mode 100644
index 0000000..b85822b
--- /dev/null
+++ b/SOURCES/BZ-1333353-verifytree-fix-handling-no-comps.patch
@@ -0,0 +1,33 @@
+commit 56c7eacd9d0ad9237d05e1393c12d5059edb2c7a
+Author: Michal Domonkos <mdomonko@redhat.com>
+Date:   Mon Oct 23 15:33:13 2017 +0200
+
+    verifytree: fix handling of missing comps. BZ 1333353
+    
+    When we have group_command = 'objects' and no comps file, invoking
+    my.comps doesn't raise a GroupsError as we would expect, and we continue
+    to newrepo.getGroups() where we finally traceback.  This commit makes
+    sure we detect that beforehand and fail correctly.
+
+diff --git a/verifytree.py b/verifytree.py
+index 6a127cd..7f11f10 100755
+--- a/verifytree.py
++++ b/verifytree.py
+@@ -237,7 +237,8 @@ def main():
+         try:
+             print "  verifying comps.xml with yum"
+             b = my.comps.compscount
+-        except Errors.GroupsError, e:
++            comps = newrepo.getGroups()
++        except (Errors.GroupsError, Errors.RepoMDError):
+             print '  comps file missing or unparseable'
+             report('COMPS','FAILED')
+             retval = retval | BAD_COMPS
+@@ -254,7 +255,6 @@ def main():
+                        'properly installed')
+                 r = 1
+             else:
+-                comps = newrepo.getGroups()
+                 r = os.system("xmllint --noout --nowarning --relaxng %s %s" %
+                     (schema, comps))
+             if r != 0:
diff --git a/SOURCES/BZ-1335587-needs-restarting-add-services-opt.patch b/SOURCES/BZ-1335587-needs-restarting-add-services-opt.patch
new file mode 100644
index 0000000..ca92737
--- /dev/null
+++ b/SOURCES/BZ-1335587-needs-restarting-add-services-opt.patch
@@ -0,0 +1,70 @@
+diff -up yum-utils-1.1.31/docs/needs-restarting.1.orig yum-utils-1.1.31/docs/needs-restarting.1
+--- yum-utils-1.1.31/docs/needs-restarting.1.orig	2016-08-04 12:22:33.765295008 +0200
++++ yum-utils-1.1.31/docs/needs-restarting.1	2016-08-04 12:24:52.076356702 +0200
+@@ -16,6 +16,8 @@ Display a help message, and then quit.
+ Show processes for my userid only.
+ .IP "\fB\-r, \-\-reboothint\fP"
+ Only report whether a full reboot is required (returns 1) or not (returns 0).
++.IP "\fB\-s, \-\-services\fP"
++List the affected systemd services only.
+ 
+ .PP
+ .SH "SEE ALSO"
+diff -up yum-utils-1.1.31/needs-restarting.py.orig yum-utils-1.1.31/needs-restarting.py
+--- yum-utils-1.1.31/needs-restarting.py.orig	2016-08-04 12:22:15.914287046 +0200
++++ yum-utils-1.1.31/needs-restarting.py	2016-08-04 12:24:22.235343391 +0200
+@@ -65,6 +65,8 @@ def parseargs(args):
+     parser.add_option("-r", "--reboothint", default=False, action="store_true",
+       help=('only report whether a full reboot is required (returns 1) or not '
+             '(returns 0)'))
++    parser.add_option("-s", "--services", default=False, action="store_true",
++      help='list the affected systemd services only')
+     
+     (opts, args) = parser.parse_args(args)
+     return (opts, args)
+@@ -106,6 +108,31 @@ def get_open_files(pid):
+             files.append(filename)
+     return files
+ 
++def get_service(pid):
++    """Return the systemd service to which the process belongs.
++
++    More details:
++    http://0pointer.de/blog/projects/systemd-for-admins-2.html
++    https://www.freedesktop.org/wiki/Software/systemd/FrequentlyAskedQuestions/
++    """
++
++    fname = '/proc/%s/cgroup' % pid
++    try:
++        with open(fname, 'r') as f:
++            groups = f.readlines()
++    except (IOError, OSError), e:
++        print >>sys.stderr, "Could not open %s" % fname
++        return None
++
++    for line in groups:
++        line = line.replace('\n', '')
++        hid, hsub, cgroup = line.split(':')
++        if hsub == 'name=systemd':
++            name = cgroup.split('/')[-1]
++            if name.endswith('.service'):
++                return name
++    return None
++
+ def main(args):
+     (opts, args)  = parseargs(args)
+ 
+@@ -189,6 +216,13 @@ def main(args):
+ 
+            
+             
++    if opts.services:
++        names = set([get_service(pid) for pid in needing_restart])
++        for name in names:
++            if name is not None:
++                print name
++        return 0
++
+     for pid in needing_restart:
+         try:
+             cmdline = open('/proc/' +pid+ '/cmdline', 'r').read()
diff --git a/SOURCES/BZ-1349433-verifytree-handle-no-core-group.patch b/SOURCES/BZ-1349433-verifytree-handle-no-core-group.patch
new file mode 100644
index 0000000..f2a7af9
--- /dev/null
+++ b/SOURCES/BZ-1349433-verifytree-handle-no-core-group.patch
@@ -0,0 +1,32 @@
+commit b586ff502946fbd3271db8370cb546f696c51cfd
+Author: Michal Domonkos <mdomonko@redhat.com>
+Date:   Fri Oct 20 19:47:36 2017 +0200
+
+    verifytree: handle no @core group gracefully. BZ 1349433
+    
+    It's not clear to me whether @core group is really mandatory, however
+    let's make verifytree fail if it's not defined so that we don't change
+    the return code to 0 for that case; we would return 1 previously (python
+    traceback) and now we OR the BAD_COMPS flag which is 4 (still not 1 but
+    at least non-zero).
+
+diff --git a/verifytree.py b/verifytree.py
+index 6a127cd..603a633 100755
+--- a/verifytree.py
++++ b/verifytree.py
+@@ -278,7 +278,14 @@ def main():
+     elif not (retval & BAD_COMPS or opts.nocomps):
+         print "Checking mandatory @core packages"
+         group = my.comps.return_group('core')
+-        for pname in group.mandatory_packages:
++        if group is not None:
++            pkgs = group.mandatory_packages
++        else:
++            print "  @core group not found"
++            retval = retval | BAD_COMPS
++            report('COMPS','FAILED')
++            pkgs = []
++        for pname in pkgs:
+             # FIXME: this pulls from pkgSack, which (I guess) is populated 
+             # based on the arch etc. of the current host.. so you can't check
+             # the x86_64 repo from an i386 machine, f'rinstance.
diff --git a/SOURCES/BZ-1403015-yum-config-manager-select-disabled-repoid-setopts.patch b/SOURCES/BZ-1403015-yum-config-manager-select-disabled-repoid-setopts.patch
new file mode 100644
index 0000000..7c9cd11
--- /dev/null
+++ b/SOURCES/BZ-1403015-yum-config-manager-select-disabled-repoid-setopts.patch
@@ -0,0 +1,109 @@
+diff -up yum-utils-1.1.31/docs/yum-config-manager.1.orig yum-utils-1.1.31/docs/yum-config-manager.1
+--- yum-utils-1.1.31/docs/yum-config-manager.1.orig	2017-02-27 18:04:05.377037276 +0100
++++ yum-utils-1.1.31/docs/yum-config-manager.1	2017-02-27 18:04:06.648030205 +0100
+@@ -3,20 +3,38 @@
+ .SH "NAME"
+ yum-config-manager \- manage yum configuration options and yum repositories
+ .SH "SYNOPSIS"
+-\fByum-config-manager\fP [options]
++\fByum-config-manager\fP [options] [section ...]
+ .SH "DESCRIPTION"
+ .PP
+ \fByum-config-manager\fP is a program that can manage main yum configuration
+ options, toggle which repositories are enabled or disabled, and add new
+ repositories.
+ .PP
++Unless \-\-add-repo is used, the program will output the current configuration
++of the selected sections, and optionally save it back to the corresponding
++files.
++.PP
++By default, if no positional arguments are specified, the program will select
++the [main] section and each enabled repository.
++You can override this by specifying your own list of sections as arguments
++(these may also include disabled repositories).
++A section can either be main or a repoid.
++.PP
+ .SH "OPTIONS"
+ .IP "\fB\-h, \-\-help\fP"
+ Display a help message, and then quit.
++.IP "\fB\-\-setopt=option=value\fP"
++Set any config option in yum config or repo files. For options in the global
++config just use: \-\-setopt=option=value for repo options use: \-\-setopt=repoid.option=value.
++The latter form accepts wildcards in repoid that will be expanded to the
++selected sections.
++If repoid contains no wildcard, it will automatically be selected; this is
++useful if you are addressing a disabled repo, in which case you don't have to
++additionally pass it as an argument.
+ .IP "\fB\-\-save\fP"
+ Save the current options (useful with \-\-setopt).
+ .IP "\fB\-\-enable\fP"
+-Enable the specified repos (automatically saves). To enable all repositories run 'yum-config-manager --enable \\*".
++Enable the specified repos (automatically saves). To enable all repositories run "yum-config-manager --enable \\*".
+ .IP "\fB\-\-disable\fP"
+ Disable the specified repos (automatically saves). To disable all repositories run "yum-config-manager --disable \\*".
+ .IP "\fB\-\-add\-repo=ADDREPO\fP"
+@@ -25,6 +43,36 @@ Add (and enable) the repo from the speci
+ Yum-config-manager inherits all other options from yum. See the yum(8)
+ man page for more information.
+ 
++.SH "EXAMPLES"
++Show the configuration of [main] and the repos foo and bar:
++.IP
++\fByum-config-manager main foo bar\fP
++.PP
++Enable the repos foo and bar:
++.IP
++\fByum-config-manager --enable foo bar\fP
++.PP
++Change a global option:
++.IP
++\fByum-config-manager --setopt=installonly_limit=5 --save\fP
++.PP
++Change a repo option of the repo foo (works even if foo is disabled):
++.IP
++\fByum-config-manager --setopt=foo.skip_if_unavailable=1 --save\fP
++.PP
++Change a repo option of more repos at once:
++.IP
++\fByum-config-manager --setopt=\\*.skip_if_unavailable=1 --save foo bar baz\fP
++.PP
++Change a repo option of all the enabled repos:
++.IP
++\fByum-config-manager --setopt=\\*.skip_if_unavailable=1 --save\fP
++.PP
++Change a repo option of all the configured (that is, enabled and disabled)
++repos:
++.IP
++\fByum-config-manager --setopt=\\*.skip_if_unavailable=1 --save \\*\fP
++
+ .PP
+ .SH "SEE ALSO"
+ .nf
+diff -up yum-utils-1.1.31/yum-config-manager.py.orig yum-utils-1.1.31/yum-config-manager.py
+--- yum-utils-1.1.31/yum-config-manager.py.orig	2017-02-27 18:04:05.367037332 +0100
++++ yum-utils-1.1.31/yum-config-manager.py	2017-02-27 18:04:40.143843850 +0100
+@@ -107,7 +107,7 @@ def match_repoid(repoid, repo_setopts):
+ 
+ NAME = 'yum-config-manager'
+ VERSION = '1.0'
+-USAGE = '"yum-config-manager [options] [section]'
++USAGE = 'yum-config-manager [options] [section ...]'
+ 
+ yum.misc.setup_locale()
+ 
+@@ -180,6 +180,15 @@ if args:
+ else:
+     repos = yb.repos.listEnabled()
+ 
++# Automatically select repos specified within --setopt (but only for exact
++# matches without wildcards).  This way users don't have to specify disabled
++# repos twice on the cmdline.
++if hasattr(yb, 'repo_setopts') and yb.repo_setopts:
++    ids = set(yb.repo_setopts.keys()) & set(yb.repos.repos.keys())
++    ids -= set([r.id for r in repos])
++    repos += yb.repos.findRepos(','.join(ids),
++                                name_match=True, ignore_case=True)
++
+ if not opts.addrepo:
+     for repo in sorted(repos):
+         print yb.fmtSection('repo: ' + repo.id)
diff --git a/SOURCES/BZ-1406891-verify-exit-status.patch b/SOURCES/BZ-1406891-verify-exit-status.patch
new file mode 100644
index 0000000..ec5f7df
--- /dev/null
+++ b/SOURCES/BZ-1406891-verify-exit-status.patch
@@ -0,0 +1,85 @@
+commit f62551849e0f8c5cc3151d78af0975fad831e8ed
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Tue Oct 18 10:31:11 2016 +0200
+
+    yum-plugin-verify: set exit status to 1 in case of problems.
+
+diff --git a/plugins/verify/verify.py b/plugins/verify/verify.py
+index 108f96e..94eca26 100644
+--- a/plugins/verify/verify.py
++++ b/plugins/verify/verify.py
+@@ -287,6 +287,7 @@ Verify packages and display data on bad verifications"""
+         
+     def show_data(self, base, msg, pkgs, name):
+         done = False
++        problem_found = False
+         mcb = lambda x: base.matchcallback(x, [])
+         for (pkg, results) in self.filter_data(msg, pkgs):
+             if not done:
+@@ -310,11 +311,13 @@ Verify packages and display data on bad verifications"""
+                     (hib, hie) = ("", "")
+                 done_prob = False
+                 for problem in sorted(results[fname]):
++                    problem_found = True
+                     if not done_prob and problem.file_types:
+                         tags = ", ".join(problem.file_types)
+                         msg("    Tags: " + hib + tags + hie)
+                     self.show_problem(base, msg, problem, done_prob)
+                     done_prob = True
++        return problem_found
+ 
+     def doCommand(self, base, basecmd, extcmds):
+         global _verify_configs
+@@ -360,10 +363,10 @@ Verify packages and display data on bad verifications"""
+             # nevr() match
+             
+         ypl = base.returnPkgLists(subgroup + extcmds)
+-        self.show_data(base, msg, ypl.installed, 'Installed Packages')
+-        self.show_data(base, msg, ypl.extras,    'Extra Packages')
++        result = (self.show_data(base, msg, ypl.installed, 'Installed Packages')
++                  or self.show_data(base, msg, ypl.extras,    'Extra Packages'))
+ 
+-        return 0, [basecmd + ' done']
++        return result, [basecmd + ' done']
+ 
+     def needTs(self, base, basecmd, extcmds):
+         if not len(extcmds) or extcmds[0] != 'extras':
+
+commit 7a94cf4434107bfcb32e60420af2106b993c7381
+Author: Michal Domonkos <mdomonko@redhat.com>
+Date:   Thu Feb 16 17:47:53 2017 +0100
+
+    docs: verify: fix wording. BZ 1406891
+
+diff --git a/docs/yum-verify.1 b/docs/yum-verify.1
+index 5246a1c..1a8cc11 100644
+--- a/docs/yum-verify.1
++++ b/docs/yum-verify.1
+@@ -6,7 +6,7 @@ yum verify plugin
+ \fByum\fP [options] verify [package ...]
+ .SH "DESCRIPTION"
+ .PP 
+-This plugin extends \fByum\fP with some commands that give verification information on the installed system, much like rpm \-V. You can change how the verification is done and which files it applies to.
++This plugin extends \fByum\fP with some commands that give verification information on the installed system, much like rpm \-V. You can change how the verification is done and which files it applies to. In case any mismatches are found, the exit status is set to 1.
+ .PP 
+ added yum \fIcommand\fPs are:
+ .br 
+@@ -17,7 +17,7 @@ added yum \fIcommand\fPs are:
+ .I \fR * verify-all
+ .br 
+ .PP 
+-all of which take the same arguments as the list yum command, obviously you can
++all of which take the same arguments as the list yum command. You can
+ only verify packages that are installed on the system.
+ .PP
+ .br 
+@@ -29,8 +29,7 @@ output. It removes all false matches due to multilib and ignores changes to
+ configuration files by default.
+ .IP
+ .IP "\fBverify-rpm\fP"
+-Is meant to be 100% compatible with rpm \-V output, and any differences should be
+-considered as bugs.
++Does the same checks as rpm \-V.
+ .IP
+ .IP "\fBverify-all\fP"
+ Is used to list all the differences, including some that rpm itself will ignore.
diff --git a/SOURCES/BZ-1428210-fastestmirror-use-prereposetup.patch b/SOURCES/BZ-1428210-fastestmirror-use-prereposetup.patch
new file mode 100644
index 0000000..f8f4b52
--- /dev/null
+++ b/SOURCES/BZ-1428210-fastestmirror-use-prereposetup.patch
@@ -0,0 +1,68 @@
+commit f62ca0e78ff5b087c0cb49d858e040a5c5284eeb
+Author: Michal Domonkos <mdomonko@redhat.com>
+Date:   Mon Jun 5 20:29:10 2017 +0200
+
+    fastestmirror: move the logic before MD retrieval. BZ 1428210
+    
+    This plugin has had no effect on metadata downloads since commit a522869
+    in yum where we put a RepoStorage.retrieveAllMD() call before
+    postreposetup_hook used by this plugin.  Let's change to using
+    prereposetup_hook instead so that retrieveAllMD() can make use of the
+    sorted urls.
+    
+    In practice, though, mirrors would still be benchmarked and sorted
+    because of a similar mechanism present in urlgrabber (the timedhosts
+    option, always enabled in yum) with one exception:  If the yum cache is
+    empty (no timedhosts file yet), the original order received from the
+    server would be retained (a property of stable sorting [1]) for the
+    repomd.xml download, which is still a bad situation that wouldn't happen
+    before a522869; this is fixed with this commit as it allows the plugin
+    to do its work beforehand.
+    
+    Note that the stuff we do in yum/repos.py in between prereposetup_hook
+    and postreposetup_hook has nothing to do with our plugin anyway, so we
+    won't "miss" or break any configuration steps when we move our logic
+    from the latter to the former location.
+    
+    [1] urlgrabber/mirror.py:275
+
+diff --git a/plugins/fastestmirror/fastestmirror.py b/plugins/fastestmirror/fastestmirror.py
+index fe79629..5887e32 100644
+--- a/plugins/fastestmirror/fastestmirror.py
++++ b/plugins/fastestmirror/fastestmirror.py
+@@ -146,7 +146,7 @@ def _len_non_ftp(urls):
+         num += 1
+     return num
+ 
+-def postreposetup_hook(conduit):
++def prereposetup_hook(conduit):
+     """
+     This function is called after Yum has initiliazed all the repository information.
+ 
+@@ -255,7 +255,7 @@ def read_timedhosts():
+     communicate with other functions.
+ 
+     This function is referred by:
+-        - L{postreposetup_hook()}
++        - L{prereposetup_hook()}
+ 
+     @param timedhosts : A list of time intervals to reach different hosts
+     corresponding to the mirrors. The index of the list are hostnames.
+@@ -281,7 +281,7 @@ def write_timedhosts():
+     communicate with other functions.
+ 
+     This function is referred by:
+-        - L{postreposetup_hook()}
++        - L{prereposetup_hook()}
+ 
+     @param timedhosts : A list of time intervals to reach different hosts
+     corresponding to the mirrors. The index of the list are hostnames.
+@@ -359,7 +359,7 @@ class FastestMirror:
+             - L{FastestMirror._poll_mirrors()}
+ 
+         This function is referred by:
+-            - L{postreposetup_hook()}
++            - L{prereposetup_hook()}
+             - L{main()}
+ 
+         @rtype: List
diff --git a/SOURCES/BZ-1429831-yum-copr.patch b/SOURCES/BZ-1429831-yum-copr.patch
new file mode 100644
index 0000000..1485c61
--- /dev/null
+++ b/SOURCES/BZ-1429831-yum-copr.patch
@@ -0,0 +1,473 @@
+diff -N -up -r a/docs/Makefile b/docs/Makefile
+--- a/docs/Makefile	2017-03-21 14:21:12.326518685 +0100
++++ b/docs/Makefile	2017-03-21 14:24:34.711624331 +0100
+@@ -5,7 +5,7 @@ DOCS = repoquery package-cleanup repo-rs
+        find-repos-of-install needs-restarting repo-graph repoclosure \
+        repomanage repotrack verifytree yum-config-manager yum-ovl
+ DOCS5 = yum-changelog.conf yum-versionlock.conf yum-fs-snapshot.conf
+-DOCS8 = yum-complete-transaction yumdb
++DOCS8 = yum-complete-transaction yumdb yum-copr
+ 
+ all:
+ 	echo "Nothing to do"
+diff -N -up -r a/docs/yum-copr.8 b/docs/yum-copr.8
+--- a/docs/yum-copr.8	1970-01-01 01:00:00.000000000 +0100
++++ b/docs/yum-copr.8	2017-03-21 14:23:17.436729456 +0100
+@@ -0,0 +1,120 @@
++.\" Man page generated from reStructuredText.
++.
++.TH "YUM-COPR" "8" "July 29, 2014" "0.1.1" "yum-plugin-copr"
++.SH NAME
++yum-plugin-copr \- YUM copr Plugin
++.
++.nr rst2man-indent-level 0
++.
++.de1 rstReportMargin
++\\$1 \\n[an-margin]
++level \\n[rst2man-indent-level]
++level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
++-
++\\n[rst2man-indent0]
++\\n[rst2man-indent1]
++\\n[rst2man-indent2]
++..
++.de1 INDENT
++.\" .rstReportMargin pre:
++. RS \\$1
++. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
++. nr rst2man-indent-level +1
++.\" .rstReportMargin post:
++..
++.de UNINDENT
++. RE
++.\" indent \\n[an-margin]
++.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
++.nr rst2man-indent-level -1
++.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
++.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
++..
++.
++.nr rst2man-indent-level 0
++.
++.de1 rstReportMargin
++\\$1 \\n[an-margin]
++level \\n[rst2man-indent-level]
++level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
++-
++\\n[rst2man-indent0]
++\\n[rst2man-indent1]
++\\n[rst2man-indent2]
++..
++.de1 INDENT
++.\" .rstReportMargin pre:
++. RS \\$1
++. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
++. nr rst2man-indent-level +1
++.\" .rstReportMargin post:
++..
++.de UNINDENT
++. RE
++.\" indent \\n[an-margin]
++.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
++.nr rst2man-indent-level -1
++.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
++.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
++..
++.sp
++Work with Copr & Playground repositories on the local system.
++.INDENT 0.0
++.IP \(bu 2
++The \fBcopr\fP command is used to add or remove Copr repositories to the local system
++.IP \(bu 2
++The \fBplayground\fP is used to enable or disable the Playground repository
++.UNINDENT
++.SH SYNOPSIS
++.sp
++\fByum copr [enable|disable|list|search] <parameters>\fP
++.sp
++\fByum playground [enable|disable|upgrade]\fP
++.SH ARGUMENTS (COPR)
++.INDENT 0.0
++.TP
++.B \fBenable name/project [chroot]\fP
++Enable the \fBname/project\fP Copr repository with the optional \fBchroot\fP\&.
++.TP
++.B \fBdisable name/project\fP
++Disable the \fBname/project\fP Copr repository.
++.TP
++.B \fBlist name\fP
++List available Copr repositories for a given \fBname\fP\&.
++.TP
++.B \fBsearch project\fP
++Search for a given \fBproject\fP\&.
++.UNINDENT
++.SH ARGUMENTS (PLAYGROUND)
++.INDENT 0.0
++.TP
++.B \fBenable\fP
++Enable the Playground repository.
++.TP
++.B \fBdisable\fP
++Disable the Playground repository.
++.TP
++.B \fBupgrade\fP
++Upgrade the Playground repository settings (same as \fBdisable\fP and then \fBenable\fP).
++.UNINDENT
++.SH EXAMPLES
++.INDENT 0.0
++.TP
++.B \fBcopr enable rhscl/perl516 epel\-6\-x86_64\fP
++Enable the \fBrhscl/perl516\fP Copr repository, using the \fBepel\-6\-x86_64\fP chroot.
++.TP
++.B \fBcopr disable rhscl/perl516\fP
++Disable the \fBrhscl/perl516\fP Copr repository
++.TP
++.B \fBcopr list rita\fP
++List available Copr projects for user \fBrita\fP\&.
++.TP
++.B \fBcopr search tests\fP
++Search for Copr projects named \fBtests\fP\&.
++.UNINDENT
++.SH AUTHOR
++See AUTHORS in the Core DNF Plugins distribution
++.SH COPYRIGHT
++2014, Red Hat, Licensed under GPLv2+
++.\" Generated by docutils manpage writer.
++.
+diff -N -up -r a/plugins/copr/copr.conf b/plugins/copr/copr.conf
+--- a/plugins/copr/copr.conf	1970-01-01 01:00:00.000000000 +0100
++++ b/plugins/copr/copr.conf	2017-03-21 14:22:49.094134790 +0100
+@@ -0,0 +1,2 @@
++[main]
++enabled=1
+diff -N -up -r a/plugins/copr/copr.py b/plugins/copr/copr.py
+--- a/plugins/copr/copr.py	1970-01-01 01:00:00.000000000 +0100
++++ b/plugins/copr/copr.py	2017-03-21 14:22:49.095134776 +0100
+@@ -0,0 +1,327 @@
++# supplies the 'copr' command.
++#
++# Copyright (C) 2014  Red Hat, Inc.
++#
++# This copyrighted material is made available to anyone wishing to use,
++# modify, copy, or redistribute it subject to the terms and conditions of
++# the GNU General Public License v.2, or (at your option) any later version.
++# This program is distributed in the hope that it will be useful, but WITHOUT
++# ANY WARRANTY expressed or implied, including the implied warranties of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
++# Public License for more details.  You should have received a copy of the
++# GNU General Public License along with this program; if not, write to the
++# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
++# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
++# source code or documentation are not subject to the GNU General Public
++# License and may only be used or replicated with the express permission of
++# Red Hat, Inc.
++#
++
++"""YUM plugin supplying the 'copr' command."""
++
++from urlgrabber import grabber
++
++import yum
++import glob
++import json
++import os
++import platform
++import requests
++import urllib
++
++from yum.i18n import _
++from yum.plugins import TYPE_INTERACTIVE
++
++requires_api_version = '2.5'
++plugin_type = (TYPE_INTERACTIVE,)
++
++yes = set([_('yes'), _('y')])
++no = set([_('no'), _('n'), ''])
++
++YError = yum.Errors.YumBaseError
++YCliError = yum.Errors.MiscError
++
++def config_hook(conduit):
++    conduit.registerCommand(CoprCommand())
++    conduit.registerCommand(PlaygroundCommand())
++
++class CoprCommand:
++    """ Copr plugin for DNF """
++
++    def getNames(self):
++        return [self.aliases[0]]
++
++    def getUsage(self):
++        return self.usage
++
++    def getSummary(self):
++        return self.summary[1:]
++
++    def doCheck(self, base, basecmd, extcmds):
++        self.base = base
++
++    copr_url = "https://copr.fedoraproject.org"
++    aliases = ("copr",)
++    summary = _("Interact with Copr repositories.")
++    usage = _("""
++  enable name/project [chroot]
++  disable name/project
++  list name
++  search project
++
++  Examples:
++  copr enable rhscl/perl516 epel-6-x86_64
++  copr enable ignatenkobrain/ocltoys
++  copr disable rhscl/perl516
++  copr list ignatenkobrain
++  copr search tests
++    """)
++
++    def doCommand(self, base, basecmd, extcmds):
++        try:
++            subcommand = extcmds[0]
++            project_name = extcmds[1]
++        except (ValueError, IndexError):
++            base.logger.critical(
++                _('Error: ') +
++                _('exactly two additional parameters to '
++                  'copr command are required'))
++            # FIXME
++            # dnf.cli.commands.err_mini_usage(self.cli, self.cli.base.basecmd)
++            raise YCliError(
++                _('exactly two additional parameters to '
++                  'copr command are required'))
++        try:
++            chroot = extcmds[2]
++        except IndexError:
++            chroot = self._guess_chroot()
++        repo_filename = "/etc/yum.repos.d/_copr_{}.repo" \
++                        .format(project_name.replace("/", "-"))
++        if subcommand == "enable":
++            self._need_root()
++            self._ask_user("""
++You are about to enable a Copr repository. Please note that this
++repository is not part of the main Fedora distribution, and quality
++may vary.
++
++The Fedora Project does not exercise any power over the contents of
++this repository beyond the rules outlined in the Copr FAQ at
++<https://fedorahosted.org/copr/wiki/UserDocs#WhatIcanbuildinCopr>, and
++packages are not held to any quality or securty level.
++
++Please do not file bug reports about these packages in Fedora
++Bugzilla. In case of problems, contact the owner of this repository.
++
++Do you want to continue? [y/N]: """)
++            self._download_repo(project_name, repo_filename, chroot)
++            base.logger.info(_("Repository successfully enabled."))
++        elif subcommand == "disable":
++            self._need_root()
++            self._remove_repo(repo_filename)
++            base.logger.info(_("Repository successfully disabled."))
++        elif subcommand == "list":
++            #http://copr.fedoraproject.org/api/coprs/ignatenkobrain/
++            api_path = "/api/coprs/{}/".format(project_name)
++
++            opener = urllib.FancyURLopener({})
++            res = opener.open(self.copr_url + api_path)
++            try:
++                json_parse = json.loads(res.read())
++            except ValueError:
++                raise YError(
++                    _("Can't parse repositories for username '{}'.")
++                    .format(project_name))
++            section_text = _("List of {} coprs").format(project_name)
++            self._print_match_section(section_text)
++            i = 0
++            while i < len(json_parse["repos"]):
++                msg = "{0}/{1} : ".format(project_name,
++                      json_parse["repos"][i]["name"])
++                desc = json_parse["repos"][i]["description"]
++                if not desc:
++                    desc = _("No description given")
++                msg = self.base.fmtKeyValFill(unicode(msg), desc)
++                print(msg)
++                i += 1
++        elif subcommand == "search":
++            #http://copr.fedoraproject.org/api/coprs/search/tests/
++            api_path = "/api/coprs/search/{}/".format(project_name)
++
++            opener = urllib.FancyURLopener({})
++            res = opener.open(self.copr_url + api_path)
++            try:
++                json_parse = json.loads(res.read())
++            except ValueError:
++                raise YError(_("Can't parse search for '{}'.").format(project_name))
++            section_text = _("Matched: {}").format(project_name)
++            self._print_match_section(section_text)
++            i = 0
++            while i < len(json_parse["repos"]):
++                msg = "{0}/{1} : ".format(json_parse["repos"][i]["username"], json_parse["repos"][i]["coprname"])
++                desc = json_parse["repos"][i]["description"]
++                if not desc:
++                    desc = _("No description given.")
++                msg = self.base.fmtKeyValFill(unicode(msg), desc)
++                print(msg)
++                i += 1
++        else:
++            raise YError(
++                _('Unknown subcommand {}.').format(subcommand))
++
++        return 0, [basecmd + ' done']
++
++    def _print_match_section(self, text):
++        formatted = self.base.fmtSection(text)
++        print(formatted)
++
++    def _ask_user(self, question):
++        if self.base.conf.assumeyes and not self.base.conf.assumeno:
++            return
++        elif self.base.conf.assumeno and not self.base.conf.assumeyes:
++            raise YError(_('Safe and good answer. Exiting.'))
++
++        answer = raw_input(question).lower()
++        answer = _(answer)
++        while not ((answer in yes) or (answer in no)):
++            answer = raw_input(question).lower()
++            answer = _(answer)
++        if answer in yes:
++            return
++        else:
++            raise YError(_('Safe and good answer. Exiting.'))
++
++    @classmethod
++    def _need_root(cls):
++        # FIXME this should do dnf itself (BZ#1062889)
++        if os.geteuid() != 0:
++            raise YError(
++                _('This command has to be run under the root user.'))
++
++    @classmethod
++    def _guess_chroot(cls):
++        """ Guess which choot is equivalent to this machine """
++        # FIXME Copr should generate non-specific arch repo
++        dist = platform.linux_distribution()
++        if "Fedora" in dist:
++            # x86_64 because repo-file is same for all arch
++            # ($basearch is used)
++            if "Rawhide" in dist:
++                chroot = ("fedora-rawhide-x86_64")
++            else:
++                chroot = ("fedora-{}-x86_64".format(dist[1]))
++        else:
++            chroot = ("epel-%s-x86_64" % dist[1].split(".", 1)[0])
++        return chroot
++
++    @classmethod
++    def _download_repo(cls, project_name, repo_filename, chroot=None):
++        if chroot is None:
++            chroot = cls._guess_chroot()
++        #http://copr.fedoraproject.org/coprs/larsks/rcm/repo/epel-7-x86_64/
++        api_path = "/coprs/{0}/repo/{1}/".format(project_name, chroot)
++        ug = grabber.URLGrabber()
++        # FIXME when we are full on python2 urllib.parse
++        try:
++            ug.urlgrab(cls.copr_url + api_path, filename=repo_filename)
++        except grabber.URLGrabError as e:
++            cls._remove_repo(repo_filename)
++            raise YError(str(e))
++
++    @classmethod
++    def _remove_repo(cls, repo_filename):
++        # FIXME is it Copr repo ?
++        try:
++            os.remove(repo_filename)
++        except OSError as e:
++            raise YError(str(e))
++
++    @classmethod
++    def _get_data(cls, req):
++        """ Wrapper around response from server
++
++        check data and print nice error in case of some error (and return None)
++        otherwise return json object.
++        """
++        try:
++            output = json.loads(req.text)
++        except ValueError:
++            YCliError(_("Unknown response from server."))
++            return
++        if req.status_code != 200:
++            YCliError(_(
++                "Something went wrong:\n {0}\n".format(output["error"])))
++            return
++        return output
++
++
++class PlaygroundCommand(CoprCommand):
++    """ Playground plugin for DNF """
++
++    aliases = ("playground",)
++    summary = _("Interact with Playground repository.")
++    usage = " [enable|disable|upgrade]"
++
++    def _cmd_enable(self, chroot):
++        self._need_root()
++        self._ask_user("""
++You are about to enable a Playground repository.
++
++Do you want to continue? [y/N]: """)
++        api_url = "{0}/api/playground/list/".format(
++            self.copr_url)
++        req = requests.get(api_url)
++        output = self._get_data(req)
++        if output["output"] != "ok":
++            raise YCliError(_("Unknown response from server."))
++        for repo in output["repos"]:
++            project_name = "{0}/{1}".format(repo["username"],
++                repo["coprname"])
++            repo_filename = "/etc/yum.repos.d/_playground_{}.repo" \
++                    .format(project_name.replace("/", "-"))
++            try:
++                # check if that repo exist? but that will result in twice
++                # up calls
++                api_url = "{0}/api/coprs/{1}/detail/{2}/".format(
++                    self.copr_url, project_name, chroot)
++                req = requests.get(api_url)
++                output2 = self._get_data(req)
++                if output2 and ("output" in output2) and (output2["output"] == "ok"):
++                    self._download_repo(project_name, repo_filename, chroot)
++            except YError:
++                # likely 404 and that repo does not exist
++                pass
++
++    def _cmd_disable(self):
++        self._need_root()
++        for repo_filename in glob.glob('/etc/yum.repos.d/_playground_*.repo'):
++            self._remove_repo(repo_filename)
++
++    def doCommand(self, base, basecmd, extcmds):
++        try:
++            subcommand = extcmds[0]
++        except (ValueError, IndexError):
++            base.logger.critical(
++                _('Error: ') +
++                _('exactly one parameter to '
++                  'playground command are required'))
++            # FIXME:
++            # dnf.cli.commands.err_mini_usage(self.cli, self.cli.base.basecmd)
++            raise YCliError(
++                _('exactly one parameter to '
++                  'playground command are required'))
++        chroot = self._guess_chroot()
++        if subcommand == "enable":
++            self._cmd_enable(chroot)
++            base.logger.info(_("Playground repositories successfully enabled."))
++        elif subcommand == "disable":
++            self._cmd_disable()
++            base.logger.info(_("Playground repositories successfully disabled."))
++        elif subcommand == "upgrade":
++            self._cmd_disable()
++            self._cmd_enable(chroot)
++            base.logger.info(_("Playground repositories successfully updated."))
++        else:
++            raise YError(
++                _('Unknown subcommand {}.').format(subcommand))
++
++        return 0, [basecmd + ' done']
diff --git a/SOURCES/BZ-1437636-yum-builddep-add-define-opt.patch b/SOURCES/BZ-1437636-yum-builddep-add-define-opt.patch
new file mode 100644
index 0000000..f8a6030
--- /dev/null
+++ b/SOURCES/BZ-1437636-yum-builddep-add-define-opt.patch
@@ -0,0 +1,64 @@
+diff --git a/docs/yum-builddep.1 b/docs/yum-builddep.1
+index fbe32bd..54dce0e 100644
+--- a/docs/yum-builddep.1
++++ b/docs/yum-builddep.1
+@@ -17,6 +17,12 @@ disabled) or it can be a local source RPM or a spec file.
+ .PP 
+ Note, that only the BuildRequires information within the SRPM header information is used to determine build dependencies. This will specifically omit any dependencies that are required only for specific architectures.
+ .PP
++.SH "GENERAL OPTIONS"
++.IP "\fB\--target ARCH\fP"
++Set target architecture for spec parsing.
++.IP "\fB\--define 'MACRO EXPR'\fP"
++Define the rpm MACRO with value EXPR for spec parsing.
++.PP
+ .SH "EXAMPLES"
+ .IP "Download and install all the RPMs needed to build the kernel RPM:"
+ \fByumdownloader --source kernel && rpm2cpio kernel*src.rpm | cpio -i kernel.spec && \\ \fP
+diff --git a/yum-builddep.py b/yum-builddep.py
+index 5f59ab8..dfdd31b 100755
+--- a/yum-builddep.py
++++ b/yum-builddep.py
+@@ -67,6 +67,13 @@ class YumBuildDep(YumUtilBase):
+         if hasattr(rpm, 'reloadConfig'):
+             self.optparser.add_option("--target",
+                               help="set target architecture for spec parsing")
++            self.optparser.add_option(
++                "--define",
++                action="append",
++                default=[],
++                metavar="'MACRO EXPR'",
++                help="define the rpm MACRO with value EXPR for spec parsing",
++            )
+         self.main()
+ 
+     def main(self):
+@@ -229,11 +236,28 @@ class YumBuildDep(YumUtilBase):
+             self.logger.info('Getting requirements for %s' % srpm)
+             self.install_deps(srpm.requiresList(), opts)
+     
++        # Parse macro defines
++        macros = []
++        error = False
++        for define in opts.define:
++            words = define.split(None, 1)
++            if len(words) == 1:
++                self.logger.error('Error: No EXPR given for MACRO %%%s'
++                                  % words[0])
++                error = True
++                continue
++            macros.append(words)
++        if error:
++            sys.exit(1)
++
+         for name in specnames:
+             # (re)load rpm config for target if set
+             if reloadworks and opts.target:
+                 rpm.reloadConfig(opts.target)
+ 
++            for macro in macros:
++                rpm.addMacro(*macro)
++
+             try:
+                 spec = rpm.spec(name)
+             except ValueError:
diff --git a/SOURCES/BZ-1445751-yum-debug-dump-improve-repo-failure-handling.patch b/SOURCES/BZ-1445751-yum-debug-dump-improve-repo-failure-handling.patch
new file mode 100644
index 0000000..67ce20d
--- /dev/null
+++ b/SOURCES/BZ-1445751-yum-debug-dump-improve-repo-failure-handling.patch
@@ -0,0 +1,48 @@
+commit 61232e9f66cc64fffa8517678b6cf224d44b02ef
+Author: Michal Domonkos <mdomonko@redhat.com>
+Date:   Wed Jul 12 16:27:53 2017 +0200
+
+    yum-debug-dump: improve repo failure handling. BZ 1445751
+    
+    Populate the repos prior to iterating over them in dump_repos().  This
+    fixes the following bugs:
+    
+    1) KeyError when calling returnPackages() on a repo that was previously
+       disabled by the pkgSack invocation in the same loop due to
+       skip_if_unavailable=true (BZ 1445751)
+    
+    2) One broken repo with skip_if_unavailable=false would cause all other
+       (even working) repos in the for loop to report the same error, thus
+       making the %%%%REPOS section useless
+
+diff --git a/yum-debug-dump.py b/yum-debug-dump.py
+index 67d943f..01ca338 100755
+--- a/yum-debug-dump.py
++++ b/yum-debug-dump.py
+@@ -73,6 +73,26 @@ class YumDebugDump(yum.YumBase):
+ 
+     def dump_repos(self):
+         msg = "%%%%REPOS\n"
++
++        # Set up the sacks first, to capture and log any broken repos.  We
++        # cannot yet call returnPackages() from this loop as that would lead to
++        # a KeyError if some repo got disabled by pkgSack due to
++        # skip_if_unavailable=true in a previous iteration.
++        #
++        # A failure means remaining repos were not processed, so we have to
++        # retry the whole process ourselves by calling pkgSack again.  Since
++        # the worst case scenario is that all the repos are broken, we have to
++        # do this at least as many times as there are enabled repos.
++        for repo in sorted(self.repos.listEnabled()):
++            try:
++                self.pkgSack
++            except Errors.RepoError, e:
++                msg += "Error accessing repo %s: %s\n" % (e.repo, str(e))
++                self.repos.disableRepo(e.repo.id)
++            else:
++                break
++
++        # Dump the packages now
+         for repo in sorted(self.repos.listEnabled()):
+             try:
+                 msg += '%%%s - %s\n' % (repo.id, repo.urls[0])
diff --git a/SOURCES/BZ-1455318-package-cleanup-dont-remove-required.patch b/SOURCES/BZ-1455318-package-cleanup-dont-remove-required.patch
new file mode 100644
index 0000000..2bf732c
--- /dev/null
+++ b/SOURCES/BZ-1455318-package-cleanup-dont-remove-required.patch
@@ -0,0 +1,199 @@
+commit f84a2dbcc28312105246fac51771481640759da5
+Author: Phil Dibowitz <phil@ipom.com>
+Date:   Thu Jul 2 11:40:55 2015 -0700
+
+    Add option to remove newest dupes instead of oldest dupes
+    
+    Sometimes in a failed transaction you need to remove the newest of the dupes and
+    not the oldest. This provides that option.
+
+diff --git a/package-cleanup.py b/package-cleanup.py
+index acad9f2..13cfb89 100755
+--- a/package-cleanup.py
++++ b/package-cleanup.py
+@@ -79,6 +79,9 @@ class PackageCleanup(YumUtilBase):
+         dupegrp.add_option("--cleandupes", default=False, 
+                     dest="cleandupes", action="store_true",
+                     help='Scan for duplicates in your rpmdb and remove older ')
++        dupegrp.add_option("--removenewestdupes", default=False, 
++                    dest="removenewestdupes", action="store_true",
++                    help='Remove the newest dupes instead of the oldest dupes.')
+         dupegrp.add_option("--noscripts", default=False,
+                     dest="noscripts", action="store_true",
+                     help="disable rpm scriptlets from running when cleaning duplicates")
+@@ -172,7 +175,7 @@ class PackageCleanup(YumUtilBase):
+             
+         return results
+ 
+-    def _remove_old_dupes(self):
++    def _remove_dupes(self, newest=False):
+         """add older duplicate pkgs to be removed in the transaction"""
+         dupedict = self._find_installed_duplicates()
+ 
+@@ -180,7 +183,11 @@ class PackageCleanup(YumUtilBase):
+         for (name,dupelists) in dupedict.items():
+             for dupelist in dupelists:
+                 dupelist.sort()
+-                for lowpo in dupelist[0:-1]:
++                if newest:
++                    plist = dupelist[1:]
++                else:
++                    plist = dupelist[0:-1]
++                for lowpo in plist:
+                     removedupes.append(lowpo)
+ 
+         for po in removedupes:
+@@ -373,7 +380,7 @@ class PackageCleanup(YumUtilBase):
+                 sys.exit(1)
+             if opts.noscripts:
+                 self.conf.tsflags.append('noscripts')
+-            self._remove_old_dupes()
++            self._remove_dupes(opts.removenewestdupes)
+             self.run_with_package_names.add('yum-utils')
+ 
+             if hasattr(self, 'doUtilBuildTransaction'):
+commit 27784822a342debd3ecfa04686a35f2e7e576023
+Author: Michal Domonkos <mdomonko@redhat.com>
+Date:   Wed Oct 11 19:26:38 2017 +0200
+
+    package-cleanup: don't remove required dupes. BZ 1455318
+    
+    Note: Turning removedupes into a set for O(1) complexity on
+    removedupes.remove().
+
+diff --git a/package-cleanup.py b/package-cleanup.py
+index 13cfb89..9f74609 100755
+--- a/package-cleanup.py
++++ b/package-cleanup.py
+@@ -176,10 +176,12 @@ class PackageCleanup(YumUtilBase):
+         return results
+ 
+     def _remove_dupes(self, newest=False):
+-        """add older duplicate pkgs to be removed in the transaction"""
+-        dupedict = self._find_installed_duplicates()
++        """add duplicate pkgs to be removed in the transaction,
++           return a dict of excluded dupes and their requiring packages"""
+ 
+-        removedupes = []
++        # Find dupes
++        dupedict = self._find_installed_duplicates()
++        removedupes = set()
+         for (name,dupelists) in dupedict.items():
+             for dupelist in dupelists:
+                 dupelist.sort()
+@@ -188,11 +190,37 @@ class PackageCleanup(YumUtilBase):
+                 else:
+                     plist = dupelist[0:-1]
+                 for lowpo in plist:
+-                    removedupes.append(lowpo)
+-
++                    removedupes.add(lowpo)
++
++        # Exclude any such dupes that would pull other installed packages into
++        # the removal transaction (to prevent us from accidentally removing a
++        # huge part of a working system) by performing a dry transaction(s)
++        # first.
++        excluded = {}
++        while True:
++            for po in removedupes:
++                self.remove(po)
++            changed = False
++            for txmbr in self.tsInfo.getMembers():
++                requiredby = self._checkRemove(txmbr)
++                if requiredby:
++                    removedupes.remove(txmbr.po)
++                    excluded[txmbr.po] = requiredby
++                    # Do another round, to cover any transitive deps within
++                    # removedupes, for example: if foo requires bar requires
++                    # baz and removedupes contains bar and baz, then
++                    # _checkRemove(baz) won't return bar.
++                    changed = True
++            del self.tsInfo
++            if not changed:
++                break
++
++        # Mark the dupes for removal
+         for po in removedupes:
+             self.remove(po)
+ 
++        return excluded
++
+ 
+     def _should_show_leaf(self, po, leaf_regex, exclude_devel, exclude_bin):
+         """
+@@ -380,7 +408,13 @@ class PackageCleanup(YumUtilBase):
+                 sys.exit(1)
+             if opts.noscripts:
+                 self.conf.tsflags.append('noscripts')
+-            self._remove_dupes(opts.removenewestdupes)
++            excluded = self._remove_dupes(opts.removenewestdupes)
++            for po, requiredby in excluded.iteritems():
++                count = len(requiredby)
++                print ('Not removing %s because it is required by %s '
++                       'installed package%s' %
++                       (po.hdr.sprintf(opts.qf), count,
++                        's' if count > 1 else ''))
+             self.run_with_package_names.add('yum-utils')
+ 
+             if hasattr(self, 'doUtilBuildTransaction'):
+@@ -397,9 +431,20 @@ class PackageCleanup(YumUtilBase):
+ 
+             if len(self.tsInfo) < 1:
+                 print 'No duplicates to remove'
+-                sys.exit(0)
+-                
+-            sys.exit(self.doUtilTransaction())
++                errc = 0
++            else:
++                errc = self.doUtilTransaction()
++
++            if excluded:
++                self.logger.warn(
++                    'Warning: Some duplicates were not removed because they '
++                    'are required by installed packages.\n'
++                    'You can try --cleandupes with%s --removenewestdupes, '
++                    'or review them with --dupes and remove manually.' %
++                    ('out' if opts.removenewestdupes else '')
++                )
++
++            sys.exit(errc)
+ 
+     
+ if __name__ == '__main__':
+commit 4594bbc623b68bea6522047fb6267069c8ad94c8
+Author: Michal Domonkos <mdomonko@redhat.com>
+Date:   Wed Oct 11 20:23:06 2017 +0200
+
+    package-cleanup: update man page
+    
+    Add missing options from --help and also clear up the wording of
+    --removenewestdupes.
+
+diff --git a/docs/package-cleanup.1 b/docs/package-cleanup.1
+index 61959ac..5b7e1c0 100644
+--- a/docs/package-cleanup.1
++++ b/docs/package-cleanup.1
+@@ -36,6 +36,10 @@ Scan for duplicates in the local RPM database.
+ .IP "\fB\-\-cleandupes\fP"
+ Scan for duplicates in the local RPM database and clean out the
+ older versions.
++.IP "\fB\-\-removenewestdupes\fP"
++Remove the newest dupes instead of the oldest dupes when cleaning duplicates.
++.IP "\fB\-\-noscripts\fP"
++Disable rpm scriptlets from running when cleaning duplicates.
+ .IP "\fB\-\-count <COUNT>\fP"
+ Number of duplicate/kernel packages to keep on the system (default 2)
+ .PP 
+diff --git a/package-cleanup.py b/package-cleanup.py
+index 9f74609..4a44326 100755
+--- a/package-cleanup.py
++++ b/package-cleanup.py
+@@ -81,7 +81,7 @@ class PackageCleanup(YumUtilBase):
+                     help='Scan for duplicates in your rpmdb and remove older ')
+         dupegrp.add_option("--removenewestdupes", default=False, 
+                     dest="removenewestdupes", action="store_true",
+-                    help='Remove the newest dupes instead of the oldest dupes.')
++                    help='Remove the newest dupes instead of the oldest dupes when cleaning duplicates.')
+         dupegrp.add_option("--noscripts", default=False,
+                     dest="noscripts", action="store_true",
+                     help="disable rpm scriptlets from running when cleaning duplicates")
diff --git a/SOURCES/BZ-1458098-yumdownloader-crash-broken-metadata.patch b/SOURCES/BZ-1458098-yumdownloader-crash-broken-metadata.patch
new file mode 100644
index 0000000..ab69980
--- /dev/null
+++ b/SOURCES/BZ-1458098-yumdownloader-crash-broken-metadata.patch
@@ -0,0 +1,21 @@
+commit 6fa187521c370a3b13503ee330140778d1dbafc1
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Fri Oct 20 13:33:11 2017 +0200
+
+    yumdownloader: fix crash on broken srpm metadata.
+
+diff --git a/yumdownloader.py b/yumdownloader.py
+index 1b95e8d..a0db95c 100755
+--- a/yumdownloader.py
++++ b/yumdownloader.py
+@@ -47,6 +47,10 @@ def _best_convert_pkg2srcpkgs(self, opts, pkg):
+     if not opts.source or pkg.arch == 'src':
+         return [pkg]
+ 
++    if pkg.sourcerpm is None:
++        self.logger.error('No source RPM found for %s' % str(pkg))
++        return []
++
+     (n,v,r,e,a) = rpmUtils.miscutils.splitFilename(pkg.sourcerpm)
+     src = self.pkgSack.searchNevra(name=n, ver=v, rel=r, arch='src')
+     if src == []:
diff --git a/SOURCES/BZ-1470647-add-pre-transaction-actions-plugin.patch b/SOURCES/BZ-1470647-add-pre-transaction-actions-plugin.patch
new file mode 100644
index 0000000..9059dc8
--- /dev/null
+++ b/SOURCES/BZ-1470647-add-pre-transaction-actions-plugin.patch
@@ -0,0 +1,200 @@
+diff -up yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.conf.orig yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.conf
+--- yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.conf.orig	2017-10-27 17:30:16.579550073 +0200
++++ yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.conf	2017-10-27 17:30:16.579550073 +0200
+@@ -0,0 +1,3 @@
++[main]
++enabled = 1
++actiondir = /etc/yum/pre-actions/
+diff -up yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.py.orig yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.py
+--- yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.py.orig	2017-10-27 17:30:16.579550073 +0200
++++ yum-utils-1.1.31/plugins/pre-transaction-actions/pre-transaction-actions.py	2017-10-27 17:30:16.579550073 +0200
+@@ -0,0 +1,164 @@
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU Library General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++
++# Copyright 2008 Red Hat, Inc
++# written by Seth Vidal <skvidal@fedoraproject.org>
++
++"""
++This plugin runs actions prior to the transaction based on the content of the
++transaction.
++"""
++
++
++from yum.plugins import TYPE_CORE
++from yum.constants import *
++import yum.misc
++from yum.parser import varReplace
++from yum.packages import parsePackages
++import fnmatch
++import re
++import os
++import glob
++import shlex
++
++requires_api_version = '2.4'
++plugin_type = (TYPE_CORE,)
++
++def parse_actions(ddir, conduit):
++    """read in .action files from ddir path. 
++       store content in a list of tuples"""
++    action_tuples = [] # (action key, action_state, shell command)
++    action_file_list = []
++    if os.access(ddir, os.R_OK): 
++        action_file_list.extend(glob.glob(ddir + "*.action"))
++
++    if action_file_list:
++        for f in action_file_list:
++            for line in open(f).readlines():
++                line = line.strip()
++                if line and line[0] != "#":
++                    try:
++                        (a_key, a_state, a_command) = line.split(':', 2)
++                    except ValueError,e:
++                        conduit.error(2,'Bad Action Line: %s' % line)
++                        continue
++                    else:
++                        action_tuples.append((a_key, a_state, a_command))
++
++    return action_tuples
++
++def _convert_vars(txmbr, command):
++    """converts %options on the command to their values from the package it
++       is running it for: takes $name, $arch, $ver, $rel, $epoch, 
++       $state, $repoid"""
++    state_dict = { TS_INSTALL: 'install',
++                   TS_TRUEINSTALL: 'install',
++                   TS_OBSOLETING: 'obsoleting',
++                   TS_UPDATE: 'updating',
++                   TS_ERASE: 'remove',
++                   TS_OBSOLETED: 'obsoleted',
++                   TS_UPDATED: 'updated'}
++    try:
++        state = state_dict[txmbr.output_state]
++    except KeyError:
++        state = 'unknown - %s' % txmbr.output_state
++
++    vardict = {'name': txmbr.name,
++               'arch': txmbr.arch,
++               'ver': txmbr.version,
++               'rel': txmbr.release,
++               'epoch': txmbr.epoch,
++               'repoid': txmbr.repoid,
++               'state':  state }
++
++    result = varReplace(command, vardict)
++    return result
++            
++
++def pretrans_hook(conduit):
++    # we have provides/requires for everything
++    # we do not have filelists for erasures
++    # we have to fetch filelists for the package object for installs/updates
++    action_dir = conduit.confString('main','actiondir','/etc/yum/pre-actions/')
++    action_tuples = parse_actions(action_dir, conduit)
++    commands_to_run = {}
++    ts = conduit.getTsInfo()
++    all = ts.getMembers()
++    removes = ts.getMembersWithState(output_states=TS_REMOVE_STATES)
++    installs = ts.getMembersWithState(output_states=TS_INSTALL_STATES)
++    updates = ts.getMembersWithState(output_states=[TS_UPDATE, TS_OBSOLETING])
++
++    for (a_k, a_s, a_c) in action_tuples:
++        #print 'if %s in state %s the run %s' %( a_k, a_s, a_c)
++        if a_s  == 'update':
++            pkgset = updates
++        elif a_s == 'install':
++            pkgset = installs
++        elif a_s == 'remove':
++            pkgset = removes
++        elif a_s == 'any':
++            pkgset = all
++        else:
++            # no idea what this is skip it
++            conduit.error(2,'whaa? %s' % a_s)
++            continue
++
++        if a_k.startswith('/'):
++            if yum.misc.re_glob(a_k):
++                restring = fnmatch.translate(a_k)
++                c_string = re.compile(restring)
++
++            for txmbr in pkgset:
++                matched = False
++                thispo = txmbr.po
++        
++                if not yum.misc.re_glob(a_k):
++                    if a_k in thispo.filelist + thispo.dirlist + thispo.ghostlist:
++                        thiscommand = _convert_vars(txmbr, a_c)
++                        commands_to_run[thiscommand] = 1
++                        matched = True
++                else:
++                    for name in thispo.filelist + thispo.dirlist + thispo.ghostlist:
++                        if c_string.match(name):
++                            thiscommand = _convert_vars(txmbr, a_c)
++                            commands_to_run[thiscommand] = 1
++                            matched = True
++                            break
++                
++                if matched:
++                    break
++            continue
++        
++        if a_k.find('/') == -1: # pkgspec
++            pkgs = [ txmbr.po for txmbr in pkgset ]
++            e,m,u = parsePackages(pkgs, [a_k])
++            if not u:
++                for pkg in e+m:
++                    for txmbr in ts.getMembers(pkgtup=pkg.pkgtup):
++                        thiscommand = _convert_vars(txmbr, a_c)
++                        commands_to_run[thiscommand] = 1
++            continue
++
++    for comm in commands_to_run.keys():
++        try:
++            args = shlex.split(comm)
++        except ValueError, e:
++            conduit.error(2,"command was not parseable: %s" % comm)
++            continue
++        #try
++        conduit.info(2,'Running pre transaction command: %s' % comm)
++        p = os.system(comm)
++        #except?
++
++
+diff -up yum-utils-1.1.31/plugins/pre-transaction-actions/sample.action.orig yum-utils-1.1.31/plugins/pre-transaction-actions/sample.action
+--- yum-utils-1.1.31/plugins/pre-transaction-actions/sample.action.orig	2017-10-27 17:30:16.579550073 +0200
++++ yum-utils-1.1.31/plugins/pre-transaction-actions/sample.action	2017-10-27 17:30:16.579550073 +0200
+@@ -0,0 +1,21 @@
++#action_key:transaction_state:command
++# action_key can be: pkgglob, /path/to/file (wildcards allowed)
++# transaction_state can be: install,update,remove,any
++# command can be: any shell command
++#  the following variables are allowed to be passed to any command:
++#   $name - package name
++#   $arch - package arch
++#   $ver - package version
++#   $rel - package release
++#   $epoch - package epoch
++#   $repoid - package repository id
++#   $state - text string of state of the package in the transaction set
++#
++# file matches cannot be used with removes b/c we don't have the info available
++
++*:install:touch /tmp/$name-installed
++zsh:remove:touch /tmp/zsh-removed
++zsh:install:touch /tmp/zsh-installed-also
++/bin/z*h:install:touch /tmp/bin-zsh-installed
++z*h:any:touch /tmp/bin-zsh-any
++
diff --git a/SOURCES/BZ-817046-yum-builddep-respect-tolerant-ignore-missing-reqs.patch b/SOURCES/BZ-817046-yum-builddep-respect-tolerant-ignore-missing-reqs.patch
new file mode 100644
index 0000000..ced85c3
--- /dev/null
+++ b/SOURCES/BZ-817046-yum-builddep-respect-tolerant-ignore-missing-reqs.patch
@@ -0,0 +1,47 @@
+commit 744cf9259ccec046a15ab5372270d931b7d74fc9
+Author: Valentina Mukhamedzhanova <vmukhame@redhat.com>
+Date:   Thu Jul 2 16:21:22 2015 +0200
+
+    yum-builddep: respect --tolerant to ignore missing dependencies
+
+diff --git a/yum-builddep.py b/yum-builddep.py
+index 7c40713..5f59ab8 100755
+--- a/yum-builddep.py
++++ b/yum-builddep.py
+@@ -145,7 +145,7 @@ class YumBuildDep(YumUtilBase):
+                 self.logger.info('Enabling %s repository' % r.id)
+                 r.enable()
+ 
+-    def install_deps(self, deplist):
++    def install_deps(self, deplist, opts):
+         errors = set()
+         for dep in deplist:
+             self.logger.debug(' REQ:  %s' % dep)                
+@@ -165,7 +165,8 @@ class YumBuildDep(YumUtilBase):
+         if errors:
+             for i in sorted(errors):
+                 self.logger.error("Error: %s" % i)
+-            sys.exit(1)
++            if not opts.tolerant:
++                sys.exit(1)
+ 
+     # go through each of the pkgs, figure out what they are/where they are 
+     # if they are not a local package then run
+@@ -226,7 +227,7 @@ class YumBuildDep(YumUtilBase):
+ 
+         for srpm in toActOn:
+             self.logger.info('Getting requirements for %s' % srpm)
+-            self.install_deps(srpm.requiresList())
++            self.install_deps(srpm.requiresList(), opts)
+     
+         for name in specnames:
+             # (re)load rpm config for target if set
+@@ -248,7 +249,7 @@ class YumBuildDep(YumUtilBase):
+                 buildreqs.append(d.DNEVR()[2:])
+                 
+             self.logger.info('Getting requirements for %s' % name)
+-            self.install_deps(buildreqs)
++            self.install_deps(buildreqs, opts)
+             
+ if __name__ == '__main__':
+     setup_locale()
diff --git a/SOURCES/yum-utils-HEAD.patch b/SOURCES/yum-utils-HEAD.patch
new file mode 100644
index 0000000..4db6be8
--- /dev/null
+++ b/SOURCES/yum-utils-HEAD.patch
@@ -0,0 +1,4891 @@
+diff --git a/COPYING b/COPYING
+index e77696a..d159169 100644
+--- a/COPYING
++++ b/COPYING
+@@ -1,12 +1,12 @@
+-		    GNU GENERAL PUBLIC LICENSE
+-		       Version 2, June 1991
++                    GNU GENERAL PUBLIC LICENSE
++                       Version 2, June 1991
+ 
+- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+-                          675 Mass Ave, Cambridge, MA 02139, USA
++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  Everyone is permitted to copy and distribute verbatim copies
+  of this license document, but changing it is not allowed.
+ 
+-			    Preamble
++                            Preamble
+ 
+   The licenses for most software are designed to take away your
+ freedom to share and change it.  By contrast, the GNU General Public
+@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users.  This
+ General Public License applies to most of the Free Software
+ Foundation's software and to any other program whose authors commit to
+ using it.  (Some other Free Software Foundation software is covered by
+-the GNU Library General Public License instead.)  You can apply it to
++the GNU Lesser General Public License instead.)  You can apply it to
+ your programs, too.
+ 
+   When we speak of free software, we are referring to freedom, not
+@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
+ 
+   The precise terms and conditions for copying, distribution and
+ modification follow.
+-
+-		    GNU GENERAL PUBLIC LICENSE
++
++                    GNU GENERAL PUBLIC LICENSE
+    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+ 
+   0. This License applies to any program or other work which contains
+@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
+     License.  (Exception: if the Program itself is interactive but
+     does not normally print such an announcement, your work based on
+     the Program is not required to print an announcement.)
+-
++
+ These requirements apply to the modified work as a whole.  If
+ identifiable sections of that work are not derived from the Program,
+ and can be reasonably considered independent and separate works in
+@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
+ access to copy the source code from the same place counts as
+ distribution of the source code, even though third parties are not
+ compelled to copy the source along with the object code.
+-
++
+   4. You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License.  Any attempt
+ otherwise to copy, modify, sublicense or distribute the Program is
+@@ -225,7 +225,7 @@ impose that choice.
+ 
+ This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.
+-
++
+   8. If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Program under this License
+@@ -255,7 +255,7 @@ make exceptions for this.  Our decision will be guided by the two goals
+ of preserving the free status of all derivatives of our free software and
+ of promoting the sharing and reuse of software generally.
+ 
+-			    NO WARRANTY
++                            NO WARRANTY
+ 
+   11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
+ 
+-		     END OF TERMS AND CONDITIONS
+-
+-	    How to Apply These Terms to Your New Programs
++                     END OF TERMS AND CONDITIONS
++
++            How to Apply These Terms to Your New Programs
+ 
+   If you develop a new program, and you want it to be of the greatest
+ possible use to the public, the best way to achieve this is to make it
+@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
+ the "copyright" line and a pointer to where the full notice is found.
+ 
+     <one line to give the program's name and a brief idea of what it does.>
+-    Copyright (C) 19yy  <name of author>
++    Copyright (C) <year>  <name of author>
+ 
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+@@ -303,16 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+ 
+-    You should have received a copy of the GNU General Public License
+-    along with this program; if not, write to the Free Software
+-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++    You should have received a copy of the GNU General Public License along
++    with this program; if not, write to the Free Software Foundation, Inc.,
++    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ Also add information on how to contact you by electronic and paper mail.
+ 
+ If the program is interactive, make it output a short notice like this
+ when it starts in an interactive mode:
+ 
+-    Gnomovision version 69, Copyright (C) 19yy name of author
++    Gnomovision version 69, Copyright (C) year name of author
+     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+     This is free software, and you are welcome to redistribute it
+     under certain conditions; type `show c' for details.
+@@ -335,5 +335,5 @@ necessary.  Here is a sample; alter the names:
+ This General Public License does not permit incorporating your program into
+ proprietary programs.  If your program is a subroutine library, you may
+ consider it more useful to permit linking proprietary applications with the
+-library.  If this is what you want to do, use the GNU Library General
++library.  If this is what you want to do, use the GNU Lesser General
+ Public License instead of this License.
+diff --git a/ChangeLog b/ChangeLog
+index bc802f6..e9be2e4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -3370,7 +3370,7 @@
+ 2008-08-04  James Antill <james@and.org>
+ 
+ 	* yum-builddep.py: Allow yum-builddep to use "extras"
+-	(installed/not-available pacakges
++	(installed/not-available packages
+ 
+ 2008-08-04  James Antill <james@and.org>
+ 
+diff --git a/debuginfo-install.py b/debuginfo-install.py
+index 177c6c3..0f026f1 100755
+--- a/debuginfo-install.py
++++ b/debuginfo-install.py
+@@ -7,11 +7,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # Copyright 2007 Seth Vidal
+ 
+ import sys
+@@ -52,7 +52,12 @@ class DebugInfoInstall(YumUtilBase):
+                         action="store_true",
+                         help="Turn off automatic installation/update of the yum debuginfo plugin")
+ 
+-        self.main()
++        self.done = set()
++        try:
++            self.main()
++        except yum.Errors.YumBaseError, e:
++            print e
++            sys.exit(1)
+ 
+     def doUtilConfigSetup(self, *args, **kwargs):
+         """ We override this to get our extra option out. """
+@@ -117,6 +122,9 @@ class DebugInfoInstall(YumUtilBase):
+         sys.exit(self.doUtilTransaction())
+ 
+     def di_try_install(self, po):
++        if po in self.done:
++            return
++        self.done.add(po)
+         if po.name.endswith('-debuginfo'): # Wildcard matches produce this
+             return
+         di_name = '%s-debuginfo' % po.name
+@@ -156,6 +164,10 @@ class DebugInfoInstall(YumUtilBase):
+                                 self.di_try_install(deppo)
+                             except yum.Errors.InstallError, e:
+                                 self.logger.critical('Could not find debuginfo pkg for dependency package %s' % deppo)
++
++        for pkgname in u:
++            self.logger.critical('Could not find a package for: %s' % pkgname)
++
+         #  This is kinda hacky, accessing the option from the plugins code
+         # but I'm not sure of a better way of doing it
+         if not self.no_debuginfo_plugin and self.tsInfo:
+diff --git a/docs/Makefile b/docs/Makefile
+index d01c1e4..acb8559 100644
+--- a/docs/Makefile
++++ b/docs/Makefile
+@@ -1,7 +1,9 @@
+ DOCS = repoquery package-cleanup repo-rss yumdownloader yum-builddep yum-changelog reposync \
+        yum-list-data yum-filter-data yum-verify yum-utils yum-aliases yum-debug-dump yum-versionlock \
+        yum-groups-manager debuginfo-install repodiff yum-fs-snapshot \
+-       show-installed show-changed-rco
++       show-installed show-changed-rco yum-debug-restore \
++       find-repos-of-install needs-restarting repo-graph repoclosure \
++       repomanage repotrack verifytree yum-config-manager
+ DOCS5 = yum-changelog.conf yum-versionlock.conf yum-fs-snapshot.conf
+ DOCS8 = yum-security yum-complete-transaction yumdb
+ 
+diff --git a/docs/debuginfo-install.1 b/docs/debuginfo-install.1
+index a47e28a..a829869 100644
+--- a/docs/debuginfo-install.1
++++ b/docs/debuginfo-install.1
+@@ -1,7 +1,7 @@
+ .\" debuginfo-install
+ .TH "debuginfo-install" "1" "21 October 2008" "James Antill" ""
+ .SH "NAME"
+-debuginfo-install
++debuginfo-install \- install debuginfo packages and their dependencies
+ .SH "SYNOPSIS"
+ \fBdebuginfo-install\fP package
+ .SH "DESCRIPTION"
+diff --git a/docs/find-repos-of-install.1 b/docs/find-repos-of-install.1
+new file mode 100644
+index 0000000..77be909
+--- /dev/null
++++ b/docs/find-repos-of-install.1
+@@ -0,0 +1,51 @@
++.\" find-repos-of-install
++.TH "find-repos-of-install" "1" "13 January 2013" "" ""
++.SH "NAME"
++find-repos-of-install \- report which Yum repository a package was installed from
++.SH "SYNOPSIS"
++\fBfind-repos-of-install\fP [options] package1 [package2...]
++.SH "DESCRIPTION"
++.PP
++\fBfind-repos-of-install\fP is a program which reports the Yum repository that
++a specified package was installed from.
++.PP
++.SH "OPTIONS"
++.IP "\fB\-\-version\fP"
++Report program version and exit.
++.IP "\fB\-h, \-\-help\fP"
++Display a help message, and then quit.
++.IP "\fB\-\-repoid=REPOID\fP"
++Specify repo ids to query, can be specified multiple times (default is
++all enabled).
++.IP "\fB\-\-enablerepo=ENABLEREPOS\fP"
++In addition to the default set, query the given additional repository, even if
++it is disabled in YUM configuration.  Can be used multiple times.
++.IP "\fB\-\-disablerepo=DISABLEREPOS\fP"
++Do not query the given repository, even if it is enabled in YUM
++configuration.  Can be used multiple times.
++.IP "\fB\-\-repofrompath=REPOID,PATH/URL\fP"
++Specify a path or url to a repository (same path as in a baseurl) to add to
++the repositories for this query. This option can be used multiple times. If
++you want to view only the pkgs from this repository combine this with
++\-\-repoid. The repoid for the repository is specified by REPOID.
++.IP "\fB\-C, \-\-cache\fP"
++Tells repoquery to run entirely from YUM cache - does not download any metadata
++or update the cache. Queries in this mode can fail or give partial/incorrect
++results if the cache isn't fully populated beforehand with eg "yum makecache".
++.IP "\fB\-\-tempcache\fP"
++Use a temp dir for storing/accessing yum-cache.
++.IP "\fB\-\-sync2yumdb\fP"
++Sync anything that is found to the yumdb, if available.
++
++.PP
++.SH "SEE ALSO"
++.nf
++.I yum.conf (5)
++http://yum.baseurl.org/
++.fi
++
++.PP
++.SH AUTHORS
++.nf
++See the Authors file included with this program.
++.fi
+diff --git a/docs/needs-restarting.1 b/docs/needs-restarting.1
+new file mode 100644
+index 0000000..74b1904
+--- /dev/null
++++ b/docs/needs-restarting.1
+@@ -0,0 +1,29 @@
++.\" needs-restarting
++.TH "needs-restarting" "1" "13 January 2013" "" ""
++.SH "NAME"
++needs-restarting \- report running processes that have been updated
++.SH "SYNOPSIS"
++\fBneeds-restarting\fP [options]
++.SH "DESCRIPTION"
++.PP
++\fBneeds-restarting\fP is a program that reports a list of process ids that
++started running before they or some component that they use were updated.
++.PP
++.SH "OPTIONS"
++.IP "\fB\-h, \-\-help\fP"
++Display a help message, and then quit.
++.IP "\fB\-u, \-\-useronly\fP"
++Show processes for my userid only.
++
++.PP
++.SH "SEE ALSO"
++.nf
++.I yum.conf (5)
++http://yum.baseurl.org/
++.fi
++
++.PP
++.SH "AUTHORS"
++.nf
++See the Authors file included with this program.
++.fi
+diff --git a/docs/package-cleanup.1 b/docs/package-cleanup.1
+index 867cf4d..61959ac 100644
+--- a/docs/package-cleanup.1
++++ b/docs/package-cleanup.1
+@@ -1,7 +1,7 @@
+ .\" package-cleanup 
+ .TH "package-cleanup" "1" "03 November 2005" "Gijs Hollestelle" ""
+ .SH "NAME"
+-package-cleanup
++package-cleanup \- clean up locally installed, duplicate, or orphaned packages
+ .SH "SYNOPSIS"
+ \fBpackage-cleanup\fP [options] <item ...>
+ .SH "DESCRIPTION"
+@@ -14,7 +14,7 @@ Use alternative config file (default is /etc/yum.conf).
+ .IP "\fB\-h, \-\-help\fP"
+ Help; display a help message and then quit\&.
+ .IP "\fB\-q, \-\-quiet\fP" 
+-Print out nothing unecessary.
++Print out nothing unnecessary.
+ .IP "\fB\-v, \-\-version\fP" 
+ Report program version and exit.
+ .IP "\fB\-y\fP" 
+@@ -36,6 +36,8 @@ Scan for duplicates in the local RPM database.
+ .IP "\fB\-\-cleandupes\fP"
+ Scan for duplicates in the local RPM database and clean out the
+ older versions.
++.IP "\fB\-\-count <COUNT>\fP"
++Number of duplicate/kernel packages to keep on the system (default 2)
+ .PP 
+ .SH "LEAVES OPTIONS" 
+ .IP "\fB\-\-all\fP"
+@@ -49,21 +51,19 @@ When listing leaf nodes do not list development packages.
+ When listing leaf nodes do not list packages with files in bin directories.
+ .PP 
+ .SH "OLDKERNELS OPTIONS" 
+-.IP "\fB\-\-count <COUNT>\fP"
+-Number of kernel packages to keep on the system (default 2)
+ .IP "\fB\-\-keepdevel\fP"
+ Do not remove kernel-devel packages when removing kernels
+ 
+ .SH "EXAMPLES"
+ .IP "List all dependency problems:"
+-\fBpackage-cleanup --problems\fP
++\fBpackage-cleanup \-\-problems\fP
+ .IP "List all packages that are not in any Yum repository:"
+-\fBpackage-cleanup --orphans\fP 
++\fBpackage-cleanup \-\-orphans\fP
+ .IP "Remove old kernels keeping 3 and leaving old kernel-devel packages installed:"
+-\fBpackage-cleanup --oldkernels --count=3 --keepdevel\fP
++\fBpackage-cleanup \-\-oldkernels \-\-count=3 \-\-keepdevel\fP
+ .PP 
+ .IP "List all leaf packages with no files in a bin directory whose name begins with either 'perl' or 'python':"
+-\fBpackage-cleanup --leaves --exclude-bin --leaf-regex="^(perl)|(python)"\fP
++\fBpackage-cleanup \-\-leaves \-\-exclude\-bin \-\-leaf\-regex="^(perl)|(python)"\fP
+ .PP
+ .SH "FILES"
+ As package-cleanup uses YUM libraries for retrieving all the information, it
+diff --git a/docs/repo-graph.1 b/docs/repo-graph.1
+new file mode 100644
+index 0000000..9bdbb20
+--- /dev/null
++++ b/docs/repo-graph.1
+@@ -0,0 +1,32 @@
++.\" repo-graph
++.TH "repo-graph" "1" "13 January 2013" "" ""
++.SH "NAME"
++repo-graph \- output a full package dependency graph in dot format
++.SH "SYNOPSIS"
++\fBrepo-graph\fP [options]
++.SH "DESCRIPTION"
++.PP
++\fBrepo-graph\fP is a program that generates a full package dependency list
++from a yum repository and outputs it in dot format.
++.PP
++.SH "OPTIONS"
++.IP "\fB\-h, \-\-help\fP"
++Display a help message, and then quit.
++.IP "\fB\-\-repoid=REPOID\fP"
++Specify repo ids to query, can be specified multiple times (default is
++all enabled).
++.IP "\fB\-c CONFIG\fP"
++Config file to use (defaults to /etc/yum.conf).
++
++.PP
++.SH "SEE ALSO"
++.nf
++.I yum.conf (5)
++http://yum.baseurl.org/
++.fi
++
++.PP
++.SH "AUTHORS"
++.nf
++See the Authors file included with this program.
++.fi
+diff --git a/docs/repo-rss.1 b/docs/repo-rss.1
+index 90788b8..62e00cc 100644
+--- a/docs/repo-rss.1
++++ b/docs/repo-rss.1
+@@ -1,7 +1,7 @@
+ .\" repo-rss
+ .TH "repo-rss" "1" "2005" "Seth Vidal" ""
+ .SH "NAME"
+-repo-rss
++repo-rss \- generates an RSS feed from one or more Yum repositories
+ .SH "SYNOPSIS"
+ \fBrepo-rss\fP [options] repoid1 [repoid2...]
+ .SH "DESCRIPTION"
+@@ -28,7 +28,7 @@ default for non-root users.
+ 
+ .SH "EXAMPLES"
+ .IP "Generate an RSS for the updates-released repository and save it as updates-release.xml:"
+-\fBrepo-rss -f updates-released.xml updates-released\fP
++\fBrepo-rss \-f updates-released.xml updates-released\fP
+ .PP 
+ .SH "FILES"
+ As repo-rss uses YUM libraries for retrieving all the information, it
+diff --git a/docs/repoclosure.1 b/docs/repoclosure.1
+new file mode 100644
+index 0000000..e0f7091
+--- /dev/null
++++ b/docs/repoclosure.1
+@@ -0,0 +1,57 @@
++.\" repoclosure
++.TH "repoclosure" "1" "13 January 2013" "" ""
++.SH "NAME"
++repoclosure \- display a list of unresolved dependencies for a yum repository
++.SH "SYNOPSIS"
++\fBrepoclosure\fP [options]
++.SH "DESCRIPTION"
++.PP
++\fBrepoclosure\fP is a program that reads package metadata from one or more yum
++repositories, checks all dependencies, and displays a list of packages with
++unresolved dependencies.
++.PP
++.SH "OPTIONS"
++.IP "\fB\-h, \-\-help\fP"
++Display a help message, and then quit.
++.IP "\fB\-c CONFIG, \-\-config=CONFIG\fP"
++Config file to use (defaults to /etc/yum.conf).
++.IP "\fB\-a ARCH, \-\-arch=ARCH\fP"
++Check packages of the given archs, can be specified multiple times (default:
++current arch).
++.IP "\fB\-\-basearch=BASEARCH\fP"
++Set the basearch for yum to run as.
++.IP "\fB\-b, \-\-builddeps\fP"
++Check build dependencies only (needs source repos enabled).
++.IP "\fB\-l LOOKASIDE, \-\-lookaside=LOOKASIDE\fP"
++Specify a lookaside repo id to query, can be specified multiple times.
++.IP "\fB\-r REPOID, \-\-repoid=REPOID\fP"
++Specify repo ids to query, can be specified multiple times (default is
++all enabled).
++.IP "\fB\-t, \-\-tempcache\fP"
++Use a temp dir for storing/accessing yum-cache.
++.IP "\fB\-q, \-\-quiet\fP"
++Run quietly: no warnings printed to stderr.
++.IP "\fB\-n, \-\-newest\fP"
++Check only the newest packages in the repos.
++.IP "\fB\-\-repofrompath=REPOID,PATH/URL\fP"
++Specify a path or url to a repository (same path as in a baseurl) to add to
++the repositories for this query. This option can be used multiple times. If
++you want to view only the pkgs from this repository combine this with
++\-\-repoid. The repoid for the repository is specified by REPOID.
++.IP "\fB\-p PKG, \-\-pkg=PKG\fP"
++Check closure for this package only
++.IP "\fB\-g GROUP, \-\-group=GROUP\fP"
++Check closure for packages in this group only
++
++.PP
++.SH "SEE ALSO"
++.nf
++.I yum.conf (5)
++http://yum.baseurl.org/
++.fi
++
++.PP
++.SH "AUTHORS"
++.nf
++See the Authors file included with this program.
++.fi
+diff --git a/docs/repodiff.1 b/docs/repodiff.1
+index c421c5d..75a8860 100644
+--- a/docs/repodiff.1
++++ b/docs/repodiff.1
+@@ -1,37 +1,45 @@
+ .\" repodiff
+ .TH "repodiff" "1" "21 October 2008" "James Antill" ""
+ .SH "NAME"
+-repodiff
++repodiff \- list differences between two or more Yum repositories
+ .SH "SYNOPSIS"
+-\fBrepodiff\fP --old=old_repo_baseurl --new=new_repo_baseurl
++\fBrepodiff\fP \-\-old=old_repo_baseurl \-\-new=new_repo_baseurl
+ .SH "DESCRIPTION"
+ .PP 
+ \fBrepodiff\fP is a program which will list differences between two sets of 
+ repositories.  \fBNote\fP that by default only source packages are compared.
+ .PP 
+ .SH "GENERAL OPTIONS"
+-.IP "\fB\-\-old, -o\fP"
+-Add a repo. as an old repo.
+-.IP "\fB\-\-new, -n\fP"
+-Add a repo. as an new repo.
+-.IP "\fB\-\-archlist, -a\fP"
++.IP "\fB\-\-old, \-o\fP"
++Add a repo. as an old repo. Note that if you prefix the url with "mirror:" then
++the following url is treated as a mirror and not a baseurl.
++.IP "\fB\-\-new, \-n\fP"
++Add a repo. as an new repo. Note that if you prefix the url with "mirror:" then
++the following url is treated as a mirror and not a baseurl.
++.IP "\fB\-\-archlist, \-a\fP"
+ Add architectures to change the default from just comparing source packages.
+ Note that if you want the same as a native
+ "x86_64" architecture machine you just need to pass "x86_64" (this is different
+ from earlier versions where you needed to specify
+ "x86_64,athlon,i686,i586,i486,i386,noarch" and you still got "src").
+-.IP "\fB\-\-size, -s\fP"
+-Ouput additional data about the size of the changes.
+-.IP "\fB\-\-compare-arch\fP"
++.IP "\fB\-\-size, \-s\fP"
++Output additional data about the size of the changes.
++.IP "\fB\-\-compare\-arch\fP"
+ Normally packages are just compared based on their name, this flag makes the
+ comparison also use the arch. So foo.i386 and foo.x86_64 are different.
++.IP "\fB\-\-simple\fP"
++Output a simple one line message for modified packages.
++.IP "\fB\-\-downgrade\fP"
++Split the data for modified packages between upgraded and downgraded packages.
+ .SH "EXAMPLES"
+ .IP "Compare source pkgs in two local repos:"
+-\fBrepodiff --old=/tmp/repo-old --new=/tmp/repo-new\fP
++\fBrepodiff \-\-old=/tmp/repo-old \-\-new=/tmp/repo-new\fP
+ .IP "Compare x86_64 compat. binary pkgs in two remote repos, and two local one:"
+-\fBrepodiff -a x86_64 --old=http://example.com/repo1-old --old=/tmp/repo-old --new=http://example.com/repo1-new --new=/tmp/repo-new\fP
++\fBrepodiff \-a x86_64 \-\-old=http://example.com/repo1-old \-\-old=/tmp/repo-old \-\-new=http://example.com/repo1-new \-\-new=/tmp/repo-new\fP
+ .IP "Compare x86_64 compat. binary pkgs, but also compare arch:"
+-\fBrepodiff -a x86_64 --compare-arch --old=http://example.com/repo1-old --old=/tmp/repo-old --new=http://example.com/repo1-new --new=/tmp/repo-new\fP
++\fBrepodiff \-a x86_64 \-\-compare\-arch \-\-old=http://example.com/repo1-old \-\-old=/tmp/repo-old \-\-new=http://example.com/repo1-new \-\-new=/tmp/repo-new\fP
++.IP "Compare two releases of Fedora (15 => 16):"
++\fBrepodiff \-\-old='mirror:https://mirrors.fedoraproject.org/metalink?repo=fedora-source-15&arch=i386' \-\-new='mirror:https://mirrors.fedoraproject.org/metalink?repo=fedora-source-16&arch=i386' \-\-size \-\-simple \-\-downgrade\fP
+ .PP 
+ 
+ .SH "SEE ALSO"
+diff --git a/docs/repomanage.1 b/docs/repomanage.1
+new file mode 100644
+index 0000000..4d336a5
+--- /dev/null
++++ b/docs/repomanage.1
+@@ -0,0 +1,38 @@
++.\" repomanage
++.TH "repomanage" "1" "13 January 2013" "" ""
++.SH "NAME"
++repomanage \- list the newest or oldest RPM packages in a directory
++.SH "SYNOPSIS"
++\fBrepomanage\fP [options] directory
++.SH "DESCRIPTION"
++.PP
++\fBrepomanage\fP is a program to manage a directory of RPM packages. It
++displays a list of the newest or oldest packages in a directory for easy
++piping to xargs or similar programs.
++.PP
++.SH "OPTIONS"
++.IP "\fB\-h, \-\-help\fP"
++Display a help message, and then quit.
++.IP "\fB\-o, \-\-old\fP"
++Print the oldest packages.
++.IP "\fB\-n, \-\-new\fP"
++Print the newest packages.
++.IP "\fB\-s, \-\-space\fP"
++Space-separated instead of newline-separated output.
++.IP "\fB\-k KEEP, \-\-keep=KEEP\fP"
++Newest N packages to keep - defaults to 1.
++.IP "\fB\-c, \-\-nocheck\fP"
++Do not check package payload signatures/digests.
++
++.PP
++.SH "SEE ALSO"
++.nf
++.I yum.conf (5)
++http://yum.baseurl.org/
++.fi
++
++.PP
++.SH "AUTHORS"
++.nf
++See the Authors file included with this program.
++.fi
+diff --git a/docs/repoquery.1 b/docs/repoquery.1
+index f5a8c5d..30fda8a 100644
+--- a/docs/repoquery.1
++++ b/docs/repoquery.1
+@@ -1,11 +1,11 @@
+ .\" repoquery 
+ .TH "repoquery" "1" "17 October 2005" "Panu Matilainen" ""
+ .SH "NAME"
+-repoquery
++repoquery \- query information from Yum repositories
+ .SH "SYNOPSIS"
+ \fBrepoquery\fP [options] <item ...>
+ .br
+-\fBrepoquery\fP -a [options] 
++\fBrepoquery\fP \-a [options]
+ .SH "DESCRIPTION"
+ .PP 
+ \fBrepoquery\fP is a program for querying information from YUM repositories
+@@ -18,7 +18,7 @@ List valid queryformat tags and exit..
+ Report program version and exit.
+ .IP "\fB\-\-repoid=<repo>\fP"
+ Specify which repository to query. Using this option disables all repositories
+-not explicitly enabled with --repoid option (can be used multiple times). By
++not explicitly enabled with \-\-repoid option (can be used multiple times). By
+ default repoquery uses whatever repositories are enabled in YUM configuration.
+ .IP "\fB\-\-enablerepo=<repo>\fP"
+ In addition to the default set, query the given additional repository, even if
+@@ -30,7 +30,7 @@ configuration.  Can be used multiple times.
+ Specify a path or url to a repository (same path as in a baseurl) to add to
+ the repositories for this query. This option can be used multiple times. If
+ you want to view only the pkgs from this repository combine this with
+---repoid. The repoid for the repository is specified by <repoid>.
++\-\-repoid. The repoid for the repository is specified by <repoid>.
+ .IP "\fB\-\-plugins\fP"
+ Enable YUM plugin support.
+ .IP "\fB\-q, \-\-query\fP"
+@@ -57,6 +57,13 @@ the releasever information from outside the installroot.
+ Note that with the default upstream cachedir, of /var/cache/yum, using this
+ option will corrupt your cache (and you can use $releasever in your cachedir
+ configuration to stop this).
++.IP "\fB\-\-installroot=root\fP"
++Specifies an alternative installroot, relative to which all packages will be
++installed. Think of this like doing "chroot <root> yum" except using
++\-\-installroot allows yum to work before the chroot is created.
++Note: You may also want to use the option \-\-releasever=/ when creating the
++installroot as otherwise the $releasever value is taken from the rpmdb within
++the installroot (and thus. will be empty, before creation).
+ .IP "\fB\-\-setopt=option=value\fP"
+ Set any config option in yum config or repo files. For options in the global 
+ config just use: \-\-setopt=option=value for repo options use: \-\-setopt=repoid.option=value
+@@ -64,13 +71,13 @@ config just use: \-\-setopt=option=value for repo options use: \-\-setopt=repoid
+ .PP 
+ .SH "PACKAGE QUERY OPTIONS" 
+ .IP "\fB\-i, \-\-info\fP"
+-Show general information about package similarly to "rpm -qi"
++Show general information about package similarly to "rpm \-qi"
+ .IP "\fB\-l, \-\-list\fP"
+ List files in package.
+ .IP "\fB\-R, \-\-requires\fP"
+ List package dependencies.
+ .IP "\fB\-\-resolve\fP"
+-When used with --requires, resolve capabilities to originating packages.
++When used with \-\-requires, resolve capabilities to originating packages.
+ .IP "\fB\-\-provides\fP"
+ List capabilities package provides.
+ .IP "\fB\-\-obsoletes\fP"
+@@ -81,7 +88,7 @@ List capabilities conflicting with package.
+ List package changelog.
+ .IP "\fB\-\-location\fP"
+ Show a location where the package could be downloaded from.
+-For example: \fBwget `repoquery --location yum`\fP
++For example: \fBwget `repoquery \-\-location yum`\fP
+ .IP "\fB\-s, \-\-source\fP"
+ Show package source RPM name. 
+ .IP "\fB\-\-srpm\fP"
+@@ -95,16 +102,16 @@ Use name-epoch:version-release.architecture output format (default)
+ .IP "\fB\-\-envra\fP"
+ Use epoch:name-version-release.architecture output format 
+ (easier to parse than nevra)
+-.IP "\fB\--qf=FORMAT, \-\-queryformat=FORMAT\fP"
++.IP "\fB\-\-qf=FORMAT, \-\-queryformat=FORMAT\fP"
+ Specify custom output format for queries. You can add ":date", ":day" and
+ ":isodate" to all the tags that are a time, and you can add ":k", ":m", ":g",
+ ":t" and ":h" to sizes. You can also specify field width as in
+ sprintf (Eg. %-20{name})
+ .IP "\fB\-\-output [text|ascii-tree|dot-tree]\fP"
+-Output format which can be used with --requires/--whatrequires/--obsoletes/--conflicts.
++Output format which can be used with \-\-requires/\-\-whatrequires/\-\-obsoletes/\-\-conflicts.
+ Default output is 'text'.
+ .IP "\fB\-\-level [all|any int]\fP"
+-In combination with --output ascii-tree|dot-tree this option specifies the
++In combination with \-\-output ascii-tree|dot-tree this option specifies the
+ number of level to print on the tree. Default level is 'all'.
+ .PP 
+ 
+@@ -112,6 +119,8 @@ number of level to print on the tree. Default level is 'all'.
+ .IP "\fB\-a, \-\-all\fP"
+ Query all available packages (for rpmquery compatibility / shorthand for 
+ repoquery '*')
++.IP "\fB\--show-duplicates\fP"
++Query all versions of packages.
+ .IP "\fB\-f, \-\-file FILE\fP"
+ Query package owning FILE.
+ .IP "\fB\-\-whatobsoletes CAPABILITY\fP"
+@@ -123,14 +132,15 @@ Query all packages that provide CAPABILITY.
+ .IP "\fB\-\-whatrequires CAPABILITY\fP"
+ Query all packages that require CAPABILITY.
+ .IP "\fB\-\-alldeps\fP"
+-When used with --whatrequires, look for non-explicit dependencies in
++When used with \-\-whatrequires, look for non-explicit dependencies in
+ addition to explicit ones (e.g. files and Provides in addition to
+ package names).  This is the default.
+ .IP "\fB\-\-exactdeps\fP"
+-When used with --whatrequires, search for dependencies only exactly as given.
+-This is effectively the opposite of --alldeps.
++When used with \-\-whatrequires, search for dependencies only exactly as given.
++This is effectively the opposite of \-\-alldeps.
+ .IP "\fB\-\-recursive\fP"
+-When used with --whatrequires, query packages recursively.
++When used with \-\-whatrequires, and \-\-requires \-\-resolve, query packages
++recursively.
+ .IP "\fB\-\-archlist=ARCH1[,ARCH2...]\fP"
+ Limit the query to packages of given architecture(s). Valid values are all
+ architectures known to rpm/yum such as 'i386' and 'src' for
+@@ -166,19 +176,19 @@ Query groups instead of packages.
+ 
+ .SH "EXAMPLES"
+ .IP "List all packages whose name contains 'perl':"
+-\fBrepoquery '*perl*'\fP
++\fBrepoquery \(aq*perl*\(aq\fP
+ .IP "List all packages depending on openssl:"
+-\fBrepoquery --whatrequires openssl\fP 
++\fBrepoquery \-\-whatrequires openssl\fP
+ .IP "List all package names and the repository they come from, nicely formatted:"
+-\fBrepoquery -a --qf "%-20{repoid} %{name}"\fP
++\fBrepoquery \-a \-\-qf "%-20{repoid} %{name}"\fP
+ .IP "List name and summary of all available updates (if any), nicely formatted:"
+-\fBrepoquery -a --pkgnarrow=updates --qf "%{name}:\\n%{summary}\\n"\fP
++\fBrepoquery \-a \-\-pkgnarrow=updates \-\-qf "%{name}:\\n%{summary}\\n"\fP
+ .IP "List optional packages in base group:"
+-\fBrepoquery -g --grouppkgs=optional -l base\fP
++\fBrepoquery \-g \-\-grouppkgs=optional \-l base\fP
+ .IP "List build requirements from 'anaconda' source rpm:"
+-\fBrepoquery --requires anaconda.src\fP
++\fBrepoquery \-\-requires anaconda.src\fP
+ .IP "List packages which BuildRequire gail-devel"
+-\fBrepoquery --archlist=src --whatrequires gail-devel\fP
++\fBrepoquery \-\-archlist=src \-\-whatrequires gail-devel\fP
+   NB: This command will only work if you have repositories enabled which include srpms.
+ 
+ .\"TODO: Add more examples...
+@@ -204,7 +214,7 @@ of the following:
+ .br
+ \fBepoch:name-ver-rel.arch\fP
+ .IP
+-For example: \fBrepoquery -l kernel-2.4.1-10.i686\fP
++For example: \fBrepoquery \-l kernel-2.4.1-10.i686\fP
+ .br
+ Additionally wildcards (shell-style globs) can be used.
+ 
+diff --git a/docs/reposync.1 b/docs/reposync.1
+index c1bc818..29043fb 100644
+--- a/docs/reposync.1
++++ b/docs/reposync.1
+@@ -1,7 +1,7 @@
+ .\" reposync
+ .TH "reposync" "1" "27 April 2007" "" ""
+ .SH "NAME"
+-reposync - synchronize yum repositories to a local directory
++reposync \- synchronize yum repositories to a local directory
+ .SH "SYNOPSIS"
+ \fBreposync\fP [options]
+ .SH "DESCRIPTION"
+@@ -14,7 +14,7 @@ Display a help message, and then quit.
+ Config file to use (defaults to /etc/yum.conf).
+ .IP "\fB\-a ARCH, \-\-arch=ARCH\fP"
+ Act as if running the specified arch (default: current arch, note: does
+-not override $releasever).
++not override $releasever. x86_64 is a superset for i*86.).
+ .IP "\fB\-\-source\fP"
+ Also download .src.rpm files.
+ .IP "\fB\-r REPOID, \-\-repoid=REPOID\fP"
+@@ -26,21 +26,26 @@ Use a temp dir for storing/accessing yum-cache.
+ Path to download packages to: defaults to current directory.
+ .IP "\fB\-g, \-\-gpgcheck\fP"
+ Remove packages that fail GPG signature checking after downloading.
++exit status is '1' if at least one package was removed.
+ .IP "\fB\-u, \-\-urls\fP"
+ Just list urls of what would be downloaded, don't download.
+-.IP "\fB\-n, \-\-newest-only\fP"
++.IP "\fB\-l, \-\-plugins\fP"
++Enable yum plugin support.
++.IP "\fB\-n, \-\-newest\-only\fP"
+ Download only newest packages per-repo.
+ .IP "\fB\-q, \-\-quiet\fP"
+ Output as little information as possible.
+ .SH "EXAMPLES"
+ .IP "Sync all packages from the 'updates' repo to the current directory:"
+-\fB reposync --repoid=updates\fP
++\fB reposync \-\-repoid=updates\fP
+ .IP "Sync only the newest packages from the 'updates' repo to the current directory:"
+-\fB reposync -n --repoid=updates\fP
++\fB reposync \-n \-\-repoid=updates\fP
+ .IP "Sync packages from the 'updates' and 'extras' repos to the current directory:"
+-\fB reposync --repoid=updates --repoid=extras\fP
++\fB reposync \-\-repoid=updates \-\-repoid=extras\fP
+ .IP "Sync all packages from the 'updates' repo to the \fBrepos\fP directory:"
+-\fB reposync -p repos --repoid=updates\fP
++\fB reposync \-p repos \-\-repoid=updates\fP
++.IP "Sync all packages from the 'updates' repo to the \fBrepos\fP directory excluding x86_64 arch. Edit \fI/etc/yum.conf\fR adding option \fBexclude=*.x86_64\fR. Then: 
++\fBreposync \-p repos \-\-repoid=updates\fP
+ .SH "FILES"
+ \fBreposync\fP uses the yum libraries for retrieving information and
+ packages. If no configuration file is specified, the default yum
+diff --git a/docs/repotrack.1 b/docs/repotrack.1
+new file mode 100644
+index 0000000..6b46ed0
+--- /dev/null
++++ b/docs/repotrack.1
+@@ -0,0 +1,44 @@
++.\" repotrack
++.TH "repotrack" "1" "13 January 2013" "" ""
++.SH "NAME"
++repotrack \- track a package and its dependencies and download them
++.SH "SYNOPSIS"
++\fBrepotrack\fP [options] package1 [package2...]
++.SH "DESCRIPTION"
++.PP
++\fBrepotrack\fP is a program for keeping track of a particular package and its
++dependencies. It will download one or more packages and all dependencies.
++.PP
++.SH "OPTIONS"
++.IP "\fB\-h, \-\-help\fP"
++Display a help message, and then quit.
++.IP "\fB\-c CONFIG, \-\-config=CONFIG\fP"
++Config file to use (defaults to /etc/yum.conf).
++.IP "\fB\-a ARCH, \-\-arch=ARCH\fP"
++Act as if running the specified arch (default: current arch).
++.IP "\fB\-r REPOID, \-\-repoid=REPOID\fP"
++Specify repo ids to query, can be specified multiple times (default is
++all enabled).
++.IP "\fB\-t, \-\-tempcache\fP"
++Use a temp dir for storing/accessing yum-cache.
++.IP "\fB\-p DESTDIR, \-\-download_path=DESTDIR\fP"
++Path to download packages to.
++.IP "\fB\-u, \-\-urls\fP"
++Instead of downloading RPMs, list the URLs that would be downloaded.
++.IP "\fB\-n, \-\-newest\fP"
++Toggle downloading only the newest packages (defaults to newest-only).
++.IP "\fB\-q, \-\-quiet\fP"
++Output as little information as possible.
++
++.PP
++.SH "SEE ALSO"
++.nf
++.I yum.conf (5)
++http://yum.baseurl.org/
++.fi
++
++.PP
++.SH "AUTHORS"
++.nf
++See the Authors file included with this program.
++.fi
+diff --git a/docs/show-changed-rco.1 b/docs/show-changed-rco.1
+index 3e3b62c..a88c942 100644
+--- a/docs/show-changed-rco.1
++++ b/docs/show-changed-rco.1
+@@ -1,17 +1,17 @@
+ .\" show-changed-rco
+ .TH "show-installed" "1" "30 March 2011" "James Antill" ""
+ .SH "NAME"
+-show\-changed-\-rco
++show\-changed\-rco \- show changes in an RPM package
+ .SH "SYNOPSIS"
+-\fBshow\-changed-\-rco\fP [options]
++\fBshow\-changed\-rco\fP [options]
+ .SH "DESCRIPTION"
+ .PP
+-\fBshow\-changed-\-rco\fP gives a compact description of the changes to a
++\fBshow\-changed\-rco\fP gives a compact description of the changes to a
+ packages Requires, Conflicts and Obsoletes data from the installed (or old) to
+ a specified rpm file.
+ .SH OPTIONS
+ .TP
+-.IP \-h, \-\-help
++.IP "\fB\-h, \-\-help\fP"
+ show this help message and exit
+ .IP "\fB\-C, \-\-cache\fP" 
+ Tells repoquery to run entirely from YUM cache - does not download any metadata
+@@ -22,7 +22,7 @@ Use alternative config file (default is /etc/yum.conf).
+ 
+ .IP "\fB\-\-repoid=<repo>\fP"
+ Specify which repository to query. Using this option disables all repositories
+-not explicitly enabled with --repoid option (can be used multiple times). By
++not explicitly enabled with \-\-repoid option (can be used multiple times). By
+ default repoquery uses whatever repositories are enabled in YUM configuration.
+ .IP "\fB\-\-enablerepo=<repo>\fP"
+ In addition to the default set, query the given additional repository, even if
+@@ -34,13 +34,13 @@ configuration.  Can be used multiple times.
+ Specify a path or url to a repository (same path as in a baseurl) to add to
+ the repositories for this query. This option can be used multiple times. If
+ you want to view only the pkgs from this repository combine this with
+---repoid. The repoid for the repository is specified by <repoid>.
++\-\-repoid. The repoid for the repository is specified by <repoid>.
+ 
+-.IP "\fB\-\-old-packages=<pkg>\fP"
++.IP "\fB\-\-old\-packages=<pkg>\fP"
+ Explicitly list the valid old packages to match the new packages against.
+-.IP "\fB\-\-ignore-arch\fP"
++.IP "\fB\-\-ignore\-arch\fP"
+ Ignore arch. so you can compare foo-2.i686 to foo-1.x86_64.
+-.IP "\fB\-\-skip-new\fP"
++.IP "\fB\-\-skip\-new\fP"
+ Only give output for packages which we've found an old package for.
+ 
+ .PP 
+diff --git a/docs/show-installed.1 b/docs/show-installed.1
+index 7072b63..0907ea2 100644
+--- a/docs/show-installed.1
++++ b/docs/show-installed.1
+@@ -1,7 +1,7 @@
+ .\" show-installed
+ .TH "show-installed" "1" "21 October 2010" "Florian Festi" ""
+ .SH "NAME"
+-show\-installed
++show\-installed \- show installed RPM packages and descriptions
+ .SH "SYNOPSIS"
+ \fBshow\-installed\fP [options]
+ .SH "DESCRIPTION"
+@@ -16,10 +16,10 @@ show this help message and exit
+ yum, kickstart or human; yum gives the result as a yum command line; kickstart the content of a %packages section; "human" readable is default.
+ .TP
+ .B \-i INPUT, \-\-input=INPUT
+-File to read the package list from instead of using the rpmdb. \- for stdin. The file must contain package names only separated by white space (including newlines). rpm \-qa \-\-qf='%{name}\\n' produces proper output.
++File to read the package list from instead of using the rpmdb. \- for stdin. The file must contain package names only separated by white space (including newlines). rpm \-qa \-\-qf=\(aq%{name}\\n\(aq produces proper output.
+ .TP
+ .B \-o OUTPUT, \-\-output=OUTPUT
+-File to write the result to. Stdout is used if option is omited.
++File to write the result to. Stdout is used if option is omitted.
+ .TP
+ .B \-q, \-\-quiet
+ Do not show warnings.
+diff --git a/docs/verifytree.1 b/docs/verifytree.1
+new file mode 100644
+index 0000000..1389e0f
+--- /dev/null
++++ b/docs/verifytree.1
+@@ -0,0 +1,33 @@
++.\" verifytree
++.TH "verifytree" "1" "13 January 2013" "" ""
++.SH "NAME"
++verifytree \- verify that a local yum repository is consistent
++.SH "SYNOPSIS"
++\fBverifytree\fP [options] directory
++.SH "DESCRIPTION"
++.PP
++\fBverifytree\fP is a program that verifies whether a local yum repository is
++consistent.
++.PP
++.SH "OPTIONS"
++.IP "\fB\-h, \-\-help\fP"
++Display a help message, and then quit.
++.IP "\fB\-a, \-\-checkall\fP"
++Check all packages in the repository.
++.IP "\fB\-t TESTOPIA, \-\-testopia=TESTOPIA\fP"
++Report results to the given testopia run number.
++.IP "\fB\-r, \-\-treeinfo\fP"
++Check the checksums of listed files in a .treeinfo file, if available.
++
++.PP
++.SH "SEE ALSO"
++.nf
++.I yum.conf (5)
++http://yum.baseurl.org/
++.fi
++
++.PP
++.SH "AUTHORS"
++.nf
++See the Authors file included with this program.
++.fi
+diff --git a/docs/yum-aliases.1 b/docs/yum-aliases.1
+index c0f148d..62fae3e 100644
+--- a/docs/yum-aliases.1
++++ b/docs/yum-aliases.1
+@@ -26,9 +26,9 @@ last form creates a new alias.
+ .PP 
+ .SH Explanation of alias to final result conversion
+ .PP 
+-When you type an aliased command, like "yum --disableexcludes UPT lsu" using
++When you type an aliased command, like "yum \-\-disableexcludes UPT lsu" using
+ the default aliases, the yum-aliases plugin first takes the first "command", by
+-skiping over any options, and then looks up the result (in this case "UPT" is converted to "--enablerepo=updates-tesintg"). If there is a match, then it will
++skipping over any options, and then looks up the result (in this case "UPT" is converted to "\-\-enablerepo=updates-testing"). If there is a match, then it will
+ replace the aliased "command" in the argument list and try again (again
+ skipping over any options). By convention, in the default aliases list, alias
+ "commands" that are in all CAPS only add options so you can join together a
+@@ -49,19 +49,19 @@ yum
+ .B alias
+ rm remove
+ .PP
+-To always add the --skip-broken --disableexcludes=all --obsoletes options to
++To always add the \-\-skip\-broken \-\-disableexcludes=all \-\-obsoletes options to
+ the update command (but leaving the upgrade option alone), you could use:
+ .IP
+ yum
+ .B alias
+-update \\update  --skip-broken --disableexcludes=all --obsoletes
++update \\update  \-\-skip\-broken \-\-disableexcludes=all \-\-obsoletes
+ .PP
+ To override the default "up" alias to use the above update command, and never
+ ask for confirmation, you could use:
+ .IP
+ yum
+ .B alias
+-up update -y
++up update \-y
+ .br
+ 
+ 
+diff --git a/docs/yum-builddep.1 b/docs/yum-builddep.1
+index 4e6c1d7..ac7601e 100644
+--- a/docs/yum-builddep.1
++++ b/docs/yum-builddep.1
+@@ -1,7 +1,7 @@
+ .\" yum-builddep
+ .TH "yum-builddep" "1" "17 July 2005 " "Panu Matilainen" ""
+ .SH "NAME"
+-yum-builddep
++yum-builddep \- install missing dependencies for building an RPM package
+ .SH "SYNOPSIS"
+ \fByum-builddep\fP package
+ .SH "DESCRIPTION"
+diff --git a/docs/yum-changelog.1 b/docs/yum-changelog.1
+index 64910dc..c7b5486 100644
+--- a/docs/yum-changelog.1
++++ b/docs/yum-changelog.1
+@@ -14,12 +14,12 @@ is a Yum plugin for viewing package changelogs before/after updating.
+ yum will invoke
+ .BR yum-changelog(1)
+ plugin if the
+-.B --changelog
++.B \-\-changelog
+ option or the
+ .B changelog
+ command is used with yum.
+ .SH OPTIONS
+-.IP --changelog
++.IP \-\-changelog
+ Show changelog delta of updated packages
+ .SH COMMANDS
+ .IP changelog
+@@ -53,7 +53,7 @@ changelog stats. 33 pkgs, 12 source pkgs, 1 changelog
+ .br
+ .br
+ # yum update ktechlab
+-.B --changelog
++.B \-\-changelog
+ .br
+ Loading "changelog" plugin
+ .br
+diff --git a/docs/yum-complete-transaction.8 b/docs/yum-complete-transaction.8
+index 945eee8..965c0b1 100644
+--- a/docs/yum-complete-transaction.8
++++ b/docs/yum-complete-transaction.8
+@@ -1,13 +1,13 @@
+ .\" yum-complete-transaction
+ .TH "yum-complete-transaction" "8" "10 December 2007" "Seth Vidal" ""
+ .SH "NAME"
+-yum-complete-transaction
++yum-complete-transaction \- attempt to complete failed or aborted Yum transactions
+ .SH "SYNOPSIS"
+ \fByum-complete-transaction\fP [options]
+ .SH "GENERAL OPTIONS"
+ .IP "\fB\-h, \-\-help\fP"
+ Help; display a help message and then quit\&.
+-.IP "\fB\-\-cleanup-only\fP" 
++.IP "\fB\-\-cleanup\-only\fP"
+ Only clean up only transaction journal files and exit\&.
+ 
+ .SH "DESCRIPTION"
+diff --git a/docs/yum-config-manager.1 b/docs/yum-config-manager.1
+new file mode 100644
+index 0000000..81b895b
+--- /dev/null
++++ b/docs/yum-config-manager.1
+@@ -0,0 +1,39 @@
++.\" yum-config-manager
++.TH "yum-config-manager" "1" "13 January 2013" "" ""
++.SH "NAME"
++yum-config-manager \- manage yum configuration options and yum repositories
++.SH "SYNOPSIS"
++\fByum-config-manager\fP [options]
++.SH "DESCRIPTION"
++.PP
++\fByum-config-manager\fP is a program that can manage main yum configuration
++options, toggle which repositories are enabled or disabled, and add new
++repositories.
++.PP
++.SH "OPTIONS"
++.IP "\fB\-h, \-\-help\fP"
++Display a help message, and then quit.
++.IP "\fB\-\-save\fP"
++Save the current options (useful with \-\-setopt).
++.IP "\fB\-\-enable\fP"
++Enable the specified repos (automatically saves).
++.IP "\fB\-\-disable\fP"
++Disable the specified repos (automatically saves).
++.IP "\fB\-\-add\-repo=ADDREPO\fP"
++Add (and enable) the repo from the specified file or url.
++.SH "ADDITIONAL OPTIONS"
++Yum-config-manager inherits all other options from yum. See the yum(8)
++man page for more information.
++
++.PP
++.SH "SEE ALSO"
++.nf
++.I yum.conf (5)
++http://yum.baseurl.org/
++.fi
++
++.PP
++.SH "AUTHORS"
++.nf
++See the Authors file included with this program.
++.fi
+diff --git a/docs/yum-debug-dump.1 b/docs/yum-debug-dump.1
+index 0e65a07..3f1e2e5 100644
+--- a/docs/yum-debug-dump.1
++++ b/docs/yum-debug-dump.1
+@@ -1,7 +1,7 @@
+ .\" yum-debug-dump
+ .TH "yum-debug-dump" "1" "28 April 2008" "Seth Vidal" ""
+ .SH "NAME"
+-yum-debug-dump
++yum-debug-dump \- write system RPM configuration to a debug-dump file
+ .SH "SYNOPSIS"
+ \fByum-debug-dump\fP
+ .SH "DESCRIPTION"
+@@ -10,11 +10,15 @@ yum-debug-dump
+ lot of information useful to developers trying to debug a problem.
+ .PP
+ By default it will output a file to the current working directory named
+-yum_debug_dump.txt.gz. This file contains no private information but does
++yum_debug_dump-<hostname>-<time>.txt.gz. This file contains no private
++information but does
+ contain a complete list of all packages you have installed, all packages
+ available in any repository, important configuration and system information.
+ You can view this file using the 'zless' command.
+ .PP 
++You can use the coresponding program \fByum-debug-restore\fP to act on this file
++and restore a set of packages (much like dump/restore).
++.PP 
+ .SH "FILES"
+ As yum-debug-dump uses YUM libraries for retrieving all the information, it
+ relies on YUM configuration for its default values like which repositories
+@@ -29,6 +33,7 @@ to use. Consult YUM documentation for details:
+ .PP 
+ .SH "SEE ALSO"
+ .nf
++.I yum-debug-restore (1)
+ .I yum.conf (5)
+ http://yum.baseurl.org/
+ .fi 
+diff --git a/docs/yum-debug-restore.1 b/docs/yum-debug-restore.1
+new file mode 100644
+index 0000000..c9d388d
+--- /dev/null
++++ b/docs/yum-debug-restore.1
+@@ -0,0 +1,62 @@
++.\" yum-debug-dump
++.TH "yum-debug-restore" "1" "15 December 2011" "James Antill" ""
++.SH "NAME"
++yum-debug-restore \- replay Yum transactions captured in a debug-dump file
++.SH "SYNOPSIS"
++\fByum-debug-restore\fP
++.SH "DESCRIPTION"
++.PP 
++\fByum-debug-restore\fP is a program which takes a gzipped file created by
++\fByum-debug-dump\fP and acts on the information about installed packages
++contained within.
++.PP
++
++.SH "GENERAL OPTIONS"
++.IP "\fB\-\-output\fP"
++Output the commands that would be run to stdout.
++.IP "\fB\-\-shell=<file>\fP"
++Output the commands that would be run to a file.
++.IP "\fB\-\-install\-latest\fP"
++Ask yum to install the latest version of the given packages, instead of the
++version that was installed in the debug-dump file.
++.IP "\fB\-\-ignore\-arch\fP"
++Ignore the architecture of the packages, so you can "restore" an i386 debug-dump
++on an x86_64 machine.
++.IP "\fB\-\-filter\-types=[install,remove,update,downgrade]\fP"
++Only perform the given types of commands, so you can filter to just upgrades
++and installs.
++
++.SH "FILES"
++As yum-debug-restore uses YUM libraries for retrieving all the information, it
++relies on YUM configuration for its default values like which repositories
++to use. Consult YUM documentation for details:
++.PP
++.nf 
++/etc/yum.conf
++/etc/yum/repos.d/
++/var/cache/yum/
++.fi 
++
++.PP 
++.SH "SEE ALSO"
++.nf
++.I yum-debug-dump (1)
++.I yum.conf (5)
++http://yum.baseurl.org/
++.fi 
++
++.PP 
++.SH "AUTHORS"
++.nf 
++See the Authors file included with this program.
++.fi 
++
++.PP 
++.SH "BUGS"
++There are of course no bugs, but should you find any, you should first
++consult the FAQ section on http://yum.baseurl.org/wiki/Faq and if unsuccessful
++in finding a resolution contact the mailing list: yum-devel@lists.baseurl.org.
++To file a bug use http://bugzilla.redhat.com for Fedora/RHEL/Centos
++related bugs and http://yum.baseurl.org/report for all other bugs.
++
++.fi
+diff --git a/docs/yum-filter-data.1 b/docs/yum-filter-data.1
+index 6d7f1e4..75a8236 100644
+--- a/docs/yum-filter-data.1
++++ b/docs/yum-filter-data.1
+@@ -16,52 +16,52 @@ is treated as a match.
+ These are the options added to yum that are available in the "list updates", 
+ "info updates", "check-update" and "update" commands. They are:
+ .PP 
+-.IP "\fB\--filter-vendors\fP"
++.IP "\fB\-\-filter\-vendors\fP"
+ This option includes packages which have a vendor which matches one of the
+ passed vendor wildcard strings, or is unknown. Note that vendors can have
+ spaces in their value, so "," is the only way to specify multiple vendors as one
+ option argument.
+-.IP "\fB\--filter-rpm-groups\fP"
++.IP "\fB\-\-filter\-rpm\-groups\fP"
+ This option includes packages which have a group which matches one of the
+ passed rpm group wildcard strings, or is unknown. Note that rpm groups can have
+ spaces in their value, so "," is the only way to specify multiple rpm groups as
+ one option argument.
+-.IP "\fB\--filter-packagers\fP"
++.IP "\fB\-\-filter\-packagers\fP"
+ This option includes packages which have a packager which matches one of the
+ passed packager wildcard strings, or is unknown. Note that vendors can have
+ spaces in their value, so "," is the only way to specify multiple packagers as
+ one option argument.
+-.IP "\fB\--filter-licenses\fP"
++.IP "\fB\-\-filter\-licenses\fP"
+ This option includes packages which have a license which matches one of the
+ passed license wildcard strings, or is unknown. Note that licenses can have
+ spaces in their value, so "," is the only way to specify multiple licenses as
+ one option argument.
+-.IP "\fB\--filter-arches\fP"
++.IP "\fB\-\-filter\-arches\fP"
+ This option includes packages which have a arch which matches one of the
+ passed arch wildcard strings, or is unknown.
+-.IP "\fB\--filter-committers\fP"
++.IP "\fB\-\-filter\-committers\fP"
+ This option includes packages which have a committer which matches one of the
+ passed committer wildcard strings, or is unknown. Note that committers can have
+ spaces in their value, so "," is the only way to specify multiple committers as
+ one option argument. Also, committer values are so loosely formed that they 
+-could contain commas too, it is recommeneded to not do that but you can work
++could contain commas too, it is recommended to not do that but you can work
+ around it by using "?".
+-.IP "\fB\--filter-buildhosts\fP"
++.IP "\fB\-\-filter\-buildhosts\fP"
+ This option includes packages which have a buildhost which matches one of the
+ passed buildhost wildcard strings, or is unknown.
+-.IP "\fB\--filter-urls\fP"
++.IP "\fB\-\-filter\-urls\fP"
+ This option includes packages which have a url which matches one of the
+ passed url wildcard strings, or is unknown.
+-.IP "\fB\--filter-package-sizes\fP"
++.IP "\fB\-\-filter\-package\-sizes\fP"
+ This option includes packages which have a packagesize which is within one of
+ the passed packagesize ranges, or is unknown.
+-.IP "\fB\--filter-archive-sizes\fP"
++.IP "\fB\-\-filter\-archive\-sizes\fP"
+ This option includes packages which have a archivesize which is within one of
+ the passed archivesize ranges, or is unknown.
+-.IP "\fB\--filter-installed-sizes\fP"
++.IP "\fB\-\-filter\-installed\-sizes\fP"
+ This option includes packages which have a installedsize which is within one of
+ the passed installedsize ranges, or is unknown.
+-.IP "\fB\--filter-groups\fP"
++.IP "\fB\-\-filter\-groups\fP"
+ This option includes packages which are in a yum group which matches one of the
+ passed yum group id strings, or is unknown. Note that yum groups can have
+ spaces in their value, so "," is the only way to specify multiple yum groups as
+@@ -73,27 +73,27 @@ one option argument.
+ .PP
+ To list all updates that are 1 MB or less use:
+ .IP
+-yum --filter-package-sizes=-1m check-update
++yum \-\-filter\-package\-sizes=-1m check-update
+ .PP
+ To apply updates that Dan Walsh has committed use:
+ .IP
+-yum --filter-committers='Dan Walsh *' update
++yum \-\-filter\-committers=\(aqDan Walsh *\(aq update
+ .PP
+ To list updates for a specific group use:
+ .IP
+-yum --filter-rpm-groups='App*/Sys*' list updates
++yum \-\-filter\-rpm\-groups=\(aqApp*/Sys*\(aq list updates
+ .PP
+ To apply updates to a specific set of groups use:
+ .IP
+-yum --filter-rpm-groups='App*/System,Devel*/Lib*,System Environment/Base' update
++yum \-\-filter\-rpm\-groups=\(aqApp*/System,Devel*/Lib*,System Environment/Base\(aq update
+ .PP
+ To list updates for a set of yum groups use:
+ .IP
+-yum --filter-groups='PostgreSQL Database,Web Server' list updates
++yum \-\-filter\-groups=\(aqPostgreSQL Database,Web Server\(aq list updates
+ .PP
+ To apply updates to a specific set of yum groups use:
+ .IP
+-yum --filter-groups='KDE,Core,Printing Support' update
++yum \-\-filter\-groups=\(aqKDE,Core,Printing Support\(aq update
+ 
+ .SH "SEE ALSO"
+ .nf
+@@ -109,7 +109,7 @@ James Antill <james.antill@redhat.com>.
+ 
+ .SH "BUGS"
+ Currently yum can't filter packages in all of the commands, so for instance
+-"yum list 'yum*'" doesn't get the results filtered.
++"yum list \(aqyum*\(aq" doesn't get the results filtered.
+ 
+ Apart from that there are no bugs, but should you find any, you should first
+ consult the FAQ section on http://yum.baseurl.org/wiki/Faq and if unsuccessful
+diff --git a/docs/yum-fs-snapshot.conf.5 b/docs/yum-fs-snapshot.conf.5
+index a4b4f02..68bb2e8 100644
+--- a/docs/yum-fs-snapshot.conf.5
++++ b/docs/yum-fs-snapshot.conf.5
+@@ -20,6 +20,10 @@ utilizes configuration options in the form of
+ .IP exclude
+ This is a space delimited list of the mount points you do not wish to have
+ snapshotted by this plugin.
++.SH OPTION
++.IP create_snapshots_in_post
++This is a boolean value used to control whether snapshots are also created
++after running the yum transaction.
+ .SH OPTION - [lvm] section
+ .IP enabled
+ This is a boolean value used to control whether LVM snapshots will be
+@@ -27,8 +31,9 @@ created for filesystems built on LVM logical volumes.
+ .SH OPTION - [lvm] section
+ .IP lvcreate_size_args
+ This is the space delimited lvcreate argument list that is used to
+-specify the size of the snapshot LV.  Valid lvcreate size options are -l
+-or -L.  If not specified then LVM snapshots will not be created.
++specify the size of the snapshot LV.  Valid lvcreate size options are \-l
++or \-L.  If not specified then LVM snapshots will not be created for
++volumes that are not thinly provisioned.
+ .SH AUTHOR
+ .RS
+ Josef Bacik <josef@toxicpanda.com>
+diff --git a/docs/yum-groups-manager.1 b/docs/yum-groups-manager.1
+index f49bde9..9854884 100644
+--- a/docs/yum-groups-manager.1
++++ b/docs/yum-groups-manager.1
+@@ -1,12 +1,12 @@
+ .\" yum-groups-manager
+ .TH "yum-groups-manager" "1" "23 August 2008" "" ""
+ .SH "NAME"
+-yum-groups-manager - create and edit yum's group metadata
++yum-groups-manager \- create and edit yum's group metadata
+ .SH "SYNOPSIS"
+ \fByum-groups-manager\fP [options] [packages]
+ .SH "DESCRIPTION"
+ \fByum-groups-manager\fP is used to create or edit a group metadata file for a
+-yum repository. This is often much easier than writting/editing the XML by hand.
++yum repository. This is often much easier than writing/editing the XML by hand.
+ The \fByum-groups-manager\fP can load an entire file of groups metadata and
+ either create a new group or edit an existing group and then write all of the
+ groups metadata back out.
+@@ -43,7 +43,7 @@ Change the integer which controls the order groups are presented in, for example
+ in yum grouplist.
+ .IP "\fB\-\-load\fP"
+ Load the groups metadata information from the specified file, before
+-performing any operataions. This option can be specified multiple times.
++performing any operations. This option can be specified multiple times.
+ .IP "\fB\-\-save\fP"
+ Save the result to this file, you can specify the name of a file you are
+ loading from as the data will only be saved when all the operations have been
+@@ -77,11 +77,11 @@ in yum.
+ 
+ .SH "EXAMPLES"
+ .IP "Create a new group metadata file, with a group called yum containing all the packages that start with yum:"
+-\fB yum-groups-manager --name YUM --save groups.xml 'yum*'\fP
++\fB yum-groups-manager \-\-name YUM \-\-save groups.xml \(aqyum*\(aq\fP
+ .IP "After the above command, load the groups.xml data, work with the yum group, make the group not user visible, and remove the yum-skip-broken and yum-priorities packages from it:"
+-\fB yum-groups-manager -n YUM --merge groups.xml --remove yum-skip-broken yum-priorities --not-user-visible\fP
++\fB yum-groups-manager \-n YUM \-\-merge groups.xml \-\-remove yum-skip-broken yum-priorities \-\-not\-user\-visible\fP
+ .IP "After the above commands, add a description and a translated name to the yum group:"
+-\fB yum-groups-manager -n YUM --merge groups.xml --description 'This is a group with most of the yum packages in it' --translated-name 'en:yum packages'\fP
++\fB yum-groups-manager \-n YUM \-\-merge groups.xml \-\-description \(aqThis is a group with most of the yum packages in it\(aq \-\-translated\-name \(aqen:yum packages\(aq\fP
+ .SH "FILES"
+ \fByum-groups-manager\fP uses the yum libraries for retrieving information and
+ packages. If no configuration file is specified, the default yum
+@@ -103,7 +103,7 @@ See the Authors file included with this program.
+ .fi
+ .SH "BUGS"
+ .nf
+-There are a couple of options you can't set, yet. Most notabley you cannot put
++There are a couple of options you can't set, yet. Most notably you cannot put
+ package names into the conditional section (where they are installed with
+ groupinstall only if another package is installed).
+ 
+diff --git a/docs/yum-list-data.1 b/docs/yum-list-data.1
+index d855104..a5477d6 100644
+--- a/docs/yum-list-data.1
++++ b/docs/yum-list-data.1
+@@ -61,7 +61,7 @@ added yum \fIcommand\fPs are:
+ .PP 
+ all of which take the same arguments as the list and info yum commands. The
+ difference between the list and info varieties is that the info versions lists
+-all the packages under each agregation.
++all the packages under each aggregation.
+ .PP
+ .br 
+ .br 
+@@ -118,7 +118,7 @@ more than one group at a time.
+ .IP
+ .PP 
+ It is worth noting that some of the above data can be "unknown", to yum, at
+-which point a seperate aggregation called "-- Unknown --" is listed.
++which point a separate aggregation called "-- Unknown --" is listed.
+ .SH "EXAMPLES"
+ .PP
+ To list all the groups that have an update, along with the number of packages in each group, use:
+@@ -127,7 +127,7 @@ yum list-rpm-groups updates
+ .PP
+ To list all the committers to packages that have yum in their name, use:
+ .IP
+-yum list-committers 'yum*'
++yum list-committers \(aqyum*\(aq
+ .PP
+ To list ranges of the sizes of packages installed or available, use:
+ .IP
+diff --git a/docs/yum-security.8 b/docs/yum-security.8
+index 7e260b0..c7d9c8b 100644
+--- a/docs/yum-security.8
++++ b/docs/yum-security.8
+@@ -6,13 +6,13 @@ yum security plugin
+ \fByum\fP [options] [command] [package ...]
+ .SH "DESCRIPTION"
+ .PP 
+-This plugin extends \fByum\fP to allow lists and updates to be limited using security relevant criteria
++This plugin extends \fByum\fP to allow lists and updates to be limited using security relevant criteria.
+ .PP 
+-added yum \fIcommand\fPs are:
++Added yum \fIcommand\fPs are:
+ .br 
+ .I \fR yum update-minimal
+ .PP 
+-This works like the update command, but if you have the the package foo-1
++This works like the update command, but if you have the package foo-1
+ installed and have foo-2 and foo-3 available with updateinfo.xml then
+ update-minimal will update you to foo-3.
+ .br 
+@@ -22,7 +22,7 @@ update-minimal will update you to foo-3.
+ .br 
+ .I \fR yum updateinfo summary
+ .PP 
+-all of the last three take these \fIsub-command\fPs:
++All of the last three take these \fIsub-command\fPs:
+ .br 
+ .I \fR yum updateinfo * all
+ .br 
+@@ -108,40 +108,40 @@ distribution.
+ .SH "GENERAL OPTIONS"
+ There are four options added to yum that are available in the "list updates", "info updates", "check-update" and "update" commands. They are:
+ .PP 
+-.IP "\fB\--advisory\fP"
+-This option includes packages coresponding to the advisory ID, Eg. FEDORA-2201-123.
+-.IP "\fB\--bz\fP"
++.IP "\fB\-\-advisory\fP"
++This option includes packages corresponding to the advisory ID, Eg. FEDORA-2201-123.
++.IP "\fB\-\-bz\fP"
+ This option includes packages that say they fix a Bugzilla ID, Eg. 123.
+-.IP "\fB\--cve\fP"
++.IP "\fB\-\-cve\fP"
+ This option includes packages that say they fix a CVE - Common Vulnerabilities and Exposures ID (http://cve.mitre.org/about/), Eg. CVE-2201-0123.
+-.IP "\fB\--bugfixes\fP"
++.IP "\fB\-\-bugfixes\fP"
+ This option includes packages that say they fix a bugfix issue.
+-.IP "\fB\--security\fP"
++.IP "\fB\-\-security\fP"
+ This option includes packages that say they fix a security issue.
+ .PP
+ .PP
+ 
+ .SH "EXAMPLES"
+ .PP
+-To list all updates that are security relevant, and get a reutrn code on whether there are security updates use:
++To list all updates that are security relevant, and get a return code on whether there are security updates use:
+ .IP
+-yum --security check-update
++yum \-\-security check-update
+ .PP
+ To upgrade packages that have security errata (upgrades to the latest
+ available package) use:
+ .IP
+-yum --security update
++yum \-\-security update
+ .PP
+ To upgrade packages that have security errata (upgrades to the last
+ security errata package) use:
+ .IP
+-yum --security update-minimal
++yum \-\-security update-minimal
+ .PP
+ To get a list of all BZs that are fixed for packages you have installed use:
+ .IP
+ yum updateinfo list bugzillas
+ .PP
+-To get a list of all security advisoryies, including the ones you have already
++To get a list of all security advisories, including the ones you have already
+ installed use:
+ .IP
+ yum updateinfo list all security
+@@ -152,15 +152,15 @@ yum updateinfo info FEDORA-2707-4567
+ .PP
+ To update packages to the latest version which contain fixes for Bugzillas 123, 456 and 789; and all security updates use:
+ .IP
+-yum --bz 123 --bz 456 --bz 789 --security update
++yum \-\-bz 123 \-\-bz 456 \-\-bz 789 \-\-security update
+ .PP
+ To update to the packages which just update Bugzillas 123, 456 and 789; and all security updates use:
+ .IP
+-yum --bz 123 --bz 456 --bz 789 --security update-minimal
++yum \-\-bz 123 \-\-bz 456 \-\-bz 789 \-\-security update-minimal
+ .PP
+ To get an info list of the latest packages which contain fixes for Bugzilla 123; CVEs CVE-2207-0123 and CVE-2207-3210; and Fedora advisories FEDORA-2707-4567 and FEDORA-2707-7654 use:
+ .IP
+-yum --bz 123 --cve CVE-2207-0123 --cve CVE-2207-3210 --advisory FEDORA-2707-4567 --advisory FEDORA-2707-7654 info updates
++yum \-\-bz 123 \-\-cve CVE-2207-0123 \-\-cve CVE-2207-3210 \-\-advisory FEDORA-2707-4567 \-\-advisory FEDORA-2707-7654 info updates
+ .PP
+ To get a list of packages which are "new".
+ .IP
+@@ -183,8 +183,8 @@ James Antill <james.antill@redhat.com>.
+ .fi
+ 
+ .SH "BUGS"
+-The update-minimal command ignores the --obsoletes flag.
++The update-minimal command ignores the \-\-obsoletes flag.
+ 
+-The update-minimal command can only directly affect things atm., so if you update pkgA minimally but that requires an update to pkgB then pkgB will be updated to the newest version by the depsolver. Also the above will happen even if you've also minimally updated pkgB, if either the direct (minimal) update for pkgB happens after or if the minimal update for pkgB doesn't satisy the requirements of pkgA.
++The update-minimal command can only directly affect things atm., so if you update pkgA minimally but that requires an update to pkgB then pkgB will be updated to the newest version by the depsolver. Also the above will happen even if you've also minimally updated pkgB, if either the direct (minimal) update for pkgB happens after or if the minimal update for pkgB doesn't satisfy the requirements of pkgA.
+ 
+-The main "problem" is that if the data is not correct the plugin cannot work correctly. For instance "--bz 123" will not fix BZ 123 if a package is updated to fix that BZ without referencing that it does so in the updateinfo.xml.
++The main "problem" is that if the data is not correct the plugin cannot work correctly. For instance "\-\-bz 123" will not fix BZ 123 if a package is updated to fix that BZ without referencing that it does so in the updateinfo.xml.
+diff --git a/docs/yum-utils.1 b/docs/yum-utils.1
+index fa830b6..3f858a8 100644
+--- a/docs/yum-utils.1
++++ b/docs/yum-utils.1
+@@ -15,8 +15,9 @@ yum\-utils \- tools for manipulating repositories and extended package managemen
+ \fBrepoquery\fR \- query yum repositories and get additional information on the them
+ \fBreposync\fR \- synchronize a remote yum repository to a local directory using yum to retrieve packages
+ \fBrepotrack\fR \- track packages and its dependencies and downloads them
++\fBshow-changed-rco\fR \- list of changes to a package Requires, Conflicts and Obsoletes data from installed to a specified rpm file
+ \fBshow-installed\fR \- gives a compact description of packages installed and makes use of comps groups in repositories
+-\fBverifytree\fR - verify that a local yum repository is consistent
++\fBverifytree\fR \- verify that a local yum repository is consistent
+ \fByum\-builddep\fR \- installs missing dependencies to build a specified package
+ \fByum\-complete\-transaction\fR \- finds incomplete or aborted yum transactions and attempts to complete them
+ \fByum\-config\-manager\fR \- toggle yum repositories, add new repositories and set main yum configuration options
+@@ -32,6 +33,6 @@ is a collection of tools and programs for managing yum repositories, installing
+ .SH "NOTES"
+ See respective tools for additional help for commands without a manual page
+ .SH "SEE ALSO"
+-debuginfo\-install(1), package\-cleanup(1), repodiff(1), repoquery(1), reposync(1), repo\-rss(1), yumdownloader(1), yum\-builddep(1), yum\-debug\-dump(1), yum\-groups\-manager(1), yumdb(8), yum\-complete\-transaction(8)
++debuginfo\-install(1), package\-cleanup(1), repodiff(1), repoquery(1), reposync(1), repo\-rss(1), show\-changed\-rco(1), show\-installed(1), yumdownloader(1), yum\-builddep(1), yum\-debug\-dump(1), yum\-groups\-manager(1), yumdb(8), yum\-complete\-transaction(8)
+ .SH "AUTHOR"
+ Shawn Starr <shawn.starr@rogers.com>
+diff --git a/docs/yum-verify.1 b/docs/yum-verify.1
+index 706c38e..5246a1c 100644
+--- a/docs/yum-verify.1
++++ b/docs/yum-verify.1
+@@ -6,7 +6,7 @@ yum verify plugin
+ \fByum\fP [options] verify [package ...]
+ .SH "DESCRIPTION"
+ .PP 
+-This plugin extends \fByum\fP with some commands that give verification information on the installed system, much like rpm -V. You can change how the verification is done and which files it applies to.
++This plugin extends \fByum\fP with some commands that give verification information on the installed system, much like rpm \-V. You can change how the verification is done and which files it applies to.
+ .PP 
+ added yum \fIcommand\fPs are:
+ .br 
+@@ -24,12 +24,12 @@ only verify packages that are installed on the system.
+ .br 
+ .PP 
+ .IP "\fBverify\fP"
+-Is the generic verification command, and is intented to give the most useful
++Is the generic verification command, and is intended to give the most useful
+ output. It removes all false matches due to multilib and ignores changes to
+ configuration files by default.
+ .IP
+ .IP "\fBverify-rpm\fP"
+-Is meant to be 100% compatible with rpm -V output, and any differences should be
++Is meant to be 100% compatible with rpm \-V output, and any differences should be
+ considered as bugs.
+ .IP
+ .IP "\fBverify-all\fP"
+@@ -39,29 +39,29 @@ Is used to list all the differences, including some that rpm itself will ignore.
+ These are the options added to yum that are available in the verify commands.
+ They are:
+ .PP 
+-.IP "\fB\--verify-filenames\fP"
++.IP "\fB\-\-verify\-filenames\fP"
+ This option is used to limit the filenames that the packages will perform
+ verification.
+-.IP "\fB\--verify-configuration-files\fP"
++.IP "\fB\-\-verify\-configuration\-files\fP"
+ This option is only useful in the generic verify command, and will
+ enable/disable verification of files that are tagged as configuration files.
+ .SH "EXAMPLES"
+ .PP
+-To do the same as rpm -Va, use:
++To do the same as rpm \-Va, use:
+ .IP
+ yum verify-rpm
+ .PP
+ To verify the packages starting with the name yum, use:
+ .IP
+-yum verify 'yum*'
++yum verify \(aqyum*\(aq
+ .PP
+ To verify the binaries that are in a bin directory, use:
+ .IP
+-yum verify --verify-filenames='*bin/*'
++yum verify \-\-verify\-filenames=\(aq*bin/*\(aq
+ .PP
+ To verify all include files, Eg. for multilib problems, use:
+ .IP
+-yum verify-all --verify-filenames='/usr/include/*'
++yum verify-all \-\-verify\-filenames=\(aq/usr/include/*\(aq
+ 
+ .SH "SEE ALSO"
+ .nf
+@@ -77,7 +77,7 @@ James Antill <james.antill@redhat.com>.
+ 
+ .SH "BUGS"
+ .nf
+-Currently yum-verify does not do verify-script checking or dependancy checking,
++Currently yum-verify does not do verify-script checking or dependency checking,
+ only file checking.
+ 
+ Should you find any other bugs, you should first
+diff --git a/docs/yum-versionlock.1 b/docs/yum-versionlock.1
+index f68665e..f7cd467 100644
+--- a/docs/yum-versionlock.1
++++ b/docs/yum-versionlock.1
+@@ -3,7 +3,7 @@
+ .\"
+ .TH YUM-VERSIONLOCK 1 "28 December 2009" "" "User Manuals"
+ .SH NAME
+-yum-versionlock - Version lock rpm packages
++yum-versionlock \- Version lock rpm packages
+ .SH SYNOPSIS
+ .B yum-versionlock
+ [ package-name [ package-name]] ...
+@@ -67,7 +67,7 @@ Panu Matilainen <pmatilai@laiskiainen.org>
+ .br
+ James Antill <james@and.org>
+ .br
+-Documetation modified by:
++Documentation modified by:
+ .br
+ Gerhardus Geldenhuis <gerhardus.geldenhuis@gmail.com>
+ .SH "SEE ALSO"
+diff --git a/docs/yumdb.8 b/docs/yumdb.8
+index 63a3c6b..600a3a9 100644
+--- a/docs/yumdb.8
++++ b/docs/yumdb.8
+@@ -1,7 +1,7 @@
+ .\" yumdb command
+ .TH "yumdb" "8" "8 April 2010" "James Antill" ""
+ .SH "NAME"
+-yumdb command
++yumdb \- query and alter the Yum database
+ .SH "SYNOPSIS"
+ \fByumdb\fP [command] [packages ...]
+ .SH "DESCRIPTION"
+diff --git a/docs/yumdownloader.1 b/docs/yumdownloader.1
+index a8a3b16..e290268 100644
+--- a/docs/yumdownloader.1
++++ b/docs/yumdownloader.1
+@@ -1,7 +1,7 @@
+ .\" yumdownloader
+ .TH "yumdownloader" "1" "28 November 2005" "Gijs Hollestelle" ""
+ .SH "NAME"
+-yumdownloader
++yumdownloader \- download RPM packages from Yum repositories
+ .SH "SYNOPSIS"
+ \fByumdownloader\fP [options] package1 [package2...]
+ .SH "DESCRIPTION"
+@@ -31,9 +31,9 @@ for more information
+ 
+ .SH "EXAMPLES"
+ .IP "Download the kernel RPM to /var/tmp:"
+-\fByumdownloader --destdir /var/tmp kernel\fP
++\fByumdownloader \-\-destdir /var/tmp kernel\fP
+ .IP "List the URL for the kernel and kernel-smp RPMs:"
+-\fByumdownloader --urls kernel kernel-smp\fP 
++\fByumdownloader \-\-urls kernel kernel-smp\fP
+ .PP 
+ .SH "FILES"
+ As yumdownloader uses YUM libraries for retrieving all the information, it
+diff --git a/find-repos-of-install.py b/find-repos-of-install.py
+index 0578295..aac29ea 100644
+--- a/find-repos-of-install.py
++++ b/find-repos-of-install.py
+@@ -7,11 +7,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # copyright 2008 red hat, inc
+ 
+ import sys
+diff --git a/needs-restarting.py b/needs-restarting.py
+index 6bc883f..a6946b0 100755
+--- a/needs-restarting.py
++++ b/needs-restarting.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # Copyright 2009 Red Hat Inc
+ # written by Seth Vidal
+ 
+@@ -40,6 +40,7 @@
+ import sys
+ import os
+ import yum
++import yum.misc
+ import glob
+ import stat
+ from optparse import OptionParser
+@@ -76,18 +77,18 @@ def get_open_files(pid):
+     files = []
+     smaps = '/proc/%s/smaps' % pid
+     try:
+-        maps = open(smaps, 'r')
++        maps = open(smaps, 'r').readlines()
+     except (IOError, OSError), e:
+         print "Could not open %s" % smaps
+         return files
+ 
+-    for line in maps.readlines():
+-        if line.find('fd:') == -1:
++    for line in maps:
++        slash = line.find('/')
++        if slash == -1 or line.find('00:') != -1: # if we don't have a '/' or if we fine 00: in the file then it's not _REALLY_ a file
+             continue
+         line = line.replace('\n', '')
+-        slash = line.find('/')
+         filename = line[slash:]
+-        filename = filename.replace('(deleted)', '') #only mildly retarded
++        #filename = filename.replace('(deleted)', '') #only mildly retarded
+         filename = filename.strip()
+         if filename not in files:
+             files.append(filename)
+@@ -106,7 +107,7 @@ def main(args):
+     if opts.useronly:
+         myuid = os.getuid()
+     
+-    needing_restart = []
++    needing_restart = set()
+ 
+     for pid in return_running_pids(uid=myuid):
+         try:
+@@ -117,12 +118,43 @@ def main(args):
+         for fn in get_open_files(pid):
+             if found_match:
+                 break
+-            
+-            for pkg in my.rpmdb.searchFiles(fn):
++            just_fn = fn.replace('(deleted)', '')
++            just_fn = just_fn.strip()            
++            bogon = False
++            # if the file is in a pkg which has been updated since we started the pid - then it needs to be restarted            
++            for pkg in my.rpmdb.searchFiles(just_fn):
+                 if float(pkg.installtime) > float(pid_start):
+-                    needing_restart.append(pid)
++                    needing_restart.add(pid)
+                     found_match = True
++                    continue
++                if just_fn in pkg.ghostlist:
++                    bogon = True
++                    break
++            
++            if bogon:
++                continue
+ 
++            # if the file is deleted 
++            if fn.find('(deleted)') != -1: 
++                # and it is from /*bin/* then it needs to be restarted 
++                if yum.misc.re_primary_filename(just_fn):
++                    needing_restart.add(pid)
++                    found_match = True
++                    continue
++
++                # if the file is from an old ver of an installed pkg - then assume it was just updated but the 
++                # new pkg doesn't have the same file names. Fabulous huh?!
++                my.conf.cache = False
++                for oldpkg in my.pkgSack.searchFiles(just_fn): # ghostfiles are always bogons
++                    if just_fn in oldpkg.ghostlist:
++                        continue
++                    if my.rpmdb.installed(oldpkg.name):
++                        needing_restart.add(pid)
++                        found_match = True
++                        break
++
++           
++            
+     for pid in needing_restart:
+         try:
+             cmdline = open('/proc/' +pid+ '/cmdline', 'r').read()
+diff --git a/package-cleanup.py b/package-cleanup.py
+index 4794369..acad9f2 100755
+--- a/package-cleanup.py
++++ b/package-cleanup.py
+@@ -12,11 +12,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ #
+ #
+ 
+@@ -119,34 +119,6 @@ class PackageCleanup(YumUtilBase):
+                                  'removing kernels')
+         self.optparser.add_option_group(kernelgrp)
+     
+-    def _find_missing_deps(self, pkgs):
+-        """find any missing dependencies for any installed package in pkgs"""
+-        # XXX - move into rpmsack/rpmdb
+-        
+-        providers = {} # To speed depsolving, don't recheck deps that have 
+-                       # already been checked
+-        problems = []
+-        for po in pkgs:
+-            for (req,flags,ver)  in po.requires:
+-                    
+-                if req.startswith('rpmlib'): continue # ignore rpmlib deps
+-                if (req,flags,ver) not in providers:
+-                    resolve_sack = self.rpmdb.whatProvides(req,flags,ver)
+-                else:
+-                    resolve_sack = providers[(req,flags,ver)]
+-                    
+-                if len(resolve_sack) < 1:
+-                    flags = yum.depsolve.flags.get(flags, flags)
+-                    missing = miscutils.formatRequire(req,ver,flags)
+-                    problems.append((po, "requires %s" % missing))
+-                                    
+-                else:
+-                    # Store the resolve_sack so that we can re-use it if another
+-                    # package has the same requirement
+-                    providers[(req,flags,ver)] = resolve_sack
+-        
+-        return problems
+-
+     def _find_installed_duplicates(self, ignore_kernel=True):
+         """find installed duplicate packages returns a dict of 
+            pkgname = [[dupe1, dupe2], [dupe3, dupe4]] """
+@@ -282,18 +254,29 @@ class PackageCleanup(YumUtilBase):
+         else:
+             kver = runningkernel
+             krel = ""
+-        remove = kernels[count:]
++
++        #  This is roughly what we want, but when there are multiple packages
++        # we want to keep N of each.
++        # remove = kernels[count:]
++        kern_name_map = {}
++        for kern in kernels:
++            if kern.name not in kern_name_map:
++                kern_name_map[kern.name] = []
++            kern_name_map[kern.name].append(kern)
++        remove = []
++        for kern in kern_name_map.values():
++            remove.extend(kern[count:])
+         
+         toremove = []
+         # Remove running kernel from remove list
+         for kernel in remove:
+-            if kernel.version == kver and krel.startswith(kernel.release):
++            if kernel.version == kver and kernel.release == krel:
+                 print "Not removing kernel %s-%s because it is the running kernel" % (kver,krel)
+             else:
+                 toremove.append(kernel)
+         
+             
+-        # Now extend the list with all kernel-devel pacakges that either
++        # Now extend the list with all kernel-devel packages that either
+         # have no matching kernel installed or belong to a kernel that is to
+         # be removed
+         if not keepdevel: 
+@@ -314,9 +297,9 @@ class PackageCleanup(YumUtilBase):
+             self.setCacheDir()
+         
+         if opts.problems:
+-            issues = self._find_missing_deps(self.rpmdb.returnPackages())
+-            for (pkg, prob) in issues:
+-                print 'Package %s %s' % (pkg.hdr.sprintf(opts.qf), prob)
++            issues = self.rpmdb.check_dependencies()
++            for prob in issues:
++                print 'Package %s' % prob
+ 
+             if issues:
+                 sys.exit(1)
+diff --git a/plugins/aliases/aliases.py b/plugins/aliases/aliases.py
+index 5cb08a1..9277c9b 100644
+--- a/plugins/aliases/aliases.py
++++ b/plugins/aliases/aliases.py
+@@ -44,7 +44,7 @@ class AliasedCommand:
+ 
+     def doCheck(self, base, basecmd, extcmds):
+         if recursive: # shouldn't happen
+-            raise PluginYumExit('And error has occured for %s, please create a bug report')
++            raise PluginYumExit('And error has occurred for %s, please create a bug report')
+ 
+         raise PluginYumExit('%s is an alias not a command, however recursive processing is turned off')
+     doCommand = doCheck
+diff --git a/plugins/auto-update-debuginfo/auto-update-debuginfo.py b/plugins/auto-update-debuginfo/auto-update-debuginfo.py
+index 39993ad..9ff927c 100644
+--- a/plugins/auto-update-debuginfo/auto-update-debuginfo.py
++++ b/plugins/auto-update-debuginfo/auto-update-debuginfo.py
+@@ -38,7 +38,7 @@ def _check_man_disable(mdrs, di):
+ def enable_debuginfo_repos(yb, conduit):
+     mdrs = set()
+     opts, args = conduit.getCmdLine()
+-    if opts is not None and hasattr(opts.repos) :
++    if hasattr(opts, 'repos'):
+         for opt, repoexp in opts.repos:
+             if opt == '--disablerepo':
+                 mdrs.add(repoexp)
+diff --git a/plugins/changelog/changelog.py b/plugins/changelog/changelog.py
+index 16144c6..d09281a 100644
+--- a/plugins/changelog/changelog.py
++++ b/plugins/changelog/changelog.py
+@@ -102,7 +102,7 @@ class ChangeLogCommand:
+         return ['changelog', 'ChangeLog']
+ 
+     def getUsage(self):
+-        return "<date>|<number>|all [PACKAGE|all|installed|updates|extras|obsoletes|recent]"
++        return "[<date>|<number>|all] [PACKAGE|all|installed|updates|extras|obsoletes|recent]"
+ 
+     def getSummary(self):
+         return """\
+@@ -212,6 +212,15 @@ Display changelog data, since a specified time, on a group of packages"""
+                     msg = "Argument -- %s -- is not valid: %s" % (since, to_str(e))
+                     raise PluginYumExit(msg)
+ 
++                if self._since_dto == dateutil_parser.parse('garbage', fuzzy=True):
++                    # 'since' was a package name, not a date
++                    extcmds.insert(0, since)
++
++                    # assume since="all"
++                    self._since_all = True
++                    self._since_dto = None
++                    self._since_tt  = None
++
+         ypl = base.returnPkgLists(extcmds)
+         self.show_data(msg, ypl.installed, 'Installed Packages')
+         self.show_data(msg, ypl.available, 'Available Packages')
+diff --git a/plugins/downloadonly/downloadonly.conf b/plugins/downloadonly/downloadonly.conf
+deleted file mode 100644
+index 8e4d76c..0000000
+--- a/plugins/downloadonly/downloadonly.conf
++++ /dev/null
+@@ -1,2 +0,0 @@
+-[main]
+-enabled=1
+diff --git a/plugins/downloadonly/downloadonly.py b/plugins/downloadonly/downloadonly.py
+deleted file mode 100644
+index 8486bb0..0000000
+--- a/plugins/downloadonly/downloadonly.py
++++ /dev/null
+@@ -1,48 +0,0 @@
+-#!/usr/bin/python
+-
+-# This program is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
+-# (at your option) any later version.
+-#
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+-#
+-# by Menno Smits
+-
+-from yum.plugins import PluginYumExit, TYPE_INTERACTIVE
+-
+-requires_api_version = '2.1'
+-plugin_type = (TYPE_INTERACTIVE,)
+-
+-def config_hook(conduit):
+-    parser = conduit.getOptParser()
+-    if hasattr(parser, 'plugin_option_group'):
+-        parser = parser.plugin_option_group
+-
+-    parser.add_option('', '--downloadonly', dest='dlonly', action='store_true',
+-           default=False, help="don't update, just download")
+-    parser.add_option('', '--downloaddir', dest='dldir',
+-                      action='store', default=None,
+-                      help="specifies an alternate directory to store packages")
+-
+-def postreposetup_hook(conduit):
+-    opts, commands = conduit.getCmdLine()
+-    if opts.dldir:
+-        repos = conduit.getRepos()
+-        rlist = repos.listEnabled()
+-        for repo in rlist:
+-            repo.setAttribute('pkgdir',opts.dldir)
+-           
+-
+-def postdownload_hook(conduit):
+-    opts, commands = conduit.getCmdLine()
+-    # Don't die on errors, or we'll never see them.
+-    if not conduit.getErrors() and opts.dlonly:
+-        raise PluginYumExit('exiting because --downloadonly specified ')
+diff --git a/plugins/fedorakmod/fedorakmod.py b/plugins/fedorakmod/fedorakmod.py
+index b3aed61..82a43d5 100644
+--- a/plugins/fedorakmod/fedorakmod.py
++++ b/plugins/fedorakmod/fedorakmod.py
+@@ -37,7 +37,7 @@ kernelVariants = ["bigmem", "enterprise", "smp", "hugemem", "PAE",
+                   "guest", "hypervisor", "xen0", "xenU", "xen"]
+ 
+ def getRunningKernel():
+-    # Taken from the installonlyn.py plugin writen by Jeremy Katz
++    # Taken from the installonlyn.py plugin written by Jeremy Katz
+     # Copyright 2005  Red Hat, Inc. 
+     # Modified by Jack Neely to return a kernel provides tuple
+     """This takes the output of uname and figures out the (version, release)
+diff --git a/plugins/fs-snapshot/fs-snapshot.conf b/plugins/fs-snapshot/fs-snapshot.conf
+index 3a67c69..9ada717 100644
+--- a/plugins/fs-snapshot/fs-snapshot.conf
++++ b/plugins/fs-snapshot/fs-snapshot.conf
+@@ -1,5 +1,6 @@
+ [main]
+ enabled = 1
++create_snapshots_in_post = 0
+ 
+ [lvm]
+ enabled = 0
+diff --git a/plugins/fs-snapshot/fs-snapshot.py b/plugins/fs-snapshot/fs-snapshot.py
+index 5094881..4f99b6a 100644
+--- a/plugins/fs-snapshot/fs-snapshot.py
++++ b/plugins/fs-snapshot/fs-snapshot.py
+@@ -21,7 +21,7 @@ This plugin creates a snapshot before any yum update or yum remove operation on
+ any btrfs filesystem that is affected by the update/remove operation.
+ 
+ This is a giant hammer.  Please be aware that if you rollback to a previous
+-snapshot that any other changes that occured to the filesystem after the
++snapshot that any other changes that occurred to the filesystem after the
+ snapshot takes place will not be in the snapshot.  You of course can mount the
+ newer version elsewhere and copy the new versions of the files back to your
+ rolled-back snapshot.  You have been warned.
+@@ -62,6 +62,9 @@ def kernel_supports_dm_snapshot_merge():
+         dm_snapshot_merge_checked = 1
+     return dm_snapshot_merge_support
+ 
++def is_thin_volume(volume):
++    return volume["segtype"] == "thin"
++
+ def inspect_volume_lvm(conduit, volume):
+     """
+     If volume is an LVM logical volume:
+@@ -79,25 +82,28 @@ def inspect_volume_lvm(conduit, volume):
+     if device.startswith("/dev/mapper/"):
+         # convert /dev/mapper name to /dev/vg/lv for use with LVM2 tools
+         # - 'dmsetup splitname' will collapse any escaped characters
+-        p = Popen(["/sbin/dmsetup", "splitname", "--separator", "/",
+-                   "--noheadings",
+-                   "-o", "vg_name,lv_name", device], stdout=PIPE, stderr=PIPE)
++        p = Popen(["/sbin/dmsetup", "splitname", "--separator", " ",
++                   "--noheadings", "-c",
++                   device], stdout=PIPE, stderr=PIPE)
+         err = p.wait()
+         if err:
+             return 0
+         output = p.communicate()[0]
+-        device = output.strip().replace("/dev/mapper/", "/dev/")
++        device = "/".join(output.split()[:2])
++        device = device.replace("/dev/mapper/", "/dev/")
+         volume["device"] = device
+ 
+     # Check if device is managed by lvm
+     # - FIXME filter out snapshot (and other) LVs; for now just rely
+     #   on 'lvcreate' to prevent snapshots of unsupported LV types
+-    p = Popen(["/sbin/lvs", device], stdout=PIPE, stderr=PIPE)
++    p = Popen(["/sbin/lvs", "--noheadings", "-o", "segtype", device], stdout=PIPE, stderr=PIPE)
+     err = p.wait()
+     if not err:
++        volume["segtype"] = p.communicate()[0].strip()
++
+         # FIXME allow creating snapshot LVs even if kernel doesn't
+         # support snapshot-merge based system rollback? make configurable?
+-        if not kernel_supports_dm_snapshot_merge():
++        if not is_thin_volume(volume) and not kernel_supports_dm_snapshot_merge():
+             conduit.error(1, "fs-snapshot: skipping volume: %s, "
+                           "kernel doesn't support snapshot-merge" % device)
+             return 0
+@@ -216,6 +222,14 @@ def _create_btrfs_snapshot(conduit, snapshot_tag, volume):
+         return 1
+     return 2
+ 
++def add_lvm_tag_to_snapshot(conduit, tag, snap_volume):
++    p = Popen(["/sbin/lvchange", "--addtag", tag, snap_volume],
++              stdout=PIPE, stderr=PIPE)
++    err = p.wait()
++    if err:
++        conduit.error(1, "fs-snapshot: couldn't add tag to snapshot: %s" %
++                      snap_volume)
++
+ def _create_lvm_snapshot(conduit, snapshot_tag, volume):
+     """
+     Create LVM snapshot LV and tag it with $snapshot_tag.
+@@ -223,16 +237,18 @@ def _create_lvm_snapshot(conduit, snapshot_tag, volume):
+       has enough free space to accommodate a snapshot LV.
+     - Also assumes user has configured 'lvcreate_size_args'.
+     """
+-    lvcreate_size_args = conduit.confString('lvm', 'lvcreate_size_args',
+-                                            default=None)
+-    if not lvcreate_size_args:
+-        conduit.error(1, "fs-snapshot: 'lvcreate_size_args' was not provided "
+-                      "in the '[lvm]' section of the config file")
+-        return 1
++    if not is_thin_volume(volume):
++        lvcreate_size_args = conduit.confString('lvm', 'lvcreate_size_args',
++                                                default=None)
+ 
+-    if not lvcreate_size_args.startswith("-L") and not lvcreate_size_args.startswith("-l"):
+-        conduit.error(1, "fs-snapshot: 'lvcreate_size_args' did not use -L or -l")
+-        return 1
++        if not lvcreate_size_args:
++            conduit.error(1, "fs-snapshot: 'lvcreate_size_args' was not provided "
++                          "in the '[lvm]' section of the config file")
++            return 1
++
++        if not lvcreate_size_args.startswith("-L") and not lvcreate_size_args.startswith("-l"):
++            conduit.error(1, "fs-snapshot: 'lvcreate_size_args' did not use -L or -l")
++            return 1
+ 
+     device = volume["device"]
+     if device.count('/') != 3:
+@@ -259,7 +275,8 @@ def _create_lvm_snapshot(conduit, snapshot_tag, volume):
+                  (mntpnt, device, snap_lvname))
+     # Create snapshot LV
+     lvcreate_cmd = ["/sbin/lvcreate", "-s", "-n", snap_lvname]
+-    lvcreate_cmd.extend(lvcreate_size_args.split())
++    if not is_thin_volume(volume):
++        lvcreate_cmd.extend(lvcreate_size_args.split())
+     lvcreate_cmd.append(device)
+     p = Popen(lvcreate_cmd, stdout=PIPE, stderr=PIPE)
+     err = p.wait()
+@@ -270,16 +287,18 @@ def _create_lvm_snapshot(conduit, snapshot_tag, volume):
+     # Add tag ($snapshot_tag) to snapshot LV
+     # - should help facilitate merge of all snapshot LVs created
+     #   by a yum transaction, e.g.: lvconvert --merge @snapshot_tag
+-    p = Popen(["/sbin/lvchange", "--addtag", snapshot_tag, snap_device],
+-              stdout=PIPE, stderr=PIPE)
+-    err = p.wait()
+-    if err:
+-        conduit.error(1, "fs-snapshot: couldn't add tag to snapshot: %s" %
+-                      snap_device)
++    if add_lvm_tag_to_snapshot(conduit, snapshot_tag, snap_device):
+         return 1
++    if conduit._base.__plugin_fs_snapshot_post_snapshot_tag == snapshot_tag:
++        # Add tag to allow other tools (e.g. snapper) to link pre
++        # and post snapshot LVs together
++        pre_snap_lv_name = "%s_%s" % (device, conduit._base.__plugin_fs_snapshot_pre_snapshot_tag)
++        pre_snapshot_tag = "yum_fs_snapshot_pre_lv_name=" + pre_snap_lv_name
++        if add_lvm_tag_to_snapshot(conduit, pre_snapshot_tag, snap_device):
++            return 1
+     return 2
+ 
+-def pretrans_hook(conduit):
++def create_snapshots(conduit):
+     """
+     This runs before the transaction starts.  Try to snapshot anything and
+     everything that is snapshottable, since we do not know what an RPM will
+@@ -287,6 +306,10 @@ def pretrans_hook(conduit):
+     """
+     # common snapshot tag format: yum_${year}${month}${day}${hour}${minute}${sec}
+     snapshot_tag = "yum_" + time.strftime("%Y%m%d%H%M%S")
++    if not conduit._base.__plugin_fs_snapshot_pre_snapshot_tag:
++        conduit._base.__plugin_fs_snapshot_pre_snapshot_tag = snapshot_tag
++    else:
++        conduit._base.__plugin_fs_snapshot_post_snapshot_tag = snapshot_tag
+ 
+     volumes = get_volumes(conduit)
+     for volume in volumes:
+@@ -296,3 +319,13 @@ def pretrans_hook(conduit):
+         elif rc == 2 and hasattr(conduit, 'registerPackageName'):
+             # A snapshot was successfully created
+             conduit.registerPackageName("yum-plugin-fs-snapshot")
++
++def pretrans_hook(conduit):
++    conduit._base.__plugin_fs_snapshot_pre_snapshot_tag = None
++    conduit._base.__plugin_fs_snapshot_post_snapshot_tag = None
++    create_snapshots(conduit)
++
++def posttrans_hook(conduit):
++    create_snapshots_in_post = conduit.confBool('main', 'create_snapshots_in_post', default=0)
++    if create_snapshots_in_post:
++        create_snapshots(conduit)
+diff --git a/plugins/keys/keys.py b/plugins/keys/keys.py
+index 3342576..4d2ca96 100644
+--- a/plugins/keys/keys.py
++++ b/plugins/keys/keys.py
+@@ -31,6 +31,15 @@ except:
+ requires_api_version = '2.1'
+ plugin_type = (TYPE_INTERACTIVE,)
+ 
++def gpgkey_fingerprint_ascii(gpg_cert, chop=4):
++    ''' Given a key_info data from getgpgkeyinfo(), return an ascii
++    fingerprint. Chop every 4 ascii values, as that is what GPG does. '''
++    fp = yum.pgpmsg.str_to_hex(gpg_cert.public_key.fingerprint())
++    if chop:
++        fp = [fp[i:i+chop] for i in range(0, len(fp), chop)]
++        fp = " ".join(fp)
++    return fp
++
+ def match_keys(patterns, key, globs=True):
+     for pat in patterns:
+         if pat == key.keyid:
+@@ -250,7 +259,7 @@ Key ID     : %s
+        time.ctime(key.createts),
+        gpg_cert.version, gpg_cert.user_id,
+        yum.pgpmsg.algo_pk_to_str[gpg_cert.public_key.pk_algo],
+-       yum.pgpmsg.str_to_hex(gpg_cert.public_key.fingerprint()),
++       gpgkey_fingerprint_ascii(gpg_cert),
+        yum.pgpmsg.str_to_hex(gpg_cert.public_key.key_id()))
+ 
+ 
+diff --git a/plugins/local/local.py b/plugins/local/local.py
+index c45a1ce..cab69c5 100644
+--- a/plugins/local/local.py
++++ b/plugins/local/local.py
+@@ -146,7 +146,7 @@ def _reposetup(conduit):
+              if repo.id == "_local"]
+     if lrepo:
+         lrepo = lrepo[0]
+-        os.unlink("%s/cachecookie" % lrepo.cachedir)
++        yum.misc.unlink_f("%s/cachecookie" % lrepo.cachedir)
+         return
+ 
+     conf_fname = '/etc/yum.repos.d/_local.repo'
+diff --git a/plugins/priorities/priorities.py b/plugins/priorities/priorities.py
+index 202c203..ce98583 100644
+--- a/plugins/priorities/priorities.py
++++ b/plugins/priorities/priorities.py
+@@ -161,9 +161,19 @@ def exclude_hook(conduit):
+                                 conduit.delPackage(po)
+                                 cnt += 1
+                                 conduit.info(3," --> %s from %s excluded (priority)" % (po,po.repoid))
++                                # Remove all occurances of this package
++                                for p in conduit.getPackages(repo):
++                                    if p.name==po.name:
++                                        conduit.delPackage(p)
++                                        cnt += 1
++                                        conduit.info(3," --> %s from %s excluded (priority)" % (p,p.repoid))
+                                 break
+     if cnt:
+         conduit.info(2, '%d packages excluded due to repository priority protections' % cnt)
++    if check_obsoletes:
++        #  Atm. the update object doesn't get updated when we manually exclude
++        # things ... so delete it. This needs to be re-written.
++        conduit._base.up = None
+ 
+ def _pkglist_to_dict(pl, priority, addArch = False):
+     out = dict()
+diff --git a/plugins/tmprepo/tmprepo.py b/plugins/tmprepo/tmprepo.py
+index e60dd4d..ec51f5b 100644
+--- a/plugins/tmprepo/tmprepo.py
++++ b/plugins/tmprepo/tmprepo.py
+@@ -91,7 +91,7 @@ def add_dir_repo(base, trepo, cleanup):
+         os.chmod(trepo_data, 0755)
+     trepo_name = os.path.basename(os.path.dirname(trepo_path))
+     tmp_fname  = "%s/tmp-%s.repo" % (trepo_data, trepo_name)
+-    repoid     = "T-%4.4s-%x" % (trepo_name, int(time.time()))
++    repoid     = "T-%0.4s-%x" % (trepo_name, int(time.time()))
+     tpc = 'true'
+     if not lpgpgcheck:
+         tpc = 'false'
+@@ -133,7 +133,7 @@ def add_repomd_repo(base, repomd):
+     AutoCleanupDir(trepo_data)
+     trepo_name = os.path.basename(os.path.dirname(os.path.dirname(repomd)))
+     tmp_fname  = "%s/tmp-%s.repo" % (trepo_data, trepo_name)
+-    repoid     = "T-%4.4s-%x" % (trepo_name, int(time.time()))
++    repoid     = "T-%0.4s-%x" % (trepo_name, int(time.time()))
+     pgpgcheck, rgpgcheck = rpgpgcheck, rrgpgcheck
+     if repomd.startswith("file:"):
+         pgpgcheck, rgpgcheck = lpgpgcheck, lrgpgcheck
+diff --git a/plugins/versionlock/versionlock.py b/plugins/versionlock/versionlock.py
+index 40756b2..dfe4dd3 100644
+--- a/plugins/versionlock/versionlock.py
++++ b/plugins/versionlock/versionlock.py
+@@ -56,6 +56,23 @@ def _read_locklist():
+         raise PluginYumExit('Unable to read version lock configuration: %s' % e)
+     return locklist
+ 
++def _match(ent, patterns):
++    # there should be an API for this in Yum
++    (n, v, r, e, a) = splitFilename(ent)
++    for name in (
++        '%s' % n,
++        '%s.%s' % (n, a),
++        '%s-%s' % (n, v),
++        '%s-%s-%s' % (n, v, r),
++        '%s-%s-%s.%s' % (n, v, r, a),
++        '%s:%s-%s-%s.%s' % (e, n, v, r, a),
++        '%s-%s:%s-%s.%s' % (n, e, v, r, a),
++    ):
++        for pat in patterns:
++            if fnmatch.fnmatch(name, pat):
++                return True
++    return False
++
+ class VersionLockCommand:
+     created = 1247693044
+ 
+@@ -99,9 +116,13 @@ class VersionLockCommand:
+             if not pkgs:
+                 pkgs = base.pkgSack.returnPackages(patterns=extcmds)
+ 
++            done = set()
++            for ent in _read_locklist():
++                (n, v, r, e, a) = splitFilename(ent)
++                done.add((n, a, e, v, r))
++
+             fo = open(filename, 'a')
+             count = 0
+-            done = set()
+             for pkg in pkgs:
+                 #  We ignore arch, so only add one entry for foo-1.i386 and
+                 # foo-1.x86_64.
+@@ -155,12 +176,7 @@ class VersionLockCommand:
+             out = os.fdopen(out, 'w', -1)
+             count = 0
+             for ent in _read_locklist():
+-                found = False
+-                for match in extcmds:
+-                    if fnmatch.fnmatch(ent, match):
+-                        found = True
+-                        break
+-                if found:
++                if _match(ent, extcmds):
+                     print "Deleting versionlock for:", ent
+                     count += 1
+                     continue
+@@ -170,6 +186,7 @@ class VersionLockCommand:
+             if not count:
+                 os.unlink(tmpfilename)
+                 return 1, ['Error: versionlock delete: no matches']
++            os.chmod(tmpfilename, 0644)
+             os.rename(tmpfilename, filename)
+             return 0, ['versionlock deleted: ' + str(count)]
+ 
+diff --git a/po/POTFILES.in b/po/POTFILES.in
+index 581da0a..d85030c 100644
+--- a/po/POTFILES.in
++++ b/po/POTFILES.in
+@@ -28,7 +28,6 @@ plugins/ps/ps.py
+ plugins/auto-update-debuginfo/auto-update-debuginfo.py
+ plugins/show-leaves/show-leaves.py
+ plugins/list-data/list-data.py
+-plugins/downloadonly/downloadonly.py
+ plugins/allowdowngrade/allowdowngrade.py
+ plugins/tsflags/tsflags.py
+ plugins/merge-conf/merge-conf.py
+diff --git a/repo-check.py b/repo-check.py
+index 7c4ae77..2aa8bde 100755
+--- a/repo-check.py
++++ b/repo-check.py
+@@ -7,11 +7,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ import sys
+ sys.path.insert(0,'/usr/share/yum-cli')
+@@ -239,4 +239,4 @@ class RepoCheck(YumUtilBase):
+ if __name__ == '__main__':
+     setup_locale()
+     util = RepoCheck()
+-    
+\ No newline at end of file
++    
+diff --git a/repo-graph.py b/repo-graph.py
+index bb901a8..bca41d0 100755
+--- a/repo-graph.py
++++ b/repo-graph.py
+@@ -7,11 +7,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # (c) 2005 Panu Matilainen <pmatilai@laiskiainen.org>
+ 
+ # generates graphviz .dot's from repomd data
+diff --git a/repo-rss.py b/repo-rss.py
+index 4a2917c..871e338 100755
+--- a/repo-rss.py
++++ b/repo-rss.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # seth vidal 2005 (c) etc etc
+ 
+ import yum
+@@ -144,7 +144,7 @@ class RepoRSS:
+             changelog += '%s - %s\n%s\n\n' % (date, author, desc)
+         description = '<p><strong>%s</strong> - %s</p>\n\n' % (escape(pkg.name), 
+                                             escape(pkg.returnSimple('summary')))
+-        description += '<p>%s</p>\n\n<p><strong>Change Log:</strong></p>\n\n' % escape(pkg.returnSimple('description').encode('utf-8').replace("\n", "<br />\n"))
++        description += '<p>%s</p>\n\n<p><strong>Change Log:</strong></p>\n\n' % escape(to_unicode(pkg.returnSimple('description')).encode('utf-8').replace("\n", "<br />\n"))
+         description += escape('<pre>%s</pre>' % escape(to_unicode(changelog).encode('utf-8')))
+         item.newChild(None, 'description', description)
+         
+@@ -222,6 +222,8 @@ def main(options, args):
+             sys.exit(1)
+     
+     recent = my.getRecent(days=days)
++    recent.sort(key=lambda pkg: pkg.returnSimple('filetime'))
++    recent.reverse()
+     if options.groups:
+         comps = Comps()
+         for repo in my.repos.listEnabled():
+diff --git a/repoclosure.py b/repoclosure.py
+index e710d8c..f895f84 100755
+--- a/repoclosure.py
++++ b/repoclosure.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # seth vidal 2005 (c) etc etc
+ 
+ 
+@@ -166,7 +166,7 @@ class RepoClosure(yum.YumBase):
+ 
+         for pkg in pkgs:
+             if pkg.repoid in self.lookaside:
+-                # don't attempt to resolve dependancy issues for
++                # don't attempt to resolve dependency issues for
+                 # packages from lookaside repositories
+                 continue
+             for (req, flags, (reqe, reqv, reqr)) in pkg.returnPrco('requires'):
+@@ -298,12 +298,12 @@ def main():
+                 req = '%s %s' % (req, v)
+             
+             my.logger.info('     %s' % req)
++    if baddeps:
++        sys.exit(1)
+ 
+ if __name__ == "__main__":
+     try:
+         main()
+     except (yum.Errors.YumBaseError, ValueError), e:
+         print >> sys.stderr, str(e)
+-        sys.exit(1)
+-        
+-        
++        sys.exit(2)
+diff --git a/repodiff.py b/repodiff.py
+index 67c162e..21be5af 100755
+--- a/repodiff.py
++++ b/repodiff.py
+@@ -10,8 +10,8 @@
+ # GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # (c) 2007 Red Hat. Written by skvidal@fedoraproject.org
+ 
+ import yum
+@@ -22,8 +22,16 @@ import locale
+ import rpmUtils.arch
+ from yum.i18n import to_unicode
+ 
++from urlgrabber.progress import format_number
++
+ from optparse import OptionParser
+ 
++def bkMG(num):
++    ''' Call format_number() but deals with negative numbers. '''
++    if num >= 0:
++        return format_number(num)
++    return '-' + format_number(-num)
++
+ class DiffYum(yum.YumBase):
+     def __init__(self):
+         yum.YumBase.__init__(self)
+@@ -43,8 +51,14 @@ class DiffYum(yum.YumBase):
+         # make our new repo obj
+         newrepo = yum.yumRepo.YumRepository(repoid)
+         newrepo.name = repoid
+-        newrepo.baseurl = [baseurl]
++        if baseurl.startswith("mirror:"):
++            newrepo.mirrorlist = baseurl[len("mirror:"):]
++        elif baseurl.startswith("/"):
++            newrepo.baseurl = ["file:" + baseurl]
++        else:
++            newrepo.baseurl = [baseurl]
+         newrepo.basecachedir = self.dy_basecachedir
++        newrepo.base_persistdir = self.dy_basecachedir
+         newrepo.metadata_expire = 0
+         newrepo.timestamp_check = False
+         # add our new repo
+@@ -157,6 +171,8 @@ def parseArgs(args):
+                       help="When comparing binary repos. also compare the arch of packages, to see if they are different")
+     parser.add_option("-s", "--size", default=False, action='store_true',
+                       help="Output size changes for any new->old packages")
++    parser.add_option("--downgrade", default=False, action='store_true',
++                      help="Output upgrade/downgrade separately")
+     parser.add_option("--simple",  default=False, action='store_true',
+                       help="output simple format")
+     (opts, argsleft) = parser.parse_args()
+@@ -177,6 +193,47 @@ def parseArgs(args):
+     
+     return opts
+ 
++def _out_mod(opts, oldpkg, pkg, sizechange):
++    if opts.simple:
++        if opts.compare_arch:
++            msg = "%s: %s ->  %s" % (pkg.name, oldpkg, pkg)
++        else:
++            msg = "%s: %s-%s-%s ->  %s-%s-%s" % (pkg.name, oldpkg.name, 
++                                                 oldpkg.ver, oldpkg.rel,
++                                                 pkg.name, pkg.ver,
++                                                 pkg.rel)
++    else:
++        if opts.compare_arch:
++            msg = "%s" % pkg
++        else:
++            msg = "%s-%s-%s" % (pkg.name, pkg.ver, pkg.rel)
++        dashes = "-" * len(msg) 
++        msg += "\n%s\n" % dashes
++        # get newest clog time from the oldpkg
++        # for any newer clog in pkg
++        # print it
++        oldlogs = oldpkg.changelog
++        if len(oldlogs):
++            #  Don't sort as that can screw the order up when time is the
++            # same.
++            oldtime    = oldlogs[0][0]
++            oldauth    = oldlogs[0][1]
++            oldcontent = oldlogs[0][2]
++            for (t, author, content) in  pkg.changelog:
++                if t < oldtime:
++                    break
++                if ((t == oldtime) and (author == oldauth) and
++                    (content == oldcontent)):
++                    break
++                tm = datetime.date.fromtimestamp(int(t))
++                tm = tm.strftime("%a %b %d %Y")
++                msg += "* %s %s\n%s\n\n" % (tm, to_unicode(author),
++                                            to_unicode(content))
++            if opts.size:
++                msg += "\nSize change: %s bytes\n" % sizechange
++
++    print msg
++
+ def main(args):
+     opts = parseArgs(args)
+ 
+@@ -221,6 +278,11 @@ def main(args):
+     total_sizechange = 0
+     add_sizechange = 0
+     remove_sizechange = 0
++    mod_sizechange = 0
++    up_sizechange = 0
++    down_sizechange = 0
++    upgraded_pkgs = 0
++    downgraded_pkgs = 0
+     if ygh.add:
+         for pkg in sorted(ygh.add):
+             if opts.compare_arch:
+@@ -243,49 +305,32 @@ def main(args):
+     if ygh.modified:
+         print '\nUpdated Packages:\n'
+         for (pkg, oldpkg) in sorted(ygh.modified):
++            if opts.downgrade and pkg.verLT(oldpkg):
++                continue
++
++            upgraded_pkgs += 1
++            sizechange = None
+             if opts.size:
+                 sizechange = int(pkg.size) - int(oldpkg.size)
+-                total_sizechange += sizechange
+-            
+-            if opts.simple:
+-                if opts.compare_arch:
+-                    msg = "%s: %s ->  %s" % (pkg.name, oldpkg, pkg)
+-                else:
+-                    msg = "%s: %s-%s-%s ->  %s-%s-%s" % (pkg.name, oldpkg.name, 
+-                                                         oldpkg.ver, oldpkg.rel,
+-                                                         pkg.name, pkg.ver,
+-                                                         pkg.rel)
+-            else:
+-                if opts.compare_arch:
+-                    msg = "%s" % pkg
++                if opts.downgrade:
++                    up_sizechange += sizechange
+                 else:
+-                    msg = "%s-%s-%s" % (pkg.name, pkg.ver, pkg.rel)
+-                dashes = "-" * len(msg) 
+-                msg += "\n%s\n" % dashes
+-                # get newest clog time from the oldpkg
+-                # for any newer clog in pkg
+-                # print it
+-                oldlogs = oldpkg.changelog
+-                if len(oldlogs):
+-                    #  Don't sort as that can screw the order up when time is the
+-                    # same.
+-                    oldtime    = oldlogs[0][0]
+-                    oldauth    = oldlogs[0][1]
+-                    oldcontent = oldlogs[0][2]
+-                    for (t, author, content) in  pkg.changelog:
+-                        if t < oldtime:
+-                            break
+-                        if ((t == oldtime) and (author == oldauth) and
+-                            (content == oldcontent)):
+-                            break
+-                        tm = datetime.date.fromtimestamp(int(t))
+-                        tm = tm.strftime("%a %b %d %Y")
+-                        msg += "* %s %s\n%s\n\n" % (tm, to_unicode(author),
+-                                                    to_unicode(content))
+-                    if opts.size:
+-                        msg += "\nSize Change: %s bytes\n" % sizechange
+-
+-            print msg
++                    mod_sizechange += sizechange
++            _out_mod(opts, oldpkg, pkg, sizechange)
++
++        if opts.downgrade:
++            print '\nDowngraded Packages:\n'
++            for (pkg, oldpkg) in sorted(ygh.modified):
++                if pkg.verGT(oldpkg):
++                    continue
++
++                downgraded_pkgs += 1
++                sizechange = None
++                if opts.size:
++                    sizechange = int(pkg.size) - int(oldpkg.size)
++                    down_sizechange += sizechange
++                _out_mod(opts, oldpkg, pkg, sizechange)
++
+ 
+     if (not ygh.add and not ygh.remove and not ygh.modified and
+         not my.pkgSack.searchNevra(arch='src')):
+@@ -294,11 +339,34 @@ def main(args):
+     print '\nSummary:'
+     print 'Added Packages: %s' % len(ygh.add)
+     print 'Removed Packages: %s' % len(ygh.remove)
+-    print 'Modified Packages: %s' % len(ygh.modified)
++    if not opts.downgrade:
++        print 'Modified Packages: %s' % len(ygh.modified)
++    else:
++        print 'Upgraded Packages: %s' % upgraded_pkgs
++        print 'Downgraded Packages: %s' % downgraded_pkgs
+     if opts.size:
+-        print 'Size of added packages: %s' % add_sizechange
+-        print 'Size change of modified packages: %s' % total_sizechange
+-        print 'Size of removed packages: %s' % remove_sizechange
++        print 'Size of added packages: %s (%s)' % (add_sizechange,
++                                                   bkMG(add_sizechange))
++
++        if not opts.downgrade:
++            msg = 'Size change of modified packages: %s (%s)'
++            print msg % (mod_sizechange, bkMG(mod_sizechange))
++
++            total_sizechange = add_sizechange +mod_sizechange -remove_sizechange
++        else:
++            msg = 'Size change of upgraded packages: %s (%s)'
++            print msg % (up_sizechange, bkMG(up_sizechange))
++            msg = 'Size change of downgraded packages: %s (%s)'
++            print msg % (down_sizechange, bkMG(down_sizechange))
++
++            total_sizechange = (add_sizechange +
++                                up_sizechange + down_sizechange -
++                                remove_sizechange)
++
++        msg = 'Size of removed packages: %s (%s)'
++        print msg % (remove_sizechange, bkMG(remove_sizechange))
++        msg = 'Size change: %s (%s)'
++        print msg % (total_sizechange, bkMG(total_sizechange))
+     
+       
+ if __name__ == "__main__":
+diff --git a/repomanage.py b/repomanage.py
+index ff77e0d..bef3b03 100755
+--- a/repomanage.py
++++ b/repomanage.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ # (c) Copyright Seth Vidal 2004
+ 
+diff --git a/repoquery.py b/repoquery.py
+index a3bb111..64976ec 100755
+--- a/repoquery.py
++++ b/repoquery.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # (c) pmatilai@laiskiainen.org
+ 
+ 
+@@ -25,7 +25,6 @@ import fnmatch
+ import time
+ import os
+ import os.path
+-import exceptions
+ import urlparse
+ 
+ from optparse import OptionParser
+@@ -74,6 +73,15 @@ querytags = [ 'name', 'version', 'release', 'epoch', 'arch', 'summary',
+               'installedsize', 'archivesize', 'packagesize', 'repoid', 
+               'requires', 'provides', 'conflicts', 'obsoletes',
+               'relativepath', 'hdrstart', 'hdrend', 'id',
++              'checksum', 'pkgid', 'committer', 'committime',
++              'ui_evr', 'evr', 'ui_nevra', 'ui_envra',
++              'ui_from_repo', 'base_package_name', 'size', 'xattr_origin_url',
++              'ui_evra', 'ui_nevr', 'na', 'vr', 'vra', 'evr', 'evra',
++              'nvr', 'nvra', 'nevr', 'nevra', 'envr', 'envra',
++
++              'repo.<attr of the repo object>',
++              'yumdb.<attr of the yumdb object>',
++              '<attr of the yum object>'
+             ]
+ 
+ def sec2isodate(timestr):
+@@ -114,7 +122,7 @@ convertmap = { 'date': sec2date,
+                'h':  size2h,
+              }
+ 
+-class queryError(exceptions.Exception):
++class queryError(Exception):
+     def __init__(self, value=None):
+         Exception.__init__(self)
+         self.value = value
+@@ -316,12 +324,13 @@ class pkgQuery:
+         print "%s%s [%s]" % (indent, str(req), str(val))
+ 
+     # These are common helpers for the --tree-* options...
+-    @staticmethod
+-    def _tree_print_req(req, val, level):
++    def _tree_print_req(self, req, val, level):
+         indent = ''
+         if level:
+             indent = ' |  ' * (level - 1) + ' \_  '
+-        print "%s%s [%s]" % (indent, str(req), str(val))
++        self.pkg = req
++        self.name = req.name
++        print "%s%s [%s]" % (indent, self.fmt_queryformat(), str(val))
+     def _tree_pkg2uniq(self, pkg):
+         """ Turn a pkg into a "unique" req."""
+         if self.yb and self.yb.conf.showdupesfromrepos:
+@@ -365,6 +374,7 @@ class pkgQuery:
+                 kw['dot'] = DotPlot()
+         elif 'dot' not in kw.keys() or kw['dot'] is None:
+             kw['dot'] = None
++        dot      = kw['dot']
+         
+         if str(kw['tree_level']).lower() != 'all':
+             try: 
+@@ -375,6 +385,15 @@ class pkgQuery:
+         if not 'output' in kw.keys():
+             kw['output'] = 'ascii-tree'
+ 
++        #  Level means something a bit different for dot, because we have to
++        # lookup it's packages ... but we don't for ascii. *sigh*
++        if dot is None:
++            self._tree_print_req(pkg, req, level)
++            lim = level + 1
++            if str(kw['tree_level']).lower() != 'all' and \
++                int(kw['tree_level']) < int(lim):
++                return
++
+         __req2pkgs = {}
+         def req2pkgs(ignore, req):
+             req = str(req)
+@@ -406,6 +425,8 @@ class pkgQuery:
+                     providers = matches.keys()
+ 
+ 
++            except yum.Errors.RepoError:
++                raise
+             except yum.Errors.YumBaseError, err:
+                 print >>sys.stderr, "No package provides %s" % req
+                 return []
+@@ -413,14 +434,9 @@ class pkgQuery:
+             __req2pkgs[req] = providers
+             return providers 
+         
+-        dot = kw['dot']
+-        
+         tups = getattr(pkg, prco_type)
+         rpkgs, loc_reqs = self._tree_maybe_add_pkgs(all_reqs, tups, req2pkgs)
+-        if dot is None:
+-            self._tree_print_req(pkg, req, level)
+-            lim = level + 1
+-        else:
++        if dot is not None:
+             dot.addPackage(pkg, rpkgs)
+             lim = level + 2
+         nlevel = level + 1
+@@ -449,6 +465,7 @@ class pkgQuery:
+ 
+     def fmt_tree_obsoletes(self, **kw):
+         pkg      = kw.get('pkg', self.pkg)
++        req      = kw.get('req', 'cmd line')
+         level    = kw.get('level', 0)
+         all_reqs = kw.get('all_reqs', {})
+         
+@@ -457,6 +474,7 @@ class pkgQuery:
+                 kw['dot'] = DotPlot()
+         elif 'dot' not in kw.keys() or kw['dot'] is None:
+             kw['dot'] = None
++        dot      = kw['dot']
+         
+         if str(kw['tree_level']).lower() != 'all':
+             try: 
+@@ -467,6 +485,15 @@ class pkgQuery:
+         if not 'output' in kw.keys():
+             kw['output'] = 'ascii-tree'
+         
++        #  Level means something a bit different for dot, because we have to
++        # lookup it's packages ... but we don't for ascii. *sigh*
++        if dot is None:
++            self._tree_print_req(pkg, req, level)
++            lim = level + 1
++            if str(kw['tree_level']).lower() != 'all' and \
++                int(kw['tree_level']) < int(lim):
++                return
++
+         def obs2pkgs():
+             if self.yb is None:
+                 return []
+@@ -496,10 +523,7 @@ class pkgQuery:
+         else:
+             reason = 'cmd line'
+         rpkgs = obs2pkgs()
+-        if dot is None:
+-            self._tree_print_req(pkg, reason, level)
+-            lim = level + 1
+-        else:
++        if dot is not None:
+             dot.addPackage(pkg, rpkgs)
+             lim = level + 2
+         all_reqs[pkg] = None
+@@ -514,6 +538,7 @@ class pkgQuery:
+                 self._tree_print_req(rpkg, '', nlevel)
+                 continue
+             self.fmt_tree_obsoletes(pkg=rpkg, level=nlevel, all_reqs=all_reqs,
++                                    req = pkg.name,
+                                     tree_level = kw['tree_level'],
+                                     output = kw['output'],
+                                     dot = dot)
+@@ -527,6 +552,7 @@ class pkgQuery:
+         if kw['output'].lower() == 'dot-tree':
+             if 'dot' not in kw.keys() or kw['dot'] is None:
+                 kw['dot'] = DotPlot()
++        dot      = kw['dot']
+ 
+         if str(kw['tree_level']).lower() != 'all':
+             try: 
+@@ -537,6 +563,15 @@ class pkgQuery:
+         if not 'output' in kw.keys():
+             kw['output'] = 'ascii-tree'
+ 
++        #  Level means something a bit different for dot, because we have to
++        # lookup it's packages ... but we don't for ascii. *sigh*
++        if dot is None:
++            self._tree_print_req(pkg, req, level)
++            lim = level + 1
++            if str(kw['tree_level']).lower() != 'all' and \
++                int(kw['tree_level']) < int(lim):
++                return
++
+         __prov2pkgs = {}
+         def prov2pkgs(prov, ignore):
+             if str(prov) in __prov2pkgs:
+@@ -562,6 +597,8 @@ class pkgQuery:
+                         arequirers = [pkg for pkg in areqs
+                                       if pkg.pkgtup not in skip]
+ 
++            except yum.Errors.RepoError:
++                raise
+             except yum.Errors.YumBaseError, err:
+                 print >>sys.stderr, "No package provides %s" % str(prov)
+                 return []
+@@ -575,12 +612,8 @@ class pkgQuery:
+         
+         tups = pkg.provides + filetupes
+         rpkgs, loc_reqs = self._tree_maybe_add_pkgs(all_reqs, tups, prov2pkgs)
+-        dot = kw['dot']
+         
+-        if dot is None:
+-            self._tree_print_req(pkg, req, level)
+-            lim = level + 1
+-        else:
++        if dot is not None:
+             dot.addPackage(pkg, rpkgs)
+             lim = level + 2
+         nlevel = level + 1
+@@ -719,13 +752,13 @@ class groupQuery:
+             raise queryError("Invalid group query: %s" % method)
+ 
+     # XXX temporary hack to make --group -a query work
+-    def fmt_queryformat(self):
++    def fmt_queryformat(self, **kw):
+         return self.fmt_nevra()
+ 
+-    def fmt_nevra(self):
++    def fmt_nevra(self, **kw):
+         return ["%s - %s" % (self.id, self.name)]
+ 
+-    def fmt_list(self):
++    def fmt_list(self, **kw):
+         pkgs = []
+         for t in self.grouppkgs.split(','):
+             if t == "mandatory":
+@@ -741,10 +774,10 @@ class groupQuery:
+             
+         return pkgs
+         
+-    def fmt_requires(self):
++    def fmt_requires(self, **kw):
+         return self.group.mandatory_packages
+ 
+-    def fmt_info(self):
++    def fmt_info(self, **kw):
+         return ["%s:\n\n%s\n" % (self.name, self.group.description)]
+ 
+ 
+@@ -826,6 +859,8 @@ class YumBaseQuery(yum.YumBase):
+                     pkgs = self.pkgSack.returnNewestByNameArch(**kwargs)
+                 except yum.Errors.PackageSackError:
+                     pkgs = []
++                except yum.Errors.RepoError, e:
++                    raise queryError(e)
+         else:
+             what = self.options.pkgnarrow
+             ygh = self.doPackageLists(what, **kwargs)
+@@ -848,6 +883,8 @@ class YumBaseQuery(yum.YumBase):
+             matches = yum.YumBase.searchPackageProvides(self, [str(depstring)])
+             provider = matches.keys()
+             # provider.extend(yum.YumBase.returnPackagesByDep(self, depstring))
++        except yum.Errors.RepoError:
++            raise
+         except yum.Errors.YumBaseError, err:
+             self.logger.error("No package provides %s" % depstring)
+         return self.queryPkgFactory(provider)
+@@ -1008,12 +1045,12 @@ class YumBaseQuery(yum.YumBase):
+ 
+     def fmt_whatrequires(self, name, **kw):
+         pkgs = {}
+-        done = [] # keep track of names we have already visited
++        done = set() # keep track of names we have already visited
+ 
+         def require_recursive(name):
+             if name in done:
+                 return
+-            done.append(name)
++            done.add(name)
+ 
+             provs = [name]
+                     
+@@ -1054,10 +1091,21 @@ class YumBaseQuery(yum.YumBase):
+ 
+     def fmt_requires(self, name, **kw):
+         pkgs = {}
+-        for pkg in self.returnByName(name):
++        done = set()
++        def require_recursive(pkg):
++            if pkg.name in done:
++                return
++            done.add(pkg.name)
++
+             for req in pkg.prco("requires"):
+                 for res in self.fmt_whatprovides(req):
+                     pkgs[(res.name, res.pkg.arch)] = res
++                    if self.options.recursive:
++                        require_recursive(res)
++
++        for pkg in self.returnByName(name):
++            require_recursive(pkg)
++
+         return pkgs.values()
+ 
+     def fmt_location(self, name):
+@@ -1070,6 +1118,44 @@ class YumBaseQuery(yum.YumBase):
+                 loc.append("%s/%s" % (repo.urls[0], pkg['relativepath']))
+         return loc
+ 
++    def _parseSetOpts(self, setopts):
++        """parse the setopts list handed to us and saves the results as
++           repo_setopts and main_setopts in the yumbase object"""
++
++        repoopts = {}
++        mainopts = yum.misc.GenericHolder()
++        mainopts.items = []
++
++        bad_setopt_tm = []
++        bad_setopt_ne = []
++
++        for item in setopts:
++            vals = item.split('=')
++            if len(vals) > 2:
++                bad_setopt_tm.append(item)
++                continue
++            if len(vals) < 2:
++                bad_setopt_ne.append(item)
++                continue
++            k,v = vals
++            period = k.find('.')
++            if period != -1:
++                repo = k[:period]
++                k = k[period+1:]
++                if repo not in repoopts:
++                    repoopts[repo] = yum.misc.GenericHolder()
++                    repoopts[repo].items = []
++                setattr(repoopts[repo], k, v)
++                repoopts[repo].items.append(k)
++            else:
++                setattr(mainopts, k, v)
++                mainopts.items.append(k)
++
++        self.main_setopts = mainopts
++        self.repo_setopts = repoopts
++
++        return bad_setopt_tm, bad_setopt_ne
++
+ 
+ def main(args):
+ 
+@@ -1198,6 +1284,10 @@ def main(args):
+     parser.add_option("--search-fields", action="append", dest="searchfields",
+                       default=[],
+                       help="search fields to search using --search")
++    parser.add_option("--installroot", default="/", help="set install root")
++    parser.add_option("", "--setopt", dest="setopts", default=[],
++                     action="append",
++                     help="set arbitrary config and repo options")
+                       
+ 
+     (opts, regexs) = parser.parse_args()
+@@ -1261,9 +1351,10 @@ def main(args):
+     if opts.srpm:
+         needsource = 1
+     if opts.whatrequires:
+-        sackops.append("whatrequires")
+         if opts.output != 'text':
+             pkgops.append("tree_what_requires")
++        else:
++            sackops.append("whatrequires")
+     if opts.whatprovides:
+         sackops.append("whatprovides")
+     if opts.whatobsoletes:
+@@ -1280,7 +1371,6 @@ def main(args):
+         needgroup = 1
+     if opts.installed:
+         opts.pkgnarrow = 'installed'
+-        opts.disablerepos = ['*']
+ 
+     if opts.nevra:
+         pkgops.append("nevra")
+@@ -1303,6 +1393,13 @@ def main(args):
+         
+     repoq = YumBaseQuery(pkgops, sackops, opts)
+ 
++    # go through all the setopts and set the global ones
++    bad_setopt_tm, bad_setopt_ne = repoq._parseSetOpts(opts.setopts)
++
++    if repoq.main_setopts:
++        for opt in repoq.main_setopts.items:
++            setattr(opts, opt, getattr(repoq.main_setopts, opt))
++
+     # silence initialisation junk from modules etc unless verbose mode
+     initnoise = (not opts.quiet) * 2
+     repoq.preconf.releasever = opts.releasever
+@@ -1312,7 +1409,26 @@ def main(args):
+         repoq.preconf.fn = opts.conffile
+     repoq.preconf.debuglevel = initnoise
+     repoq.preconf.init_plugins = opts.plugins
+-    repoq.conf
++    repoq.preconf.root = opts.installroot
++    try:
++        repoq.conf
++    except YumBaseError, e:
++        repoq.logger.error(e)
++        sys.exit(1)
++
++    for item in  bad_setopt_tm:
++        msg = "Setopt argument has multiple values: %s"
++        repoq.logger.warning(msg % item)
++    for item in  bad_setopt_ne:
++        msg = "Setopt argument has no value: %s"
++        repoq.logger.warning(msg % item)
++    # now set  all the non-first-start opts from main from our setopts
++    if repoq.main_setopts:
++        for opt in repoq.main_setopts.items:
++            if not hasattr(repoq.conf, opt):
++                msg ="Main config did not have a %s attr. before setopt"
++                repoq.logger.warning(msg % opt)
++            setattr(repoq.conf, opt, getattr(repoq.main_setopts, opt))
+ 
+     if opts.repofrompath:
+         # setup the fake repos
+@@ -1327,8 +1443,13 @@ def main(args):
+             else:
+                 baseurl = repopath
+                 
+-            repoq.add_enable_repo(repoid, baseurls=[baseurl], 
+-                    basecachedir=repoq.conf.cachedir)
++            try:
++                repoq.add_enable_repo(repoid, baseurls=[baseurl],
++                                      basecachedir=repoq.conf.cachedir,
++                                      timestamp_check=False)
++            except yum.Errors.DuplicateRepoError, e:
++                repoq.logger.error(e)
++                sys.exit(1)
+             if not opts.quiet:
+                 repoq.logger.info( "Added %s repo from %s" % (repoid,repopath))
+ 
+@@ -1359,6 +1480,13 @@ def main(args):
+     if opts.show_dupes:
+         repoq.conf.showdupesfromrepos = True
+             
++
++    if opts.pkgnarrow == 'installed':
++        # Just use a blunt hammer here, to make everyone sane:
++        opts.repoid = []
++        opts.disablerepos = ['*']
++        opts.enablerepos  = []
++
+     if opts.repoid:
+         found_repos = set()
+         for repo in repoq.repos.findRepos('*'):
+@@ -1380,6 +1508,14 @@ def main(args):
+             for repo in repoq.repos.findRepos(repo_match):
+                 repo.enable()
+ 
++    while True:
++        try: repoq.doLock(); break
++        except yum.Errors.LockError, e: pass
++        repoq.logger.error(e)
++        if repoq.conf.exit_on_lock:
++            sys.exit(50)
++        time.sleep(2)
++
+     try:
+         if not hasattr(repoq, 'arch'):
+             repoq.doSackSetup(archlist=archlist)
+@@ -1396,10 +1532,15 @@ def main(args):
+     except (yum.Errors.RepoError, yum.Errors.GroupsError), e:
+         repoq.logger.error(e)
+         sys.exit(1)
++
+     try:
+         repoq.runQuery(regexs)
++    except yum.Errors.RepoError, e:
++        repoq.logger.error(e)
++        sys.exit(1)
+     except queryError, e:
+         repoq.logger.error(e)
++        sys.exit(1)
+ 
+ if __name__ == "__main__":
+     misc.setup_locale()
+diff --git a/reposync.py b/reposync.py
+index 7950854..b1ee285 100755
+--- a/reposync.py
++++ b/reposync.py
+@@ -11,8 +11,8 @@
+ # GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # copyright 2006 Duke University
+ # author seth vidal
+ 
+@@ -47,7 +47,7 @@ from yum.constants import *
+ from yum.packageSack import ListPackageSack
+ import rpmUtils.arch
+ import logging
+-from urlgrabber.progress import TextMeter
++from urlgrabber.progress import TextMeter, TextMultiFileMeter
+ import urlgrabber
+ 
+ # for yum 2.4.X compat
+@@ -96,7 +96,7 @@ def parseArgs():
+     parser.add_option("-c", "--config", default='/etc/yum.conf',
+         help='config file to use (defaults to /etc/yum.conf)')
+     parser.add_option("-a", "--arch", default=None,
+-        help='act as if running the specified arch (default: current arch, note: does not override $releasever)')
++        help='act as if running the specified arch (default: current arch, note: does not override $releasever. x86_64 is a superset for i*86.)')
+     parser.add_option("--source", default=False, dest="source", action="store_true",
+                       help='operate on source packages')
+     parser.add_option("-r", "--repoid", default=[], action='append',
+@@ -153,15 +153,27 @@ def main():
+         opts.tempcache = True
+ 
+     if opts.tempcache:
+-        cachedir = getCacheDir()
+-        if cachedir is None:
++        if not my.setCacheDir(force=True):
+             print >> sys.stderr, "Error: Could not make cachedir, exiting"
+             sys.exit(50)
+-            
+-        my.repos.setCacheDir(cachedir)
++        my.conf.uid = 1 # force locking of user cache
+     elif opts.cachedir:
+         my.repos.setCacheDir(opts.cachedir)
+ 
++    # Lock if they've not given an explicit cachedir
++    if not opts.cachedir:
++        try:
++            my.doLock()
++        except yum.Errors.LockError, e:
++            print >> sys.stderr, "Error: %s" % e
++            sys.exit(50)
++
++    #  Use progress bar display when downloading repo metadata
++    # and package files ... needs to be setup before .repos (ie. RHN/etc.).
++    if not opts.quiet:
++        my.repos.setProgressBar(TextMeter(fo=sys.stdout), TextMultiFileMeter(fo=sys.stdout))
++    my.doRepoSetup()
++
+     if len(opts.repoid) > 0:
+         myrepos = []
+         
+@@ -182,13 +194,6 @@ def main():
+         print >> sys.stderr, "Error: Can't use --norepopath with multiple repositories"
+         sys.exit(1)
+ 
+-    # Use progress bar display when downloading repo metadata
+-    # and package files
+-    if not opts.quiet:
+-        my.repos.setProgressBar(TextMeter(fo=sys.stdout))
+-
+-    my.doRpmDBSetup()
+-    my.doRepoSetup()
+     try:
+         arches = rpmUtils.arch.getArchList(opts.arch)
+         if opts.source:
+@@ -199,6 +204,7 @@ def main():
+         # maybe this shouldn't be entirely fatal
+         sys.exit(1)
+     
++    exit_code = 0
+     for repo in my.repos.listEnabled():
+         reposack = ListPackageSack(my.pkgSack.returnPackages(repoid=repo.id))
+ 
+@@ -277,73 +283,47 @@ def main():
+             urlgrabber.progress.text_meter_total_size(remote_size)
+ 
+         download_list.sort(sortPkgObj)
+-        n = 0
++        if opts.urls:
++            for pkg in download_list:
++                print urljoin(pkg.repo.urls[0], pkg.relativepath)
++            return 0
++
++        # create dest dir
++        if not os.path.exists(local_repo_path):
++            os.makedirs(local_repo_path)
++
++        # set localpaths
+         for pkg in download_list:
+-            n = n + 1
+-            repo = my.repos.getRepo(pkg.repoid)
+-            remote = pkg.returnSimple('relativepath')
+-            local = local_repo_path + '/' + remote
+-            localdir = os.path.dirname(local)
+-            if not os.path.exists(localdir):
+-                os.makedirs(localdir)
+-
+-            sz = int(pkg.returnSimple('packagesize'))
+-            if os.path.exists(local) and os.path.getsize(local) == sz:
+-                
+-                if not opts.quiet:
+-                    my.logger.error("[%s: %-5d of %-5d ] Skipping existing %s" % (repo.id, n, len(download_list), remote))
+-                continue
+-    
+-            if opts.urls:
+-                baseurl = None
+-                if repo.urls[0][-1] != '/':
+-                    baseurl = repo.urls[0] + '/'
+-                else:
+-                    baseurl = repo.urls[0]
+-                    url = urljoin(baseurl,remote)
+-                    print '%s' % url
+-                continue
+-    
+-            # make sure the repo subdir is here before we go on.
+-            if not os.path.exists(local_repo_path):
+-                try:
+-                    os.makedirs(local_repo_path)
+-                except IOError, e:
+-                    my.logger.error("Could not make repo subdir: %s" % e)
+-                    my.closeRpmDB()
+-                    sys.exit(1)
+-            
+-            # Disable cache otherwise things won't download            
+-            repo.cache = 0
+-            if not opts.quiet:
+-                my.logger.info( '[%s: %-5d of %-5d ] Downloading %s' % (repo.id, n, len(download_list), remote))
+-            pkg.localpath = local # Hack: to set the localpath we want.
+-            try:
+-                path = repo.getPackage(pkg)
+-            except yum.Errors.RepoError, e:
+-                my.logger.error("Could not retrieve package %s. Error was %s" % (pkg, str(e)))
+-                local_size += sz
+-                continue
+-
+-            local_size += sz
+-            if hasattr(urlgrabber.progress, 'text_meter_total_size'):
+-                urlgrabber.progress.text_meter_total_size(remote_size, local_size)
+-            if opts.gpgcheck:
++            rpmfn = os.path.basename(pkg.remote_path)
++            pkg.localpath = os.path.join(local_repo_path, rpmfn)
++            pkg.repo.copy_local = True
++            pkg.repo.cache = 0
++
++        # use downloader from YumBase
++        probs = my.downloadPkgs(download_list)
++        if probs:
++            exit_code = 1
++            for key in probs:
++                for error in probs[key]:
++                    my.logger.error('%s: %s', key, error)
++
++        if opts.gpgcheck:
++            for pkg in download_list:
+                 result, error = my.sigCheckPkg(pkg)
+                 if result != 0:
++                    rpmfn = os.path.basename(pkg.remote_path)
+                     if result == 1:
+-                        my.logger.warning('Removing %s, due to missing GPG key.' % os.path.basename(remote))
++                        my.logger.warning('Removing %s, due to missing GPG key.' % rpmfn)
+                     elif result == 2:
+-                        my.logger.warning('Removing %s due to failed signature check.' % os.path.basename(remote))
++                        my.logger.warning('Removing %s due to failed signature check.' % rpmfn)
+                     else:
+-                        my.logger.warning('Removing %s due to failed signature check: %s' % (os.path.basename(remote), error))
+-                    os.unlink(path)
++                        my.logger.warning('Removing %s due to failed signature check: %s' % rpmfn)
++                    os.unlink(pkg.localpath)
++                    exit_code = 1
+                     continue
+ 
+-            if not os.path.exists(local) or not os.path.samefile(path, local):
+-                shutil.copy2(path, local)
+-
+     my.closeRpmDB()
++    sys.exit(exit_code)
+ 
+ if __name__ == "__main__":
+     main()
+diff --git a/repotrack.py b/repotrack.py
+index ed26b9f..6c6a18c 100755
+--- a/repotrack.py
++++ b/repotrack.py
+@@ -7,11 +7,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # (c) 2005 seth vidal skvidal at phy.duke.edu
+ 
+ 
+diff --git a/show-changed-rco.py b/show-changed-rco.py
+index 3489247..f314ef0 100755
+--- a/show-changed-rco.py
++++ b/show-changed-rco.py
+@@ -10,11 +10,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ import yum
+ 
+@@ -194,6 +194,21 @@ def main():
+     if opts.conffile is not None:
+         yb.preconf.fn = opts.conffile
+ 
++    # setup the fake repos
++    for repo in opts.repofrompath or []:
++        tmp = tuple(repo.split(','))
++        if len(tmp) != 2:
++            yb.logger.error("Error: Bad repofrompath argument: %s" %repo)
++            continue
++        repoid,repopath = tmp
++        if repopath[0] == '/':
++            baseurl = 'file://' + repopath
++        else:
++            baseurl = repopath
++        yb.add_enable_repo(repoid, baseurls=[baseurl],
++                           basecachedir=yb.conf.cachedir)
++        yb.logger.info("Added %s repo from %s" % (repoid, repopath))
++
+     if opts.cache:
+         yb.conf.cache = 1
+     elif not yb.setCacheDir():
+diff --git a/show-installed.py b/show-installed.py
+index 737f97e..65aae11 100755
+--- a/show-installed.py
++++ b/show-installed.py
+@@ -360,7 +360,7 @@ def __main__():
+                      choices=('kickstart','human','yum'), default="human",
+                      help='yum, kickstart or human; yum gives the result as a yum command line; kickstart the content of a %packages section; "human" readable is default.')
+     parser.add_option("-i", "--input", dest="input", action="store", default=None, help="File to read the package list from instead of using the rpmdb. - for stdin. The file must contain package names only separated by white space (including newlines). rpm -qa --qf='%{name}\\n' produces proper output.")
+-    parser.add_option("-o", "--output", dest="output", action="store", default=None, help="File to write the result to. Stdout is used if option is omited.")
++    parser.add_option("-o", "--output", dest="output", action="store", default=None, help="File to write the result to. Stdout is used if option is omitted.")
+     parser.add_option("-q", "--quiet", dest="quiet", action="store_true", help="Do not show warnings.")
+     parser.add_option("-e", "--no-excludes", dest="excludes",
+                       action="store_false", default=True,
+diff --git a/test/yum-utils-pylintrc b/test/yum-utils-pylintrc
+index 1a03789..def5613 100644
+--- a/test/yum-utils-pylintrc
++++ b/test/yum-utils-pylintrc
+@@ -1,6 +1,6 @@
+ # lint Python modules using external checkers.
+ # 
+-# This is the main checker controling the other ones and the reports
++# This is the main checker controlling the other ones and the reports
+ # generation. It is itself both a raw checker and an astng checker in order
+ # to:
+ # * handle message activation / deactivation at the module level
+@@ -101,12 +101,12 @@ include-ids=yes
+ # written in a file name "pylint_global.[txt|html]".
+ files-output=no
+ 
+-# Tells wether to display a full report or only the messages
++# Tells whether to display a full report or only the messages
+ reports=yes
+ 
+ # Python expression which should return a note less than 10 (10 is the highest
+ # note).You have access to the variables errors warning, statement which
+-# respectivly contain the number of errors / warnings messages and the total
++# respectively contain the number of errors / warnings messages and the total
+ # number of statements analyzed. This is used by the global evaluation report
+ # (R0004).
+ evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+@@ -187,7 +187,7 @@ bad-functions=input
+ # 
+ [VARIABLES]
+ 
+-# Tells wether we should check for unused import in __init__ files.
++# Tells whether we should check for unused import in __init__ files.
+ init-import=no
+ 
+ # A regular expression matching names used for dummy variables (i.e. not used).
+@@ -202,7 +202,7 @@ additional-builtins=
+ # 
+ [TYPECHECK]
+ 
+-# Tells wether missing members accessed in mixin class should be ignored. A
++# Tells whether missing members accessed in mixin class should be ignored. A
+ # mixin class is detected if its name ends with "mixin" (case insensitive).
+ ignore-mixin-members=yes
+ 
+@@ -246,7 +246,7 @@ int-import-graph=
+ # checks for :
+ # * methods without self as first argument
+ # * overridden methods signature
+-# * access only to existant members via self
++# * access only to existent members via self
+ # * attributes not defined in the __init__ method
+ # * supported interfaces implementation
+ # * unreachable code
+diff --git a/verifytree.py b/verifytree.py
+index d1fe5e2..78e8264 100755
+--- a/verifytree.py
++++ b/verifytree.py
+@@ -7,11 +7,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ # copyright (c) 2008 Red Hat, Inc - written by Seth Vidal and Will Woods
+ 
+ import yum
+@@ -130,6 +130,11 @@ def main():
+     
+     parser.add_option("-a","--checkall",action="store_true",default=False,
+             help="Check all packages in the repo")
++    parser.add_option("--nocomps", "--nogroups",action="store_true",
++                      default=False,
++            help="Do not read and check comps")
++    parser.add_option("--noplugins",action="store_true",default=False,
++            help="Do not load any plugins")
+     parser.add_option("-t","--testopia",action="store",type="int",
+             help="Report results to the given testopia run number")
+     parser.add_option("-r","--treeinfo", action="store_true", default=False,
+@@ -159,6 +164,8 @@ def main():
+     basedir = url.replace('file://', '') # for a normal path thing
+ 
+     my = yum.YumBase()
++    if opts.noplugins:
++        my.preconf.init_plugins = False
+     my.conf.cachedir = getCacheDir()
+     my.repos.disableRepo('*')
+     newrepo = yum.yumRepo.YumRepository(repoid)
+@@ -211,25 +218,26 @@ def main():
+     else:
+         report('REPODATA','PASSED')
+ 
+-    print "Checking groups (comps.xml):"
+-    try:
+-        print "  verifying comps.xml with yum"
+-        b = my.comps.compscount
+-    except Errors.GroupsError, e:
+-        print '  comps file missing or unparseable'
+-        report('COMPS','FAILED')
+-        retval = retval | BAD_COMPS
+-
+-    if not (retval & BAD_COMPS):
+-        print "  verifying comps.xml grammar with xmllint"
+-        comps = newrepo.getGroups()
+-        r = os.system("xmllint --noout --nowarning --relaxng %s %s" % 
+-            (SCHEMA,comps))
+-        if r != 0:
+-            retval = retval | BAD_COMPS
++    if not opts.nocomps:
++        print "Checking groups (comps.xml):"
++        try:
++            print "  verifying comps.xml with yum"
++            b = my.comps.compscount
++        except Errors.GroupsError, e:
++            print '  comps file missing or unparseable'
+             report('COMPS','FAILED')
+-        else:
+-            report('COMPS','PASSED')
++            retval = retval | BAD_COMPS
++
++        if not (retval & BAD_COMPS):
++            print "  verifying comps.xml grammar with xmllint"
++            comps = newrepo.getGroups()
++            r = os.system("xmllint --noout --nowarning --relaxng %s %s" % 
++                (SCHEMA,comps))
++            if r != 0:
++                retval = retval | BAD_COMPS
++                report('COMPS','FAILED')
++            else:
++                report('COMPS','PASSED')
+ 
+     # if we've got a .treeinfo file and we are told to check it, then do so
+     tr_path = basedir + '/.treeinfo'
+@@ -243,7 +251,7 @@ def main():
+     if opts.checkall:
+         print "Checking all packages"
+         sack = my.pkgSack
+-    elif not (retval & BAD_COMPS):
++    elif not (retval & BAD_COMPS or opts.nocomps):
+         print "Checking mandatory @core packages"
+         group = my.comps.return_group('core')
+         for pname in group.mandatory_packages:
+diff --git a/yum-builddep.py b/yum-builddep.py
+index d7a37c3..b9e682a 100755
+--- a/yum-builddep.py
++++ b/yum-builddep.py
+@@ -8,17 +8,18 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ import sys
+ sys.path.insert(0,'/usr/share/yum-cli')
+ 
+ import yum
+ from yum.misc import setup_locale
++from yum.i18n import exception2msg
+ import yum.Errors
+ from utils import YumUtilBase
+ 
+@@ -26,6 +27,8 @@ import logging
+ import rpmUtils
+ import rpm
+ 
++rhn_source_repos = False
++
+ # Copied from yumdownloader (need a yum-utils python module ;)
+ # This is to fix Bug 469
+ # To convert from a pkg to a source pkg, we have a problem in that all we have
+@@ -61,6 +64,9 @@ class YumBuildDep(YumUtilBase):
+         self.logger = logging.getLogger("yum.verbose.cli.yumbuildep")                             
+         # Add util commandline options to the yum-cli ones
+         self.optparser = self.getOptionParser() 
++        if hasattr(rpm, 'reloadConfig'):
++            self.optparser.add_option("--target",
++                              help="set target architecture for spec parsing")
+         self.main()
+ 
+     def main(self):
+@@ -118,9 +124,16 @@ class YumBuildDep(YumUtilBase):
+         # enable the -source repos for enabled primary repos
+         archlist = rpmUtils.arch.getArchList() + ['src']    
+         for repo in self.repos.listEnabled():
+-            if not repo.id.endswith('-source'):
++            issource_repo = repo.id.endswith('-source')
++            if rhn_source_repos and repo.id.endswith('-source-rpms'):
++                issource_repo = True
++            if rhn_source_repos and (not repo.id.endswith('-source-rpms') and
++                                     repo.id.endswith('-rpms')):
++                srcrepo = '%s-source,%s-source-rpms' % (repo.id, repo.id[:-5])
++            elif not issource_repo:
+                 srcrepo = '%s-source' % repo.id
+             else:
++                # Need to change the arch.
+                 repo.close()
+                 self.repos.disableRepo(repo.id)
+                 srcrepo = repo.id
+@@ -140,6 +153,7 @@ class YumBuildDep(YumUtilBase):
+                     sys.exit(1)
+ 
+     def install_deps(self, deplist):
++        errors = set()
+         for dep in deplist:
+             self.logger.debug(' REQ:  %s' % dep)                
+             if dep.startswith("rpmlib("): 
+@@ -152,10 +166,13 @@ class YumBuildDep(YumUtilBase):
+                 pkg = self.returnPackageByDep(dep)
+                 self.logger.info(' --> %s' % pkg)
+                 self.install(pkg)
+-                
+             except yum.Errors.YumBaseError, e:
+-                self.logger.error("Error: %s" % e)
+-                sys.exit(1)
++                errors.add(exception2msg(e))
++
++        if errors:
++            for i in sorted(errors):
++                self.logger.error("Error: %s" % i)
++            sys.exit(1)
+ 
+     # go through each of the pkgs, figure out what they are/where they are 
+     # if they are not a local package then run
+@@ -170,10 +187,14 @@ class YumBuildDep(YumUtilBase):
+         specnames = []
+         srpms = []
+         specworks = False
++        reloadworks = False
+ 
+         # See if we can use spec files for buildrequires
+         if hasattr(rpm, 'spec') and hasattr(rpm.spec, 'sourceHeader'):
+             specworks = True
++        # See if we can reload rpm configuration
++        if hasattr(rpm, 'reloadConfig'):
++            reloadworks = True
+ 
+         for arg in self.cmds:
+             if arg.endswith('.src.rpm'):
+@@ -206,22 +227,30 @@ class YumBuildDep(YumUtilBase):
+                     sys.exit(1)
+                     
+         toActOn = []
++        # Get the best matching srpms
+         for newpkg in srpms:
+-            toActOn.extend(_best_convert_pkg2srcpkgs(self, opts, newpkg))
+-        # Get the best matching srpm
+-        toActOn = self.bestPackagesFromList(toActOn, 'src')
++            srcpkg = _best_convert_pkg2srcpkgs(self, opts, newpkg)
++            toActOn.extend(self.bestPackagesFromList(srcpkg, 'src'))
+ 
+         for srpm in toActOn:
+             self.logger.info('Getting requirements for %s' % srpm)
+             self.install_deps(srpm.requiresList())
+     
+         for name in specnames:
++            # (re)load rpm config for target if set
++            if reloadworks and opts.target:
++                rpm.reloadConfig(opts.target)
++
+             try:
+                 spec = rpm.spec(name)
+             except ValueError:
+                 self.logger.error("Bad spec: %s" % name)
+                 continue
+ 
++            # reset default rpm config after each parse to avoid side-effects
++            if reloadworks:
++                rpm.reloadConfig()
++
+             buildreqs = []
+             for d in rpm.ds(spec.sourceHeader, 'requires'):
+                 buildreqs.append(d.DNEVR()[2:])
+diff --git a/yum-complete-transaction.py b/yum-complete-transaction.py
+index c5074ab..3a9f305 100755
+--- a/yum-complete-transaction.py
++++ b/yum-complete-transaction.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ import sys
+ sys.path.insert(0,'/usr/share/yum-cli')
+@@ -93,7 +93,7 @@ except ImportError:
+         return to_complete_items
+ 
+ class YumCompleteTransaction(YumUtilBase):
+-    NAME = 'yum-complete-transactions'
++    NAME = 'yum-complete-transaction'
+     VERSION = '1.0'
+     USAGE = """
+     yum-complete-transaction: completes unfinished yum transactions which occur due to error, failure
+@@ -115,7 +115,8 @@ class YumCompleteTransaction(YumUtilBase):
+         else:
+             self.optparser_grp = self.optparser
+         self.addCmdOptions()
+-        self.main()
++        try: self.main()
++        finally: self.unlock()
+ 
+     def clean_up_ts_files(self, timestamp, path, disable=False):
+ 
+diff --git a/yum-config-manager.py b/yum-config-manager.py
+index 50f5123..df90885 100755
+--- a/yum-config-manager.py
++++ b/yum-config-manager.py
+@@ -153,7 +153,7 @@ if (not args and not opts.addrepo) or 'main' in args:
+         ybc = yb.conf
+         writeRawConfigFile(fn, 'main', ybc.yumvar,
+                            ybc.cfg.options, ybc.iteritems, ybc.optionobj,
+-                           only)
++                           only=yb.main_setopts.items)
+ 
+ if opts.enable or opts.disable:
+     opts.save = True
+@@ -161,7 +161,8 @@ if opts.enable or opts.disable:
+         only = ['enabled']
+ 
+ if args:
+-    repos = yb.repos.findRepos(','.join(args))
++    repos = yb.repos.findRepos(','.join(args),
++                               name_match=True, ignore_case=True)
+ else:
+     repos = yb.repos.listEnabled()
+ 
+diff --git a/yum-debug-dump.py b/yum-debug-dump.py
+index 4653f3c..67d943f 100755
+--- a/yum-debug-dump.py
++++ b/yum-debug-dump.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ ## (c) 2008 Red Hat. Written by skvidal@fedoraproject.org
+ 
+ import os
+diff --git a/yum-debug-restore.py b/yum-debug-restore.py
+index fd95741..1d827f4 100755
+--- a/yum-debug-restore.py
++++ b/yum-debug-restore.py
+@@ -8,11 +8,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ ## (c) 2008 Red Hat. Written by skvidal@fedoraproject.org
+ ##                                james@fedoraproject.org
+ 
+@@ -107,11 +107,15 @@ def pkg_data2list(yb, opkgtups, opkgmaps, install_latest, ignore_arch):
+     ret = []
+     npkgtups = set()
+     npkgmaps = {}
++    installonly = set(yb.conf.installonlypkgs)
+     for po in sorted(yb.rpmdb.returnPackages()):
+         arch = po.arch
+         if ignore_arch:
+             arch = None
+         if False: pass
++        elif po.name in installonly:
++            if not po.pkgtup in opkgtups:
++                ret.append(("remove", pkgtup2str(po.pkgtup)))
+         elif (po.name, arch) not in opkgmaps:
+             ret.append(("remove", str(po)))
+         elif po.pkgtup not in opkgtups:
+@@ -129,6 +133,8 @@ def pkg_data2list(yb, opkgtups, opkgmaps, install_latest, ignore_arch):
+             npkgmaps[(po.name, None)] = po
+ 
+     for name, arch in sorted(opkgmaps):
++        if name in installonly:
++            continue # done separately
+         if ignore_arch and arch is not None:
+             continue
+         if (name, arch) in npkgmaps:
+@@ -139,6 +145,9 @@ def pkg_data2list(yb, opkgtups, opkgmaps, install_latest, ignore_arch):
+             ret.append(("install", "%s.%s" % (name, arch)))
+         else:
+             ret.append(("install", pkgtup2str(opkgmaps[(name, arch)])))
++    for pkgtup in opkgtups:
++        if pkgtup[0] in installonly and not pkgtup in npkgtups:
++            ret.append(("install", pkgtup2str(pkgtup)))
+     return ret
+ 
+ def main():
+@@ -223,10 +232,8 @@ def main():
+         sys.exit(0)
+ 
+     # Want to do the transaction, hacky method
+-    if xtra_args:
+-        os.system("yum shell %s %s" % (" ".join(xtra_args), fo.name))
+-    else:
+-        os.system("yum shell %s" % fo.name)
++    xtra_args.append('--setopt=installonly_limit=0')
++    os.system("yum shell %s %s" % (" ".join(xtra_args), fo.name))
+ 
+ if __name__ == "__main__":
+     main()
+diff --git a/yum-groups-manager.py b/yum-groups-manager.py
+index 2cf73c8..c536092 100755
+--- a/yum-groups-manager.py
++++ b/yum-groups-manager.py
+@@ -204,7 +204,7 @@ def main():
+             sys.exit(50)
+ 
+     if not loaded_files and opts.remove:
+-        yb.logger.error("Can't remove package(s) when we havn't loaded any")
++        yb.logger.error("Can't remove package(s) when we haven't loaded any")
+         sys.exit(50)
+ 
+     group = None
+@@ -213,7 +213,7 @@ def main():
+     if group is None and opts.name:
+         group = comps.return_group(opts.name)
+     if group is None and opts.remove:
+-        yb.logger.error("Can't remove package(s) from non-existant group")
++        yb.logger.error("Can't remove package(s) from non-existent group")
+         sys.exit(50)
+ 
+     if group is None:
+diff --git a/yum-util-cli-template b/yum-util-cli-template
+index 8bfdbcd..250ebc9 100644
+--- a/yum-util-cli-template
++++ b/yum-util-cli-template
+@@ -7,7 +7,7 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software
+diff --git a/yum-utils.bash b/yum-utils.bash
+index 1d37231..65bff76 100644
+--- a/yum-utils.bash
++++ b/yum-utils.bash
+@@ -1,3 +1,6 @@
++# need functions from yum.bash
++type -t _yum >/dev/null || . $(pkg-config --variable=completionsdir bash-completion)/yum
++
+ # bash completion for yum-utils
+ 
+ _yu_init_completion()
+@@ -100,7 +103,7 @@ _yu_repo_graph()
+             return 0
+             ;;
+         --repoid)
+-            _yum_repolist all "$cur" 2>/dev/null
++            _yum_helper repolist all "$cur" 2>/dev/null
+             return 0
+             ;;
+         -c)
+@@ -136,7 +139,7 @@ _yu_repo_rss()
+ 
+     COMPREPLY=( $( compgen -W '--help -f -l -t -d -r --tempcache -g -a -c' \
+         -- "$2" ) )
+-    [[ $2 == -* ]] || _yum_repolist all "$2" 2>/dev/null || return 0
++    [[ $2 == -* ]] || _yum_helper repolist all "$2" 2>/dev/null || return 0
+ } &&
+ complete -F _yu_repo_rss -o filenames repo-rss repo-rss.py
+ 
+@@ -155,7 +158,7 @@ _yu_repoclosure()
+             return 0
+             ;;
+         -l|--lookaside|-r|--repoid)
+-            _yum_repolist all "$cur" 2>/dev/null
++            _yum_helper repolist all "$cur" 2>/dev/null
+             return 0
+             ;;
+         -p|--pkg)
+@@ -163,7 +166,7 @@ _yu_repoclosure()
+             return 0
+             ;;
+         -g|--group)
+-            _yum_grouplist "" "$cur" 2>/dev/null
++            _yum_helper groups list all "$cur" 2>/dev/null
+             return 0
+             ;;
+     esac
+@@ -188,26 +191,23 @@ _yu_repoquery()
+     done
+ 
+     case $prev in
+-        -h|--help|--version|-f|--file|--qf|--queryformat|--resolve|--archlist|\
+-        --whatprovides|--whatrequires|--whatobsoletes|--whatconflicts|\
+-        --repofrompath|--level|--search-fields)
++        -h|--help|--version|--qf|--queryformat|--archlist|--repofrompath|\
++        --setopt)
++            return 0
++            ;;
++        -f|--file)
++            COMPREPLY=( $( compgen -f -o plusdirs -- "$cur" ) )
+             return 0
+             ;;
+         -l|--list|-i|--info|-R|--requires)
+             if $groupmode ; then
+-                _yum_grouplist "" "$cur" 2>/dev/null
++                _yum_helper groups list all "$cur" 2>/dev/null
+             else
+                 declare -F _yum_atgroups &>/dev/null && \
+                     _yum_atgroups "$cur" || _yum_list all "$cur" 2>/dev/null
+             fi
+             return 0
+             ;;
+-        --provides|--obsoletes|--conflicts|--groupmember|--changelog|\
+-        --location|--nevra|--envra|--nvr|-s|--source)
+-            declare -F _yum_atgroups &>/dev/null && \
+-                _yum_atgroups "$cur" || _yum_list all "$cur" 2>/dev/null
+-            return 0
+-            ;;
+         --grouppkgs)
+             COMPREPLY=( $( compgen -W 'all default optional mandatory' \
+                 -- "$cur" ) )
+@@ -219,38 +219,56 @@ _yu_repoquery()
+             return 0
+             ;;
+         --repoid)
+-            _yum_repolist all "$cur" 2>/dev/null
++            _yum_helper repolist all "$cur" 2>/dev/null
+             return 0
+             ;;
+         --enablerepo)
+-            _yum_repolist disabled "$cur" 2>/dev/null
++            _yum_helper repolist disabled "$cur" 2>/dev/null
+             return 0
+             ;;
+         --disablerepo)
+-            _yum_repolist enabled "$cur" 2>/dev/null
++            _yum_helper repolist enabled "$cur" 2>/dev/null
+             return 0
+             ;;
+         -c|--config)
+             COMPREPLY=( $( compgen -f -o plusdirs -X '!*.conf' -- "$cur" ) )
+             return 0
+             ;;
++        --level)
++            COMPREPLY=( $( compgen -W '{1..9} all' -- "$cur" ) )
++            return 0
++            ;;
+         --output)
+             COMPREPLY=( $( compgen -W 'text ascii-tree dot-tree' -- "$cur" ) )
+             return 0
+             ;;
++        --search-fields)
++            COMPREPLY=( $( compgen -W 'name summary description' -- "$cur" ) )
++            return 0
++            ;;
++        --installroot)
++            COMPREPLY=( $( compgen -d -- "$cur" ) )
++            return 0
++            ;;
+     esac
+ 
+     $split && return 0
+ 
+-    COMPREPLY=( $( compgen -W '--version --help --list --info --file
+-        --queryformat --groupmember --all --requires --provides --obsoletes
+-        --conflicts --changelog --location --nevra --envra --nvr --source
+-        --srpm --resolve --exactdeps --recursive --whatprovides --whatrequires
+-        --whatobsoletes --whatconflicts --group --grouppkgs --archlist
+-        --pkgnarrow --installed --show-duplicates --repoid --enablerepo
+-        --disablerepo --repofrompath --plugins --quiet --verbose --cache
+-        --tempcache --querytags --config --level --output --search
+-        --search-fields' -- "$cur" ) )
++    if [[ $cur == -* ]] ; then
++        COMPREPLY=( $( compgen -W '--version --help --list --info --file
++            --queryformat --groupmember --all --requires --provides --obsoletes
++            --conflicts --changelog --location --nevra --envra --nvr --source
++            --srpm --resolve --exactdeps --recursive --whatprovides
++            --whatrequires --whatobsoletes --whatconflicts --group --grouppkgs
++            --archlist --pkgnarrow --installed --show-duplicates --repoid
++            --enablerepo --disablerepo --repofrompath --plugins --quiet
++            --verbose --cache --tempcache --querytags --config --level --output
++            --search --search-fields --setopt --installroot' -- "$cur" ) )
++        return 0
++    fi
++
++    declare -F _yum_atgroups &>/dev/null && \
++        _yum_atgroups "$cur" || _yum_list all "$cur" 2>/dev/null
+ } &&
+ complete -F _yu_repoquery -o filenames repoquery repoquery.py
+ 
+@@ -278,8 +296,8 @@ _yu_yumdb()
+ 
+     if [ $COMP_CWORD -le 1 ] ; then
+         COMPREPLY=( $( compgen -W 'get set del rename rename-force copy search
+-            exist unset info shell --version --help --noplugins --config' \
+-                -- "$cur" ) )
++            exist unset info sync undeleted shell --version --help --noplugins
++            --config' -- "$cur" ) )
+     fi
+ } &&
+ complete -F _yu_yumdb -o filenames yumdb yumdb.py
+@@ -299,7 +317,7 @@ _yu_repodiff()
+     $split && return 0
+ 
+     COMPREPLY=( $( compgen -W '--version --help --new --old --quiet --archlist
+-        --size --simple' -- "$cur" ) )
++        --compare-arch --size --downgrade --simple' -- "$cur" ) )
+ } &&
+ complete -F _yu_repodiff repodiff repodiff.py
+ 
+@@ -311,6 +329,13 @@ _yu_builddep()
+ 
+     _yum_complete_baseopts "$cur" "$prev" && return 0
+ 
++    case $prev in
++        --target)
++            declare -F _rpm_buildarchs &>/dev/null && _rpm_buildarchs
++            return 0
++            ;;
++    esac
++
+     $split && return 0
+ 
+     if [[ $cur == -* ]] ; then
+@@ -363,6 +388,36 @@ _yu_debug_dump()
+ } &&
+ complete -F _yu_debug_dump -o filenames yum-debug-dump yum-debug-dump.py
+ 
++# yumdownloader
++_yu_yumdownloader()
++{
++    local cur prev words=() split=false
++    _yu_init_completion "$2" "$3"
++
++    _yum_complete_baseopts "$cur" "$prev" 2>/dev/null && return 0
++
++    case $prev in
++        --destdir)
++            COMPREPLY=( $( compgen -d -- "$cur" ) )
++            return 0
++            ;;
++        --archlist)
++            return 0
++            ;;
++    esac
++
++    $split && return 0
++
++    if [[ $cur == -* ]] ; then
++        COMPREPLY=( $( compgen -W '$( _yum_baseopts 2>/dev/null ) --destdir
++            --urls --resolve --source --archlist' -- "$cur" ) )
++        return 0
++    fi
++
++    _yum_list all "$cur"
++} &&
++complete -F _yu_yumdownloader -o filenames yumdownloader yumdownloader.py
++
+ # Local variables:
+ # mode: shell-script
+ # sh-basic-offset: 4
+diff --git a/yum-utils.spec b/yum-utils.spec
+index ce7fb64..e22d692 100644
+--- a/yum-utils.spec
++++ b/yum-utils.spec
+@@ -1,4 +1,11 @@
++%if 0%{?rhel}
++%define package_yum_updatesd 0
++%else
++%define package_yum_updatesd 1
++%endif
++
+ %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
++%define pluginhome /usr/lib/yum-plugins
+ 
+ Summary: Utilities based around the yum package manager
+ Name: yum-utils
+@@ -10,7 +17,8 @@ Source: http://yum.baseurl.org/download/yum-utils/%{name}-%{version}.tar.gz
+ URL: http://yum.baseurl.org/download/yum-utils/
+ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+ BuildArch: noarch
+-Requires: yum >= 3.2.29
++# For new findRepos() API.
++Requires: yum >= 3.4.3-96
+ Requires: python-kitchen
+ BuildRequires: python-devel >= 2.4
+ BuildRequires: gettext
+@@ -105,18 +113,6 @@ Requires: yum >= 3.0
+ This plugin allows you to specify optional transaction flags on the yum
+ command line
+ 
+-%package -n yum-plugin-downloadonly
+-Summary: Yum plugin to add downloadonly command option
+-Group: System Environment/Base
+-Provides: yum-downloadonly = %{version}-%{release}
+-Obsoletes: yum-downloadonly < 1.1.20-0
+-Conflicts: yum-downloadonly < 1.1.20-0
+-Requires: yum >= 3.0
+-
+-%description -n yum-plugin-downloadonly
+-This plugin adds a --downloadonly flag to yum so that yum will only download
+-the packages and not install/update them.
+-
+ %package -n yum-plugin-priorities
+ Summary: plugin to give priorities to packages from different repos
+ Group: System Environment/Base
+@@ -130,6 +126,7 @@ This plugin allows repositories to have different priorities.
+ Packages in a repository with a lower priority can't be overridden by packages
+ from a repository with a higher priority even if repo has a later version.
+ 
++%if %{package_yum_updatesd}
+ %package -n yum-plugin-refresh-updatesd
+ Summary: Tell yum-updatesd to check for updates when yum exits
+ Group: System Environment/Base
+@@ -143,6 +140,7 @@ Requires: yum-updatesd
+ yum-refresh-updatesd tells yum-updatesd to check for updates when yum exits.
+ This way, if you run 'yum update' and install all available updates, puplet
+ will almost instantly update itself to reflect this.
++%endif
+ 
+ %package -n yum-plugin-merge-conf
+ Summary: Yum plugin to merge configuration changes when installing packages
+@@ -290,7 +288,7 @@ This plugin allows the user to run arbitrary actions immediately following a
+ transaction when specified packages are changed.
+ 
+ %package -n yum-NetworkManager-dispatcher
+-Summary: NetworkManager script which tells yum to check it's cache on network change
++Summary: NetworkManager script which tells yum to check its cache on network change
+ Group: System Environment/Base
+ Requires: yum >= 3.2.17
+ 
+@@ -395,9 +393,7 @@ plugins="\
+  protectbase \
+  versionlock \
+  tsflags \
+- downloadonly \
+  priorities \
+- refresh-updatesd \
+  merge-conf \
+  security \
+  upgrade-helper \
+@@ -418,14 +414,20 @@ plugins="\
+  puppetverify \
+ "
+ 
+-mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/yum/pluginconf.d/ $RPM_BUILD_ROOT/usr/lib/yum-plugins/
++%if %{package_yum_updatesd}
++plugins="$plugins \
++ refresh-updatesd \
++"
++%endif
++
++mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/yum/pluginconf.d/ $RPM_BUILD_ROOT/%pluginhome
+ mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/yum/post-actions
+ 
+ cd plugins
+ for plug in $plugins; do
+     install -m 644 $plug/*.conf $RPM_BUILD_ROOT/%{_sysconfdir}/yum/pluginconf.d/
+-    install -m 644 $plug/*.py $RPM_BUILD_ROOT/usr/lib/yum-plugins/
+-    %{__python} -c "import compileall; compileall.compile_dir('$RPM_BUILD_ROOT/usr/lib/yum-plugins', 1)"
++    install -m 644 $plug/*.py $RPM_BUILD_ROOT/%pluginhome
++    %{__python} -c "import compileall; compileall.compile_dir('$RPM_BUILD_ROOT/%pluginhome', 1)"
+ done
+ install -m 644 aliases/aliases $RPM_BUILD_ROOT/%{_sysconfdir}/yum/aliases.conf
+ install -m 644 versionlock/versionlock.list $RPM_BUILD_ROOT/%{_sysconfdir}/yum/pluginconf.d/
+@@ -469,8 +471,8 @@ fi
+ %{_bindir}/yum-builddep
+ %{_bindir}/yum-config-manager
+ %{_bindir}/yum-debug-dump
+-%{_bindir}/yum-groups-manager
+ %{_bindir}/yum-debug-restore
++%{_bindir}/yum-groups-manager
+ %{_bindir}/show-installed
+ %{_bindir}/show-changed-rco
+ %{_sbindir}/yum-complete-transaction
+@@ -487,10 +489,19 @@ fi
+ %{_mandir}/man1/show-installed.1.*
+ %{_mandir}/man1/yum-builddep.1.*
+ %{_mandir}/man1/yum-debug-dump.1.*
++%{_mandir}/man1/yum-debug-restore.1.*
+ %{_mandir}/man8/yum-complete-transaction.8.*
+ %{_mandir}/man1/yum-groups-manager.1.*
+ %{_mandir}/man8/yumdb.8.*
+ %{_mandir}/man1/yumdownloader.1.*
++%{_mandir}/man1/find-repos-of-install.1.*
++%{_mandir}/man1/needs-restarting.1.*
++%{_mandir}/man1/repo-graph.1.*
++%{_mandir}/man1/repoclosure.1.*
++%{_mandir}/man1/repomanage.1.*
++%{_mandir}/man1/repotrack.1.*
++%{_mandir}/man1/verifytree.1.*
++%{_mandir}/man1/yum-config-manager.1.*
+ 
+ %files -n yum-updateonboot
+ %defattr(-, root, root)
+@@ -502,7 +513,7 @@ fi
+ %defattr(-, root, root)
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/changelog.conf
+ %doc COPYING
+-/usr/lib/yum-plugins/changelog.*
++%{pluginhome}/changelog.*
+ %{_mandir}/man1/yum-changelog.1.*
+ %{_mandir}/man5/yum-changelog.conf.5.*
+ 
+@@ -510,20 +521,20 @@ fi
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/fastestmirror.conf
+-/usr/lib/yum-plugins/fastestmirror*.*
++%{pluginhome}/fastestmirror*.*
+ 
+ %files -n yum-plugin-protectbase
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/protectbase.conf
+-/usr/lib/yum-plugins/protectbase.*
++%{pluginhome}/protectbase.*
+ 
+ %files -n yum-plugin-versionlock
+ %defattr(-, root, root)
+ %doc plugins/versionlock/README COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/versionlock.conf
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/versionlock.list
+-/usr/lib/yum-plugins/versionlock.*
++%{pluginhome}/versionlock.*
+ %{_mandir}/man1/yum-versionlock.1.*
+ %{_mandir}/man5/yum-versionlock.conf.5.*
+ 
+@@ -531,85 +542,81 @@ fi
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/tsflags.conf
+-/usr/lib/yum-plugins/tsflags.*
+-
+-%files -n yum-plugin-downloadonly
+-%defattr(-, root, root)
+-%doc COPYING
+-%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/downloadonly.conf
+-/usr/lib/yum-plugins/downloadonly.*
++%{pluginhome}/tsflags.*
+ 
+ %files -n yum-plugin-priorities
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/priorities.conf
+-/usr/lib/yum-plugins/priorities.*
++%{pluginhome}/priorities.*
+ 
++%if %{package_yum_updatesd}
+ %files -n yum-plugin-refresh-updatesd
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/refresh-updatesd.conf
+-/usr/lib/yum-plugins/refresh-updatesd.*
++%{pluginhome}/refresh-updatesd.*
++%endif
+ 
+ %files -n yum-plugin-merge-conf
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/merge-conf.conf
+-/usr/lib/yum-plugins/merge-conf.*
++%{pluginhome}/merge-conf.*
+ 
+ %files -n yum-plugin-security
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/security.conf
+-/usr/lib/yum-plugins/security.*
++%{pluginhome}/security.*
+ %{_mandir}/man8/yum-security.8.*
+ 
+ %files -n yum-plugin-upgrade-helper
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/upgrade-helper.conf
+-/usr/lib/yum-plugins/upgrade-helper.*
++%{pluginhome}/upgrade-helper.*
+ 
+ %files -n yum-plugin-aliases
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/aliases.conf
+ %config(noreplace) %{_sysconfdir}/yum/aliases.conf
+-/usr/lib/yum-plugins/aliases.*
++%{pluginhome}/aliases.*
+ %{_mandir}/man1/yum-aliases.1.*
+ 
+ %files -n yum-plugin-list-data
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/list-data.conf
+-/usr/lib/yum-plugins/list-data.*
++%{pluginhome}/list-data.*
+ %{_mandir}/man1/yum-list-data.1.*
+ 
+ %files -n yum-plugin-filter-data
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/filter-data.conf
+-/usr/lib/yum-plugins/filter-data.*
++%{pluginhome}/filter-data.*
+ %{_mandir}/man1/yum-filter-data.1.*
+ 
+ %files -n yum-plugin-tmprepo
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/tmprepo.conf
+-/usr/lib/yum-plugins/tmprepo.*
++%{pluginhome}/tmprepo.*
+ 
+ %files -n yum-plugin-verify
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/verify.conf
+-/usr/lib/yum-plugins/verify.*
++%{pluginhome}/verify.*
+ %{_mandir}/man1/yum-verify.1.*
+ 
+ %files -n yum-plugin-keys
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/keys.conf
+-/usr/lib/yum-plugins/keys.*
++%{pluginhome}/keys.*
+ 
+ %files -n yum-NetworkManager-dispatcher
+ %defattr(-, root, root)
+@@ -619,13 +626,13 @@ fi
+ %files -n yum-plugin-remove-with-leaves
+ %defattr(-, root, root)
+ %doc COPYING
+-/usr/lib/yum-plugins/remove-with-leaves.*
++%{pluginhome}/remove-with-leaves.*
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/remove-with-leaves.conf
+ 
+ %files -n yum-plugin-post-transaction-actions
+ %defattr(-, root, root)
+ %doc COPYING
+-/usr/lib/yum-plugins/post-transaction-actions.*
++%{pluginhome}/post-transaction-actions.*
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/post-transaction-actions.conf
+ %doc plugins/post-transaction-actions/sample.action
+ # Default *.action file dropping dir.
+@@ -634,19 +641,19 @@ fi
+ %files -n yum-plugin-rpm-warm-cache
+ %defattr(-, root, root)
+ %doc COPYING
+-/usr/lib/yum-plugins/rpm-warm-cache.*
++%{pluginhome}/rpm-warm-cache.*
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/rpm-warm-cache.conf
+ 
+ %files -n yum-plugin-auto-update-debug-info
+ %defattr(-, root, root)
+ %doc COPYING
+-/usr/lib/yum-plugins/auto-update-debuginfo.*
++%{pluginhome}/auto-update-debuginfo.*
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/auto-update-debuginfo.conf
+ 
+ %files -n yum-plugin-show-leaves
+ %defattr(-, root, root)
+ %doc COPYING
+-/usr/lib/yum-plugins/show-leaves.*
++%{pluginhome}/show-leaves.*
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/show-leaves.conf
+ 
+ %files -n yum-plugin-local
+@@ -654,13 +661,13 @@ fi
+ %doc COPYING
+ %ghost %{_sysconfdir}/yum.repos.d/_local.repo
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/local.conf
+-/usr/lib/yum-plugins/local.*
++%{pluginhome}/local.*
+ 
+ %files -n yum-plugin-fs-snapshot
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/fs-snapshot.conf
+-/usr/lib/yum-plugins/fs-snapshot.*
++%{pluginhome}/fs-snapshot.*
+ %{_mandir}/man1/yum-fs-snapshot.1.*
+ %{_mandir}/man5/yum-fs-snapshot.conf.5.*
+ 
+@@ -668,13 +675,13 @@ fi
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/ps.conf
+-/usr/lib/yum-plugins/ps.*
++%{pluginhome}/ps.*
+ 
+ %files -n yum-plugin-puppetverify
+ %defattr(-, root, root)
+ %doc COPYING
+ %config(noreplace) %{_sysconfdir}/yum/pluginconf.d/puppetverify.conf
+-/usr/lib/yum-plugins/puppetverify.*
++%{pluginhome}/puppetverify.*
+ 
+ %changelog
+ * Thu Aug 10 2011 Tim Lauridsen <timlau@fedoraproject.org> 
+diff --git a/yumdb.py b/yumdb.py
+index 8a4888e..c50159e 100755
+--- a/yumdb.py
++++ b/yumdb.py
+@@ -7,8 +7,24 @@ import fnmatch
+ import yum
+ import shlex
+ 
++import os
++import glob
++
+ parser = None
+ 
++# FIXME: Internal knowledge
++def _load_all_package_paths(db_path):
++    # glob the path and get a dict of pkgs to their subdir
++    glb = '%s/*/*/' % db_path
++    pkgdirs = glob.glob(glb)
++    _packages = {}
++    for d in pkgdirs:
++        if d[-1] == '/':
++            d = d[:-1]
++        pkgid = os.path.basename(d).split('-')[0]
++        _packages[pkgid] = d
++    return _packages
++
+ def setup_opts():
+     version = "0.0.1"
+     vers_txt = "Manage yum groups metadata version %s" % version
+@@ -25,6 +41,7 @@ def setup_opts():
+       unset?        <key> [pkg-wildcard]...
+       info          [pkg-wildcard]...
+       sync          [pkg-wildcard]...
++      undeleted
+       shell         [filename]...
+ """
+     parser =  optparse.OptionParser(usage = usage_txt, version = vers_txt)
+@@ -99,8 +116,8 @@ def run_cmd(yb, args, inshell=False):
+                 delattr(pkg.yumdb_info, ykey)
+             print pkg
+             print " " * 4, ykey, '<unset>'
+-    elif args[0] == 'search' and len(args) > 2:
+-        args.pop(0)
++    elif args[0] in ('search', 'search-q', 'search-quiet') and len(args) > 2:
++        cmd = args.pop(0)
+         ykey = args.pop(0)
+         done = False
+         # Maybe need some API so we don't have to load everything?
+@@ -115,10 +132,11 @@ def run_cmd(yb, args, inshell=False):
+                     break
+             if not found:
+                 continue
+-            if done: print ''
++            if done and cmd == 'search': print ''
+             done = True
+             print pkg
+-            print " " * 4, ykey, '=', yval
++            if cmd == 'search':
++                print " " * 4, ykey, '=', yval
+     elif args[0] in ['exist?', 'exist', 'exists'] and len(args) > 1:
+         args.pop(0)
+         ykey = args.pop(0)
+@@ -183,6 +201,14 @@ def run_cmd(yb, args, inshell=False):
+                 if ykey not in ndata:
+                     continue
+                 print " " * 4, ykey, '=', getattr(pkg.yumdb_info, ykey)
++    elif args[0] == 'undeleted':
++        yumdb_packages = _load_all_package_paths(yb.rpmdb.yumdb.conf.db_path)
++        for pkg in sorted(yb.rpmdb.returnPackages()):
++            if pkg.pkgid in yumdb_packages:
++                del yumdb_packages[pkg.pkgid]
++        for pkgid in yumdb_packages:
++            print "%s: %s" % (pkgid, yumdb_packages[pkgid])
++
+     elif args[0] == 'shell' and not inshell:
+         args.pop(0)
+         if args:
+diff --git a/yumdownloader.py b/yumdownloader.py
+index e6107d4..4c5eefb 100755
+--- a/yumdownloader.py
++++ b/yumdownloader.py
+@@ -7,11 +7,11 @@
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU Library General Public License for more details.
++# GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ import sys
+ import os
+@@ -22,6 +22,7 @@ import yum
+ from yum.misc import setup_locale
+ from yum.packages import parsePackages
+ from yum.Errors import RepoError
++from yum.i18n import exception2msg
+ from utils import YumUtilBase
+ 
+ from urlparse import urljoin
+@@ -31,6 +32,8 @@ import shutil
+ import rpmUtils
+ import logging
+ 
++rhn_source_repos = False
++
+ # This is to fix Bug 469
+ # To convert from a pkg to a source pkg, we have a problem in that all we have
+ # is "sourcerpm", which can be a different nevra ... but just to make it fun
+@@ -68,7 +71,11 @@ class YumDownloader(YumUtilBase):
+                           
+         # Add util commandline options to the yum-cli ones
+         self.optparser = self.getOptionParser() 
+-        self.main()
++        try:
++            self.main()
++        except (OSError, IOError), e:
++            self.logger.error(exception2msg(e))
++            sys.exit(1)
+ 
+     def main(self):
+         # Add command line option specific to yumdownloader
+@@ -77,7 +84,7 @@ class YumDownloader(YumUtilBase):
+         try:
+             opts = self.doUtilConfigSetup()
+         except yum.Errors.RepoError, e:
+-            self.logger.error(str(e))
++            self.logger.error(exception2msg(e))
+             sys.exit(50)
+                 
+         # Check if there is anything to do.
+@@ -92,53 +99,27 @@ class YumDownloader(YumUtilBase):
+             
+         # Setup yum (Ts, RPM db, Repo & Sack)
+         self.doUtilYumSetup(opts)
+-        # Setup source repos
+-        if opts.source:
+-            self.setupSourceRepos()
+         # Do the real action
+         self.exit_code = self.downloadPackages(opts)
+         
+     def setupSourceRepos(self):
+         # enable the -source repos for enabled primary repos
+-        archlist = rpmUtils.arch.getArchList() + ['src']    
+-        # Ok, we have src and bin repos. What we want to do here is:
+-        #
+-        # 1. _enable_ source repos for which the bin repos are enabled.
+-        # 2. _disable_ the _other_ src repos.
+-        #
+-        # ...also we don't want to disable the src repos. for #1 and then
+-        # re-enable them as then we get annoying messages and call .close() on
+-        # them losing the primarydb data etc.
+ 
+-        # Get all src repos.
+-        src_repos = {}
+-        for repo in self.repos.findRepos('*-source'):
+-            src_repos[repo.id] = False
++        enabled = {}
++        for repo in self.repos.findRepos('*'):
++            enabled[repo.id] = repo.isEnabled()
+ 
+-        #  Find the enabled bin repos, and mark their respective *-source repo.
+-        # as good.
+-        for repo in self.repos.listEnabled():
+-            if repo.id not in src_repos:
+-                srcrepo = '%s-source' % repo.id
+-                if srcrepo in src_repos:
+-                    src_repos[srcrepo] = True
++        for repo in self.repos.findRepos('*'):
++            if repo.id.endswith('-source'):
++                primary = repo.id[:-7]
++            elif rhn_source_repos and repo.id.endswith('-source-rpms'):
++                primary = repo.id[:-12] + '-rpms'
++            else:
++                continue
+ 
+-        # Toggle src repos that are set the wrong way
+-        for repo in self.repos.findRepos('*-source'):
+-            if     repo.isEnabled() and not src_repos[repo.id]:
+-                repo.close()
+-                self.repos.disableRepo(repo.id)
+-            if not repo.isEnabled() and     src_repos[repo.id]:
++            if not repo.isEnabled() and enabled.get(primary):
+                 self.logger.info('Enabling %s repository' % repo.id)
+                 repo.enable()
+-                # Setup the repo, without a cache
+-                repo.setup(0)
+-                try:
+-                    # Setup pkgSack with 'src' in the archlist
+-                    self._getSacks(archlist=archlist, thisrepo=repo.id)
+-                except yum.Errors.YumBaseError, msg:
+-                    self.logger.critical(str(msg))
+-                    sys.exit(1)
+         
+     def downloadPackages(self,opts):
+         
+@@ -177,7 +158,7 @@ class YumDownloader(YumUtilBase):
+                     installable = self.returnPackagesByDep(pkg)
+                     installable = yum.misc.unique(installable)
+                 except yum.Errors.YumBaseError, msg:
+-                    self.logger.error(str(msg))
++                    self.logger.error(exception2msg(msg))
+                     continue
+ 
+             if not installable: # doing one at a time, apart from groups
+@@ -211,57 +192,35 @@ class YumDownloader(YumUtilBase):
+             self.resolveDeps()
+             # Add newly added packages to the toDownload list
+             for pkg in self.tsInfo.getMembers():
+-                if not pkg in toDownload:
+-                    toDownload.append(pkg)
++                if pkg.ts_state in ('i', 'u') and pkg.po not in toDownload:
++                    toDownload.append(pkg.po)
+         if len(toDownload) == 0:
+             self.logger.error('Nothing to download')
+             sys.exit(1)
++        if opts.urls:
++            for pkg in toDownload:
++                print urljoin(pkg.repo.urls[0], pkg.relativepath)
++            return 0
+ 
+-        exit_code = 0
++        # create dest dir
++        if not os.path.exists(opts.destdir):
++            os.makedirs(opts.destdir)
++
++        # set localpaths
+         for pkg in toDownload:
+-            n,a,e,v,r = pkg.pkgtup
+-            packages =  self.pkgSack.searchNevra(n,e,v,r,a)
+-            packages.sort()
+-            last = None
+-            for download in packages:
+-                if download.pkgtup == last :
+-                    continue
+-                last = download.pkgtup
+-                repo = self.repos.getRepo(download.repoid)
+-                remote = download.returnSimple('relativepath')
+-                if opts.urls:
+-                    url = urljoin(repo.urls[0]+'/',remote)
+-                    self.logger.info('%s' % url)
+-                    continue
+-                local = os.path.basename(remote)
+-                if not os.path.exists(opts.destdir):
+-                    os.makedirs(opts.destdir)
+-                local = os.path.join(opts.destdir, local)
+-                if (os.path.exists(local) and 
+-                    os.path.getsize(local) == int(download.returnSimple('packagesize'))):
+-                    self.logger.error("%s already exists and appears to be complete" % local)
+-                    continue
+-                # Disable cache otherwise things won't download
+-                repo.cache = 0
+-                download.localpath = local # Hack: to set the localpath we want.
+-                try:
+-                    checkfunc = (self.verifyPkg, (download, 1), {})
+-                    path = repo.getPackage(download, checkfunc=checkfunc)
+-                except IOError, e:
+-                    self.logger.error("Cannot write to file %s. Error was: %s" % (local, e))
+-                    exit_code = 2
+-                    continue
+-                except RepoError, e:
+-                    self.logger.error("Could not download/verify pkg %s: %s" % (download, e))
+-                    exit_code = 2
+-                    continue
+-    
+-                if not os.path.exists(local) or not os.path.samefile(path, local):
+-                    progress = TextMeter()
+-                    progress.start(basename=os.path.basename(local),
+-                                   size=os.stat(path).st_size)
+-                    shutil.copy2(path, local)
+-                    progress.end(progress.size)
++            rpmfn = os.path.basename(pkg.remote_path)
++            pkg.localpath = os.path.join(opts.destdir, rpmfn)
++            pkg.repo.copy_local = True
++            pkg.repo.cache = 0
++
++        # use downloader from YumBase
++        exit_code = 0
++        probs = self.downloadPkgs(toDownload)
++        if probs:
++            exit_code = 2
++            for key in probs:
++                for error in probs[key]:
++                    self.logger.error('%s: %s', key, error)
+         return exit_code
+                     
+     def _groupPackages(self,pkglist):
+@@ -279,6 +238,9 @@ class YumDownloader(YumUtilBase):
+         """do a default setup for all the normal/necessary yum components,
+            really just a shorthand for testing"""
+         try:
++            # Setup source repos
++            if opts.source:
++                self.setupSourceRepos()
+             self._getRepos(doSetup = True)
+             # if '--source' is used the add src to the archlist
+             if opts.source:
+@@ -291,18 +253,11 @@ class YumDownloader(YumUtilBase):
+                 archlist = rpmUtils.arch.getArchList()
+             self._getSacks(archlist=archlist)
+         except yum.Errors.YumBaseError, msg:
+-            self.logger.critical(str(msg))
++            self.logger.critical(exception2msg(msg))
+             sys.exit(1)
+ 
+-    def _removeEnabledSourceRepos(self):
+-        ''' Disable all enabled *-source repos.'''
+-        for repo in self.repos.listEnabled():
+-            if repo.id.endswith('-source'):
+-                repo.close()
+-                self.repos.disableRepo(repo.id)
+-
+     def addCmdOptions(self):
+-        # this if for compability with old API (utils.py from yum < 3.2.23)
++        # this if for compatibility with old API (utils.py from yum < 3.2.23)
+         if hasattr(self,'getOptionGroup'): # check if the group option API is available
+             group = self.getOptionGroup()
+         else:
diff --git a/SPECS/yum-utils.spec b/SPECS/yum-utils.spec
new file mode 100644
index 0000000..0d479fc
--- /dev/null
+++ b/SPECS/yum-utils.spec
@@ -0,0 +1,1241 @@
+%define package_puppetverify 0
+
+%if 0%{?rhel}
+%define package_yum_updatesd 0
+%else
+%define package_yum_updatesd 1
+%endif
+
+%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
+%define pluginhome /usr/lib/yum-plugins
+
+Summary: Utilities based around the yum package manager
+Name: yum-utils
+Version: 1.1.31
+Release: 45%{?dist}
+License: GPLv2+
+Group: Development/Tools
+Source: http://yum.baseurl.org/download/yum-utils/%{name}-%{version}.tar.gz
+Patch1: yum-utils-HEAD.patch
+Patch2: BZ-1002491-remove-security-plugin.patch
+Patch3: BZ-1050218-YumBaseError-not-defined.patch
+Patch4: BZ-1052871-debuginfo-install-wrong-repo-suffix.patch
+Patch5: BZ-1024070-yum-builddep-requires-source-repos-disabled.patch
+Patch6: BZ-1060702-reposync-nonexistent-repo.patch
+Patch7: BZ-1082050-source-repos.patch
+
+# rhel-7.1
+Patch50: BZ-1134989-post-transaction-actions-allow-colons.patch
+Patch51: BZ-1133125-reposync-urls-for-all-repos.patch
+Patch52: BZ-1129590-setopt-wildcards-save.patch
+Patch53: BZ-1127782-post-transaction-action.patch
+Patch54: BZ-1121714-reposync-manpage-missing-switches.patch
+Patch55: BZ-1113391-yumdownloader-depsolving-errors.patch
+Patch56: BZ-1104995-yumdownloader-redownloading-existing-rpms.patch
+Patch57: BZ-1095150-needs-restarting-fixes.patch
+Patch58: BZ-1139032-reposync-directory-structure.patch
+Patch59: BZ-1140864-reposync-urls-option-ignores-downloaded.patch
+Patch60: BZ-1107658-needs-restarting-graceful-error.patch
+
+#rhel-7.2
+Patch100: BZ-1075708-yum-config-manager-config-file-update.patch
+Patch101: BZ-1151154-yum-config-manager-disable-all-repos.patch
+Patch102: BZ-1213602-overlayfs-workaround-plugin.patch
+Patch103: BZ-817046-yum-builddep-respect-tolerant-ignore-missing-reqs.patch
+
+#rhel-7.3
+Patch120: BZ-1293707-debuginfo-installonly-latest-version.patch
+Patch121: BZ-1184912-yum-config-manager-fix-add-repo.patch
+Patch122: BZ-1091698-fs-snapshot-obsolete-btrfsctl.patch
+Patch123: BZ-1285750-repoquery-version.patch
+Patch124: BZ-1269414-yum-plugin-priorities-obsoletes.patch
+Patch125: BZ-1264774-archlist-docs.patch
+Patch126: BZ-1156057-yum-builddep-manpage-arched-requires.patch
+Patch127: BZ-1245117-yum-config-manager-all-repos.patch
+Patch128: BZ-1296282-verifytree-fix-comps-schema.patch
+Patch129: BZ-1192946-needs-restarting-add-reboothint-opt.patch
+Patch130: BZ-1335587-needs-restarting-add-services-opt.patch
+Patch131: BZ-1329649-reposync-download-metadata-manpage.patch
+
+#rhel-7.4
+Patch150: BZ-1403015-yum-config-manager-select-disabled-repoid-setopts.patch
+Patch151: BZ-1406891-verify-exit-status.patch
+Patch152: BZ-1429831-yum-copr.patch
+
+#rhel-7.5
+Patch160: BZ-1458098-yumdownloader-crash-broken-metadata.patch
+Patch161: BZ-1455318-package-cleanup-dont-remove-required.patch
+Patch162: BZ-1428210-fastestmirror-use-prereposetup.patch
+Patch163: BZ-1445751-yum-debug-dump-improve-repo-failure-handling.patch
+Patch164: BZ-1470647-add-pre-transaction-actions-plugin.patch
+Patch165: BZ-1437636-yum-builddep-add-define-opt.patch
+Patch166: BZ-1349433-verifytree-handle-no-core-group.patch
+Patch167: BZ-1333353-verifytree-fix-handling-no-comps.patch
+Patch168: BZ-1127783-transaction-actions-fix-file-globs.patch
+
+URL: http://yum.baseurl.org/download/yum-utils/
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+BuildArch: noarch
+# For new findRepos() API and utils.get_process_info() API.
+Requires: yum >= 3.4.3-143, libxml2-python
+Requires: python-kitchen
+BuildRequires: python-devel >= 2.4
+BuildRequires: gettext
+BuildRequires: intltool
+Provides: yum-utils-translations = %{version}-%{release}
+
+
+%description
+yum-utils is a collection of utilities and examples for the yum package
+manager. It includes utilities by different authors that make yum easier and
+more powerful to use. These tools include: debuginfo-install, 
+find-repos-of-install, needs-restarting, package-cleanup, repoclosure, 
+repodiff, repo-graph, repomanage, repoquery, repo-rss, reposync,
+repotrack, show-installed, show-changed-rco, verifytree, yumdownloader,
+yum-builddep, yum-complete-transaction, yum-config-manager, yum-debug-dump,
+yum-debug-restore and yum-groups-manager.
+
+%package -n yum-updateonboot
+Summary: Run yum update on system boot
+Group: System Environment/Base
+Requires: python, yum >= 2.4
+Requires(pre): chkconfig
+Requires(post): chkconfig
+
+%description -n yum-updateonboot
+Runs yum update on system boot. This allows machines that have been turned
+off for an extended amount of time to become secure immediately, instead of
+waiting until the next early morning cron job.
+
+%package -n yum-plugin-changelog
+Summary: Yum plugin for viewing package changelogs before/after updating
+Group: System Environment/Base
+Provides: yum-changelog = %{version}-%{release}
+Obsoletes: yum-changelog < 1.1.20-0
+Conflicts: yum-changelog < 1.1.20-0
+# changelog requires new update_md.UpdateMetadata() API in 3.2.23
+Requires: yum >= 3.2.23
+Requires: python-dateutil
+
+%description -n yum-plugin-changelog
+This plugin adds a command line option to allow viewing package changelog
+deltas before or after updating packages.
+
+%package -n yum-plugin-fastestmirror
+Summary: Yum plugin which chooses fastest repository from a mirrorlist
+Group: System Environment/Base
+Provides: yum-fastestmirror = %{version}-%{release}
+Obsoletes: yum-fastestmirror < 1.1.20-0
+Conflicts: yum-fastestmirror < 1.1.20-0
+Requires: yum >= 3.0
+
+%description -n yum-plugin-fastestmirror
+This plugin sorts each repository's mirrorlist by connection speed
+prior to downloading packages.
+
+%package -n yum-plugin-protectbase
+Summary: Yum plugin to protect packages from certain repositories.
+Group: System Environment/Base
+Provides: yum-protectbase = %{version}-%{release}
+Obsoletes: yum-protectbase < 1.1.20-0
+Conflicts: yum-protectbase < 1.1.20-0
+Requires: yum >= 3.0
+
+%description -n yum-plugin-protectbase
+This plugin allows certain repositories to be protected. Packages in the
+protected repositories can't be overridden by packages in non-protected
+repositories even if the non-protected repo has a later version.
+
+%package -n yum-plugin-versionlock
+Summary: Yum plugin to lock specified packages from being updated
+Group: System Environment/Base
+Provides: yum-versionlock = %{version}-%{release}
+Obsoletes: yum-versionlock < 1.1.20-0
+Conflicts: yum-versionlock < 1.1.20-0
+Requires: yum >= 3.2.24
+
+%description -n yum-plugin-versionlock
+This plugin takes a set of name/versions for packages and excludes all other
+versions of those packages (including optionally following obsoletes). This
+allows you to protect packages from being updated by newer versions,
+for example.
+
+%package -n yum-plugin-tsflags
+Summary: Yum plugin to add tsflags by a commandline option
+Group: System Environment/Base
+Provides: yum-tsflags = %{version}-%{release}
+Obsoletes: yum-tsflags < 1.1.20-0
+Conflicts: yum-tsflags < 1.1.20-0
+Requires: yum >= 3.0
+
+%description -n yum-plugin-tsflags
+This plugin allows you to specify optional transaction flags on the yum
+command line
+
+%package -n yum-plugin-priorities
+Summary: plugin to give priorities to packages from different repos
+Group: System Environment/Base
+Provides: yum-priorities = %{version}-%{release}
+Obsoletes: yum-priorities < 1.1.20-0
+Conflicts: yum-priorities < 1.1.20-0
+Requires: yum >= 3.0
+
+%description -n yum-plugin-priorities
+This plugin allows repositories to have different priorities.
+Packages in a repository with a lower priority can't be overridden by packages
+from a repository with a higher priority even if repo has a later version.
+
+%if %{package_yum_updatesd}
+%package -n yum-plugin-refresh-updatesd
+Summary: Tell yum-updatesd to check for updates when yum exits
+Group: System Environment/Base
+Provides: yum-refresh-updatesd = %{version}-%{release}
+Obsoletes: yum-refresh-updatesd < 1.1.20-0
+Conflicts: yum-refresh-updatesd < 1.1.20-0
+Requires: yum >= 3.0
+Requires: yum-updatesd
+
+%description -n yum-plugin-refresh-updatesd
+yum-refresh-updatesd tells yum-updatesd to check for updates when yum exits.
+This way, if you run 'yum update' and install all available updates, puplet
+will almost instantly update itself to reflect this.
+%endif
+
+%package -n yum-plugin-merge-conf
+Summary: Yum plugin to merge configuration changes when installing packages
+Group: System Environment/Base
+Provides: yum-merge-conf = %{version}-%{release}
+Obsoletes: yum-merge-conf < 1.1.20-0
+Conflicts: yum-merge-conf < 1.1.20-0
+Requires: yum >= 3.0
+
+%description -n yum-plugin-merge-conf
+This yum plugin adds the "--merge-conf" command line option. With this option,
+Yum will ask you what to do with config files which have changed on updating a
+package.
+
+%package -n yum-plugin-upgrade-helper
+Summary: Yum plugin to help upgrades to the next distribution version
+Group: System Environment/Base
+Provides: yum-upgrade-helper = %{version}-%{release}
+Obsoletes: yum-upgrade-helper < 1.1.20-0
+Conflicts: yum-upgrade-helper < 1.1.20-0
+Requires: yum >= 3.0
+
+%description -n yum-plugin-upgrade-helper
+this plugin allows yum to erase specific packages on install/update based on an additional
+metadata file in repositories. It is used to simplify distribution upgrade hangups.
+
+%package -n yum-plugin-aliases
+Summary: Yum plugin to enable aliases filters
+Group: System Environment/Base
+Provides: yum-aliases = %{version}-%{release}
+Obsoletes: yum-aliases < 1.1.20-0
+Conflicts: yum-aliases < 1.1.20-0
+# Requires args_hook
+Requires: yum >= 3.2.23
+Requires: yum-utils-translations = %{version}-%{release}
+
+%description -n yum-plugin-aliases
+This plugin adds the command alias, and parses the aliases config. file to
+enable aliases.
+
+%package -n yum-plugin-list-data
+Summary: Yum plugin to list aggregate package data
+Group: System Environment/Base
+Provides: yum-list-data = %{version}-%{release}
+Obsoletes: yum-list-data < 1.1.20-0
+Conflicts: yum-list-data < 1.1.20-0
+Requires: yum >= 3.0.5
+
+%description -n yum-plugin-list-data
+This plugin adds the commands list- vendors, groups, packagers, licenses,
+arches, committers, buildhosts, baseurls, package-sizes, archive-sizes and
+installed-sizes.
+
+%package -n yum-plugin-filter-data
+Summary: Yum plugin to list filter based on package data
+Group: System Environment/Base
+Provides: yum-filter-data = %{version}-%{release}
+Obsoletes: yum-filter-data < 1.1.20-0
+Conflicts: yum-filter-data < 1.1.20-0
+Requires: yum >= 3.2.17
+
+%description -n yum-plugin-filter-data
+This plugin adds the options --filter- vendors, groups, packagers, licenses,
+arches, committers, buildhosts, baseurls, package-sizes, archive-sizes and
+installed-sizes. Note that each package must match at least one pattern/range in
+each category, if any were specified.
+
+%package -n yum-plugin-tmprepo
+Summary: Yum plugin to add temporary repositories
+Group: System Environment/Base
+Provides: yum-tmprepo = %{version}-%{release}
+Obsoletes: yum-tmprepo < 1.1.20-0
+Conflicts: yum-tmprepo < 1.1.20-0
+Requires: yum >= 3.2.11
+Requires: createrepo
+
+%description -n yum-plugin-tmprepo
+This plugin adds the option --tmprepo which takes a url to a .repo file
+downloads it and enables it for a single run. This plugin tries to ensure
+that temporary repositories are safe to use, by default, by not allowing
+gpg checking to be disabled.
+
+%package -n yum-plugin-verify
+Summary: Yum plugin to add verify command, and options
+Group: System Environment/Base
+Provides: yum-verify = %{version}-%{release}
+Obsoletes: yum-verify < 1.1.20-0
+Conflicts: yum-verify < 1.1.20-0
+Requires: yum >= 3.2.12
+
+%description -n yum-plugin-verify
+This plugin adds the commands verify, verify-all and verify-rpm. There are
+also a couple of options. This command works like rpm -V, to verify your
+installation.
+
+%package -n yum-plugin-keys
+Summary: Yum plugin to deal with signing keys
+Group: System Environment/Base
+Provides: yum-keys = %{version}-%{release}
+Obsoletes: yum-keys < 1.1.20-0
+Conflicts: yum-keys < 1.1.20-0
+Requires: yum >= 3.2.19
+
+%description -n yum-plugin-keys
+This plugin adds the commands keys, keys-info, keys-data and keys-remove. They
+allow you to query and remove signing keys.
+
+%package -n yum-plugin-remove-with-leaves
+Summary: Yum plugin to remove dependencies which are no longer used because of a removal
+Group: System Environment/Base
+Provides: yum-remove-with-leaves = %{version}-%{release}
+Obsoletes: yum-remove-with-leaves < 1.1.20-0
+Conflicts: yum-remove-with-leaves < 1.1.20-0
+Requires: yum >= 3.2.19
+
+%description -n yum-plugin-remove-with-leaves
+This plugin removes any unused dependencies that were brought in by an install
+but would not normally be removed. It helps to keep a system clean of unused
+libraries and packages.
+
+%package -n yum-plugin-pre-transaction-actions
+Summary: Yum plugin to run arbitrary commands when certain pkgs are acted on
+Group: System Environment/Base
+Provides: yum-pre-transaction-actions = %{version}-%{release}
+Requires: yum >= 3.2.19
+
+%description -n yum-plugin-pre-transaction-actions
+This plugin allows the user to run arbitrary actions prior to a transaction
+when specified packages are changed.
+
+%package -n yum-plugin-post-transaction-actions
+Summary: Yum plugin to run arbitrary commands when certain pkgs are acted on
+Group: System Environment/Base
+Provides: yum-post-transaction-actions = %{version}-%{release}
+Obsoletes: yum-post-transaction-actions < 1.1.20-0
+Conflicts: yum-post-transaction-actions < 1.1.20-0
+Requires: yum >= 3.2.19
+
+%description -n yum-plugin-post-transaction-actions
+This plugin allows the user to run arbitrary actions immediately following a
+transaction when specified packages are changed.
+
+%package -n yum-NetworkManager-dispatcher
+Summary: NetworkManager script which tells yum to check its cache on network change
+Group: System Environment/Base
+Requires: yum >= 3.2.17
+
+%description -n yum-NetworkManager-dispatcher
+This NetworkManager "dispatch script" forces yum to check its cache if/when a
+new network connection happens in NetworkManager. Note that currently there is
+no checking of previous data, so if your WiFi keeps going up and down (or you
+suspend/resume a lot) yum will recheck its cached data a lot.
+
+%package -n yum-plugin-rpm-warm-cache
+Summary: Yum plugin to access the rpmdb files early to warm up access to the db 
+Group: System Environment/Base
+Provides: yum-rpm-warm-cache = %{version}-%{release}
+Obsoletes: yum-rpm-warm-cache < 1.1.20-0
+Conflicts: yum-rpm-warm-cache < 1.1.20-0
+Requires: yum >= 3.2.19
+
+%description -n yum-plugin-rpm-warm-cache
+This plugin reads the rpmdb files into the system cache before accessing the
+rpmdb directly. In some cases this should speed up access to rpmdb information
+
+%package -n yum-plugin-auto-update-debug-info
+# Works by searching for *-debuginfo ... so it shouldn't trigger on itself.
+Summary: Yum plugin to enable automatic updates to installed debuginfo packages
+Group: System Environment/Base
+Obsoletes: yum-plugin-auto-update-debuginfo < 1.1.21-0
+Conflicts: yum-plugin-auto-update-debuginfo < 1.1.21-0
+Provides: yum-plugin-auto-update-debuginfo = %{version}-%{release}
+Requires: yum >= 3.2.19
+
+%description -n yum-plugin-auto-update-debug-info
+This plugin looks to see if any debuginfo packages are installed, and if there
+are it enables all debuginfo repositories that are "children" of enabled
+repositories.
+
+%package -n yum-plugin-show-leaves
+Summary: Yum plugin which shows newly installed leaf packages
+Group: System Environment/Base
+Requires: yum >= 3.2.23
+
+%description -n yum-plugin-show-leaves
+Yum plugin which shows newly installed leaf packages
+and packages that became leaves after a transaction
+
+%package -n yum-plugin-local
+Summary: Yum plugin to automatically manage a local repo. of downloaded packages
+Group: System Environment/Base
+# Who the hell knows what version :)
+Requires: yum >= 3.2.22
+Requires: createrepo
+
+%description -n yum-plugin-local
+When this plugin is installed it will automatically copy all downloaded packages
+to a repository on the local filesystem, and (re)build that repository. This
+means that anything you've downloaded will always exist, even if the original
+repo. removes it (and can thus. be reinstalled/downgraded/etc.).
+
+%package -n yum-plugin-fs-snapshot
+Summary: Yum plugin to automatically snapshot your filesystems during updates
+Group: System Environment/Base
+Requires: yum >= 3.2.22
+Requires: btrfs-progs
+
+%description -n yum-plugin-fs-snapshot
+When this plugin is installed it will automatically snapshot any
+filesystem that is touched by the packages in a yum update or yum remove.
+
+%package -n yum-plugin-ps
+Summary: Yum plugin to look at processes, with respect to packages
+Group: System Environment/Base
+Requires: yum >= 3.2.27
+
+%description -n yum-plugin-ps
+When this plugin is installed it adds the yum command "ps", which allows you
+to see which running processes are accociated with which packages (and if they
+need rebooting, or have updates, etc.)
+
+%if %{package_puppetverify}
+%package -n yum-plugin-puppetverify
+Summary: Yum plugin to add puppet checksums to verify data
+Group: System Environment/Base
+Provides: yum-puppetverify = %{version}-%{release}
+Requires: yum >= 3.2.12
+Requires: PyYAML >= 3.09
+Requires: puppet
+
+%description -n yum-plugin-puppetverify
+Supplies checksums for files in packages from puppet's state file. 
+%endif
+
+%package -n yum-plugin-copr
+Summary: Yum plugin to add copr command
+Group: System Environment/Base
+Provides: yum-copr = %{version}-%{release}
+Requires: yum >= 3.4.3
+Requires: python-requests
+
+%description -n yum-plugin-copr
+This plugin adds the command copr, for adding/listing/searching copr repos.
+
+%package -n yum-plugin-ovl
+Summary: Yum plugin to work around overlayfs issues
+Group: System Environment/Base
+Provides: yum-ovl = %{version}-%{release}
+Requires: yum >= 3.4.3
+
+%description -n yum-plugin-ovl
+This plugin touches rpmdb files to work around overlayfs issues.
+
+%prep
+%setup -q
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+
+# rhel-7.1
+%patch50 -p1
+%patch51 -p1
+%patch52 -p1
+%patch53 -p1
+%patch54 -p1
+%patch55 -p1
+%patch56 -p1
+%patch57 -p1
+%patch58 -p1
+%patch59 -p1
+%patch60 -p1
+
+#rhel-7.2
+%patch100 -p1
+%patch101 -p1
+%patch102 -p1
+%patch103 -p1
+
+#rhel-7.3
+%patch120 -p1
+%patch121 -p1
+%patch122 -p1
+%patch123 -p1
+%patch124 -p1
+%patch125 -p1
+%patch126 -p1
+%patch127 -p1
+%patch128 -p1
+%patch129 -p1
+%patch130 -p1
+%patch131 -p1
+
+#rhel-7.4
+%patch150 -p1
+%patch151 -p1
+%patch152 -p1
+
+#rhel-7.5
+%patch160 -p1
+%patch161 -p1
+%patch162 -p1
+%patch163 -p1
+%patch164 -p1
+%patch165 -p1
+%patch166 -p1
+%patch167 -p1
+%patch168 -p1
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make DESTDIR=$RPM_BUILD_ROOT install
+make -C updateonboot DESTDIR=$RPM_BUILD_ROOT install
+
+%find_lang %name
+
+# Plugins to install
+plugins="\
+ changelog \
+ fastestmirror \
+ protectbase \
+ versionlock \
+ tsflags \
+ priorities \
+ merge-conf \
+ upgrade-helper \
+ aliases \
+ list-data \
+ filter-data \
+ tmprepo \
+ verify \
+ keys \
+ remove-with-leaves \
+ pre-transaction-actions \
+ post-transaction-actions \
+ rpm-warm-cache \
+ auto-update-debuginfo \
+ show-leaves \
+ local \
+ fs-snapshot \
+ ps \
+ ovl \
+ copr \
+"
+%if %{package_puppetverify}
+plugins="$plugins \
+ puppetverify \
+"
+%endif
+
+%if %{package_yum_updatesd}
+plugins="$plugins \
+ refresh-updatesd \
+"
+%endif
+
+mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/yum/pluginconf.d/ $RPM_BUILD_ROOT/%pluginhome
+mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/yum/pre-actions
+mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/yum/post-actions
+
+cd plugins
+for plug in $plugins; do
+    install -m 644 $plug/*.conf $RPM_BUILD_ROOT/%{_sysconfdir}/yum/pluginconf.d/
+    install -m 644 $plug/*.py $RPM_BUILD_ROOT/%pluginhome
+    %{__python} -c "import compileall; compileall.compile_dir('$RPM_BUILD_ROOT/%pluginhome', 1)"
+done
+install -m 644 aliases/aliases $RPM_BUILD_ROOT/%{_sysconfdir}/yum/aliases.conf
+install -m 644 versionlock/versionlock.list $RPM_BUILD_ROOT/%{_sysconfdir}/yum/pluginconf.d/
+# need for for the ghost in files section of yum-plugin-local
+mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/yum.repos.d
+touch $RPM_BUILD_ROOT%{_sysconfdir}/yum.repos.d/_local.repo
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post -n yum-updateonboot
+/sbin/chkconfig --add yum-updateonboot >/dev/null 2>&1 || :;
+
+%preun -n yum-updateonboot
+if [ $1 = 0 ]; then
+    /sbin/service yum-updateonboot stop >/dev/null 2>&1 || :;
+    /sbin/chkconfig --del yum-updateonboot >/dev/null 2>&1 || :;
+fi
+
+%files -f %{name}.lang
+%defattr(-, root, root)
+%doc README yum-util-cli-template
+%doc COPYING
+%doc plugins/README
+%{_sysconfdir}/bash_completion.d
+%{_bindir}/debuginfo-install
+%{_bindir}/find-repos-of-install
+%{_bindir}/needs-restarting
+%{_bindir}/package-cleanup
+%{_bindir}/repoclosure
+%{_bindir}/repodiff
+%{_bindir}/repomanage
+%{_bindir}/repoquery
+%{_bindir}/repotrack
+%{_bindir}/reposync
+%{_bindir}/repo-graph
+%{_bindir}/repo-rss
+%{_bindir}/verifytree
+%{_bindir}/yumdownloader
+%{_bindir}/yum-builddep
+%{_bindir}/yum-config-manager
+%{_bindir}/yum-debug-dump
+%{_bindir}/yum-debug-restore
+%{_bindir}/yum-groups-manager
+%{_bindir}/show-installed
+%{_bindir}/show-changed-rco
+%{_sbindir}/yum-complete-transaction
+%{_sbindir}/yumdb
+%{python_sitelib}/yumutils/
+%{_mandir}/man1/yum-utils.1.*
+%{_mandir}/man1/debuginfo-install.1.*
+%{_mandir}/man1/package-cleanup.1.*
+%{_mandir}/man1/repo-rss.1.*
+%{_mandir}/man1/repoquery.1.*
+%{_mandir}/man1/repodiff.1.*
+%{_mandir}/man1/reposync.1.*
+%{_mandir}/man1/show-changed-rco.1.*
+%{_mandir}/man1/show-installed.1.*
+%{_mandir}/man1/yum-builddep.1.*
+%{_mandir}/man1/yum-debug-dump.1.*
+%{_mandir}/man1/yum-debug-restore.1.*
+%{_mandir}/man8/yum-complete-transaction.8.*
+%{_mandir}/man1/yum-groups-manager.1.*
+%{_mandir}/man8/yumdb.8.*
+%{_mandir}/man1/yumdownloader.1.*
+%{_mandir}/man1/find-repos-of-install.1.*
+%{_mandir}/man1/needs-restarting.1.*
+%{_mandir}/man1/repo-graph.1.*
+%{_mandir}/man1/repoclosure.1.*
+%{_mandir}/man1/repomanage.1.*
+%{_mandir}/man1/repotrack.1.*
+%{_mandir}/man1/verifytree.1.*
+%{_mandir}/man1/yum-config-manager.1.*
+
+%files -n yum-updateonboot
+%defattr(-, root, root)
+%doc updateonboot/README COPYING
+%config(noreplace) %{_sysconfdir}/sysconfig/yum-updateonboot
+%{_initrddir}/yum-updateonboot
+
+%files -n yum-plugin-changelog
+%defattr(-, root, root)
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/changelog.conf
+%doc COPYING
+%{pluginhome}/changelog.*
+%{_mandir}/man1/yum-changelog.1.*
+%{_mandir}/man5/yum-changelog.conf.5.*
+
+%files -n yum-plugin-fastestmirror
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/fastestmirror.conf
+%{pluginhome}/fastestmirror*.*
+
+%files -n yum-plugin-protectbase
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/protectbase.conf
+%{pluginhome}/protectbase.*
+
+%files -n yum-plugin-versionlock
+%defattr(-, root, root)
+%doc plugins/versionlock/README COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/versionlock.conf
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/versionlock.list
+%{pluginhome}/versionlock.*
+%{_mandir}/man1/yum-versionlock.1.*
+%{_mandir}/man5/yum-versionlock.conf.5.*
+
+%files -n yum-plugin-tsflags
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/tsflags.conf
+%{pluginhome}/tsflags.*
+
+%files -n yum-plugin-priorities
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/priorities.conf
+%{pluginhome}/priorities.*
+
+%if %{package_yum_updatesd}
+%files -n yum-plugin-refresh-updatesd
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/refresh-updatesd.conf
+%{pluginhome}/refresh-updatesd.*
+%endif
+
+%files -n yum-plugin-merge-conf
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/merge-conf.conf
+%{pluginhome}/merge-conf.*
+
+%files -n yum-plugin-upgrade-helper
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/upgrade-helper.conf
+%{pluginhome}/upgrade-helper.*
+
+%files -n yum-plugin-aliases
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/aliases.conf
+%config(noreplace) %{_sysconfdir}/yum/aliases.conf
+%{pluginhome}/aliases.*
+%{_mandir}/man1/yum-aliases.1.*
+
+%files -n yum-plugin-list-data
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/list-data.conf
+%{pluginhome}/list-data.*
+%{_mandir}/man1/yum-list-data.1.*
+
+%files -n yum-plugin-filter-data
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/filter-data.conf
+%{pluginhome}/filter-data.*
+%{_mandir}/man1/yum-filter-data.1.*
+
+%files -n yum-plugin-tmprepo
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/tmprepo.conf
+%{pluginhome}/tmprepo.*
+
+%files -n yum-plugin-verify
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/verify.conf
+%{pluginhome}/verify.*
+%{_mandir}/man1/yum-verify.1.*
+
+%files -n yum-plugin-keys
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/keys.conf
+%{pluginhome}/keys.*
+
+%files -n yum-NetworkManager-dispatcher
+%defattr(-, root, root)
+%doc COPYING
+/etc/NetworkManager/dispatcher.d/*
+
+%files -n yum-plugin-remove-with-leaves
+%defattr(-, root, root)
+%doc COPYING
+%{pluginhome}/remove-with-leaves.*
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/remove-with-leaves.conf
+
+%files -n yum-plugin-pre-transaction-actions
+%defattr(-, root, root)
+%doc COPYING
+%{pluginhome}/pre-transaction-actions.*
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/pre-transaction-actions.conf
+%doc plugins/pre-transaction-actions/sample.action
+# Default *.action file dropping dir.
+%dir %{_sysconfdir}/yum/pre-actions
+
+%files -n yum-plugin-post-transaction-actions
+%defattr(-, root, root)
+%doc COPYING
+%{pluginhome}/post-transaction-actions.*
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/post-transaction-actions.conf
+%doc plugins/post-transaction-actions/sample.action
+# Default *.action file dropping dir.
+%dir %{_sysconfdir}/yum/post-actions
+
+%files -n yum-plugin-rpm-warm-cache
+%defattr(-, root, root)
+%doc COPYING
+%{pluginhome}/rpm-warm-cache.*
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/rpm-warm-cache.conf
+
+%files -n yum-plugin-auto-update-debug-info
+%defattr(-, root, root)
+%doc COPYING
+%{pluginhome}/auto-update-debuginfo.*
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/auto-update-debuginfo.conf
+
+%files -n yum-plugin-show-leaves
+%defattr(-, root, root)
+%doc COPYING
+%{pluginhome}/show-leaves.*
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/show-leaves.conf
+
+%files -n yum-plugin-local
+%defattr(-, root, root)
+%doc COPYING
+%ghost %{_sysconfdir}/yum.repos.d/_local.repo
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/local.conf
+%{pluginhome}/local.*
+
+%files -n yum-plugin-fs-snapshot
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/fs-snapshot.conf
+%{pluginhome}/fs-snapshot.*
+%{_mandir}/man1/yum-fs-snapshot.1.*
+%{_mandir}/man5/yum-fs-snapshot.conf.5.*
+
+%files -n yum-plugin-ps
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/ps.conf
+%{pluginhome}/ps.*
+
+%if %{package_puppetverify}
+%files -n yum-plugin-puppetverify
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/puppetverify.conf
+%{pluginhome}/puppetverify.*
+%endif
+
+%files -n yum-plugin-copr
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/copr.conf
+%{pluginhome}/copr.*
+%{_mandir}/man8/yum-copr.8.*
+
+%files -n yum-plugin-ovl
+%defattr(-, root, root)
+%doc COPYING
+%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/ovl.conf
+%{pluginhome}/ovl.*
+%{_mandir}/man1/yum-ovl.1.*
+
+%changelog
+* Tue Nov 21 2017 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-45
+- Fix file globbing in transaction-actions.
+- Related: bug#1470647
+
+* Mon Oct 30 2017 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-44
+- Add pre-transaction-actions plugin.
+- Resolves: bug#1470647
+- yum-builddep: add --define option.
+- Resolves: bug#1437636
+- verifytree: handle no @core group gracefully.
+- Resolves: bug#1349433
+- verifytree: fix handling of missing comps.
+- Resolves: bug#1333353
+
+* Fri Oct 20 2017 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-43
+- yumdownloader: fix crash on broken srpm metadata.
+- Resolves: bug#1458098
+- package-cleanup: don't remove required dupes.
+- Resolves: bug#1455318
+- fastestmirror: move the logic before MD retrieval.
+- Resolves: bug#1428210
+- yum-debug-dump: improve repo failure handling.
+- Resolves: bug#1445751
+
+* Tue Mar 21 2017 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-42
+- Add yum-plugin-copr.
+- Resolves: bug#1429831
+
+* Thu Mar 09 2017 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-41
+- yum-config-manager: only select exact matches from --setopt.
+- Resolves: bug#1403015
+- yum-plugin-verify: set exit status to 1 in case of problems.
+- Resolves: bug#1406891
+
+* Thu Aug 04 2016 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-40
+- needs-restarting: rework reboothint logic.
+- Related: bug#1192946
+- needs-restarting: rebase patch for 1335587.
+- Related: bug#1335587
+
+* Fri Jul 22 2016 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-39
+- verifytree: don't fail with versioned docdirs.
+- Related: bug#1296282
+
+* Thu Jun 30 2016 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-38
+- verifytree: use local comps schema.
+- Related: bug#1296282
+* Tue Jun 21 2016 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-37
+- needs-restarting: add option for reboot hint.
+- Resolves: bug#1192946
+- needs-restarting: add option to list services.
+- Resolves: bug#1335587
+- reposync: add --download-metadata to the man page.
+- Resolves: bug#1329649
+- debuginfo-install: also respect provides when testing for installonly.
+- Related: bug#1293707
+
+* Fri May 13 2016 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-36
+- yum-config-manager: document syntax for enabling/disabling all repos.
+- Resolves: bug#1245117
+- verifytree: use current url of comps schema.
+- Resolves: bug#1296282
+
+* Tue Mar 01 2016 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-35
+- debuginfo-install: install debuginfo only for the latest installed version of installonly package.
+- Resolves: bug#1293707
+- yum-config-manager: don't require enabled repos for --add-repo to work.
+- Resolves: bug#1184912
+- fs-snapshot: btrfsctl is obsolete, use btrfs.
+- Resolves: bug#1091698
+- Add libxml2-python to Requires for repo-rss.
+- Resolves: bug#1297788
+- Remove -v from repoquery man page.
+- Resolves: bug#1285750
+- yum-plugin-priorities: get all obsoletes, not just the newest.
+- Resolves: bug#1269414
+- yumdownloader: fix description of --archlist in the manpage.
+- Resolves: bug#1264774
+- yum-builddep: mention the workaround for arched srpms in the man page.
+- Resolves: bug#1156057
+
+* Mon Oct 12 2015 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-34
+- ovl plugin: run at init_hook stage.
+- Resolves: bug#1269395
+
+* Fri Sep 04 2015 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-33
+- ovl plugin: remove fs check and add manpage.
+- Related: bug#1213602
+
+* Tue Aug 04 2015 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-32
+- ovl plugin: change copy-up strategy, execute when root fs is mounted OverlayFS, add logging.
+- Related: bug#1213602
+
+* Thu Jul 02 2015 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-31
+- yum-builddep: respect --tolerant to ignore missing dependencies.
+- Resolves: bug#817046
+
+* Tue May 26 2015 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-30
+- yum-config-manager: update config file specified using -c option.
+- Resolves: bug#1075708
+- yum-config-manager: require \* syntax to disable all repos.
+- Resolves: bug#1151154
+- Add plugin for overlayfs issue workaround.
+- Resolves: bug#1213602
+
+* Mon Nov 10 2014 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-29
+- reposync: fix man page formatting.
+- Related: bug#1121714
+
+* Wed Sep 24 2014 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-28
+- needs-restarting: handle RepoError gracefully.
+- Resolves: bug#1107658
+
+* Wed Sep 24 2014 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-27
+- reposync: preserve directory structure.
+- Resolves: bug#1139032
+- reposync: check for existing packages when using -u option.
+- Resolves: bug#1140864
+
+* Thu Sep  4 2014 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-26
+- yum-post-transaction-actions: allow colons in command part.
+- Resolves: bug#1134989
+- reposync: show urls for all repos when using -u option.
+- Resolves: bug#1133125
+- yum-config-manager: fix --save when --setopt contains wildcards.
+- Resolves: bug#1129590
+- post-transaction-actions: fix filename matching.
+- Resolves: bug#1127782
+- reposync: add missing switches to the manpage.
+- Resolves: bug#1121714
+- yumdownloader: print depsolving errors instead of ignoring them.
+- Resolves: bug#1113391
+- yumdownloader: make --destdir less of a hack.
+- Resolves: bug#1104995
+- needs-restarting: multiple fixes.
+- Resolves: bug#1095150
+
+* Tue Aug  5 2014 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-25
+- yumdownloader, yum-builddep: do not ignore source repos.
+- Resolves: bug#1082050
+
+* Fri Feb 14 2014 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-24
+- reposync: fix 'reposync -r nosuchrepo' behaviour.
+- Resolves: bug#1060702
+
+* Mon Jan 20 2014 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-23
+- yum-builddep: Use srpms in already enabled repos.
+- Resolves: bug1024070
+
+* Wed Jan 15 2014 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-22
+- Fix repo suffix to '-debug-rpms' in debuginfo-install.
+- Resolves: bug#1052871
+
+* Fri Jan 10 2014 Valentina Mukhamedzhanova <vmukhame@redhat.com> - 1.1.31-21
+- Fix YumBaseError name error in repoquery
+- Resolves: bug#1050218
+
+* Fri Dec 27 2013 Daniel Mach <dmach@redhat.com> - 1.1.31-20
+- Mass rebuild 2013-12-27
+
+* Fri Nov  1 2013 James Antill <james.antill@redhat.com> - 1.1.31-19
+- Remove security plugin.
+- Resolves: rhbz#1002491
+
+* Mon Sep  9 2013 James Antill <james.antill@redhat.com> - 1.1.31-18
+- Disable puppetverify plugin for el7. BZ 1002876.
+- reposync: fix a copy-paste error. BZ 994514
+- repo-rss: non-ASCII fix, sorting.
+- Add --nogroups and --noplugins options to verifytree.
+
+* Wed Jul 31 2013 Zdenek Pavlas <zpavlas@redhat.com> - 1.1.31-17
+- Use new findRepos() API for yum-config-manager. BZ 971599
+
+* Wed Jul 31 2013 Zdenek Pavlas <zpavlas@redhat.com> - 1.1.31-16
+- Update to latest HEAD
+- Fix pacakge => package typos
+- docs: Add missing man page short descriptions
+- docs: Escape dashes in command-line options
+- docs: Add missing man pages for all yum-utils
+- Add --show-duplicates to repoquery manpage. BZ 975565
+- yum-complete-transaction: unlock yum.pid. BZ 984119
+- sanitize repoquery --repofrompath. BZ 988140
+- yum changelog: implicit since=all. BZ 961782
+- repoquery: retry doLock() BZ 988223
+- repoquery: add --installroot option. BZ 988429
+
+* Mon Jun 24 2013 Zdenek Pavlas <zpavlas@redhat.com> - 1.1.31-15
+- Update to latest HEAD
+- debuginfo-install: handle YumBaseError
+- fs-snapshot: "dmsetup -o" workaround.  BZ 954358, BZ 949569
+- tmprepo: avoid spaces in repoid. BZ 965806
+- repoquery: add cachedir locking. BZ 969776
+- Fix a bug in Modified/Upgraded/Downgraded output. BZ 819502
+
+* Thu Apr 18 2013 Zdenek Pavlas <zpavlas@redhat.com> - 1.1.31-14
+- yum-utils.bash: load yum.bash first
+
+* Wed Apr 17 2013 Zdenek Pavlas <zpavlas@redhat.com> - 1.1.31-13
+- Update to latest HEAD
+- versionlock add: Skip packages already locked.
+- versionlock delete: Match all names, not just envra.
+- Allow --old=/foo urls for repodiff.
+- Don't check timestamps for repofrompath repos. BZ 880944
+- Output couldn't find a pkg. for 'foo'. BZ 838158
+
+* Tue Mar 12 2013 James Antill <james@fedoraproject.org> - 1.1.31-12
+- Update to latest HEAD.
+- FS snapshot tweaks for snapper support.
+
+* Mon Mar 11 2013 James Antill <james@fedoraproject.org> - 1.1.31-11
+- Update to latest HEAD.
+- FS snapshot fixes, and thin provisioning support.
+- search-quiet for yumdb.
+
+* Wed Feb  6 2013 Zdenek Pavlas <zpavlas@redhat.com> - 1.1.31-10
+- Update to latest HEAD
+- Small fixes in documentation and error handling
+
+* Mon Jan 14 2013 Zdenek Pavlas <zpavlas@redhat.com> - 1.1.31-9
+- Update to latest HEAD.
+- Added pluginhome define to get rid of hardcoded paths
+- Fix yum-NetworkManager-dispatcher description, BZ 894729
+- reposync should lock. BZ 880722
+- Initialize exit_code correctly.  BZ 882536
+
+* Mon Jan 14 2013 Zdenek Pavlas <zpavlas@redhat.com> - 1.1.31-8
+- Update to latest HEAD.
+
+* Wed Aug  8 2012 Zdenek Pavlas <zpavlas@redhat.com> - 1.1.31-7
+- Update to latest HEAD.
+- Use package downloader from Yum.
+
+* Sun Jul 22 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.1.31-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Fri Apr 27 2012 James Antill <james@fedoraproject.org> - 1.1.31-5
+- Update to latest HEAD.
+
+* Thu Jan 26 2012 James Antill <james@fedoraproject.org> - 1.1.31-4
+- Update to latest HEAD.
+
+* Sat Jan 14 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.1.31-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Thu Aug 13 2011 Tim Lauridsen <timlau@fedoraproject.org> 
+- fix traceback in auto-update-debuginfo plugin (rhbz #729982)
+
+* Thu Aug 10 2011 Tim Lauridsen <timlau@fedoraproject.org> 
+- mark as 1.1.31
+- remove patches
+
+* Thu Jul 28 2011 James Antill <james@fedoraproject.org>
+- Fix for BuildTrans no return value checking, needed for mock.
+- Resolves: bug#716267
+
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.1.30-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Thu Jan 13 2011 Tim Lauridsen <timlau@fedoraproject.org> 
+- mark as 1.1.30 
+ 
+* Mon Jan 3 2011 Tim Lauridsen <timlau@fedoraproject.org>
+- Added yumutils python module
+ 
+* Thu Dec 30 2010 Tim Lauridsen <timlau@fedoraproject.org>
+- Added Translation support and need Requires, BuildRequires 
+
+* Sun Nov 7 2010 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.29 
+
+* Tue Aug  3 2010 Seth Vidal <skvidal at fedoraproject.org>
+- add COPYING docs to all the plugins to make fedora(and Tim) happy. :)
+
+* Tue Aug 3 2010 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.28 
+
+* Sun Jun 6 2010 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.27  
+
+* Wed Feb 10 2010 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.26  
+
+* Wed Jan 27 2010 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.25
+- add touch /etc/yum.repos.d/_local.repo to install section
+- this need for for the ghost in files section of yum-plugin-local
+
+* Sun Nov 8 2009 Tim Lauridsen <timlau@fedoraproject.org>
+- remove basearchonly since all versions of yum for quite some time obsolete it
+- truncate changelog to last 2 years
+
+* Sat Nov 7 2009 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.24
+
+* Wed Nov  4 2009 Seth Vidal <skvidal at fedoraproject.org>
+- add needs-restarting
+
+* Mon Oct 12 2009 Seth Vidal <skvidal at fedoraproject.org>
+- add python compileall to all plugins so we get .pyc/.pyo files in them
+- fixes https://bugzilla.redhat.com/show_bug.cgi?id=493174
+
+* Wed Sep 2 2009 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.23
+
+* Tue May 19 2009 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.22 
+
+* Mon May 18 2009 Seth Vidal <skvidal at fedoraproject.org>
+- add show-leaves plugin from Ville Skyttä
+
+* Wed Mar 25 2009 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.21 
+
+* Mon Mar 2 2009 Tim Lauridsen <timlau@fedoraproject.org>
+- set yum require to 3.2.21 (the 3.2.21 in rawhide is patched to yum head, so it matches the need yum 3.2.22 code)
+- Added versioned Provides: yum-<pluginname> to make rpm/yum happy.
+- yum-updateonboot is not renamed and dont need Obsoletes/Conflicts/Provides
+
+* Sun Mar 1 2009 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.20
+- rename plugins from yum-name to yum-plugin-name
+
+* Wed Feb 25 2009 Tim Lauridsen <timlau@fedoraproject.org> 
+- Remove yum-kernel-module & yum-fedorakmod plugins (no obsoleting yet)
+- Remove yum-skip-broken plugin leftovers
+
+* Tue Feb  3 2009 James Antill <james@fedoraproject.org>
+- add auto-update-debuginfo plugin
+
+* Wed Dec 17 2008 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.19
+
+* Wed Dec 10 2008 Seth Vidal <skvidal at fedoraproject.org>
+- add find-repos-of-install from James' stash of misc stuff
+
+* Wed Oct 29 2008 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.18
+
+* Mon Oct 27 2008 Seth Vidal <skvidal at fedoraproject.org>
+- add rpm-warm-cache plugin
+
+* Fri Sep 19 2008 Tim Lauridsen <timlau@fedoraproject.org>
+- removed skip-broken plugin
+
+* Wed Sep 17 2008 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.17
+
+* Mon Sep  8 2008 Seth Vidal <skvidal at fedoraproject.org>
+- add yum-remove-with-leaves plugin
+
+* Wed Aug 27 2008 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.16
+* Wed Aug 20 2008 James Antill <james@fedoraproject.org>
+- add yum-groups-manager
+
+* Thu Aug 7 2008 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.15
+* Wed May 21 2008 Tim Lauridsen <timlau@fedoraproject.org>
+- add verifytree
+
+* Wed May 21 2008 Tim Lauridsen <timlau@fedoraproject.org>
+  Make yum-fastestmirror %%files handle the fastestmirror-asyncore.py file
+* Wed May 21 2008 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.14
+* Fri Apr 10 2008 James Antill <james@fedoraproject.org>
+- Add keys plugin
+
+* Fri Mar 31 2008 James Antill <james@fedoraproject.org>
+- Add yum-aliases man page
+
+* Fri Mar 21 2008 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.13
+* Fri Mar 21 2008 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.12
+* Tue Mar 18 2008 Shawn Starr <shawn.starr@rogers.com>
+- Add yum-utils.1 manual page
+- Rename yum-complete-transaction manual page to 8
+- Move yum-complete-transaction to /usr/sbin
+
+* Sat Mar  1 2008 James Antill <james@fedoraproject.org>
+- Add verify plugin
+
+* Wed Feb 20 2008 James Antill <james@fedoraproject.org>
+- Add empty versionlock file
+
+* Fri Feb  1 2008 James Antill <james@fedoraproject.org>
+- Add filter-data plugin
+
+* Wed Jan 30 2008 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.11
+
+* Sun Jan 13 2008 Seth Vidal <skvidal at fedoraproject.org>
+- add repodiff
+
+* Thu Jan 3 2008 Tim Lauridsen <timlau@fedoraproject.org>
+- mark as 1.1.10
+