diff --git a/meta/recipes-devtools/python/python-smartpm/smart-missingok.patch b/meta/recipes-devtools/python/python-smartpm/smart-missingok.patch
deleted file mode 100644
index 7e13869..0000000
--- a/meta/recipes-devtools/python/python-smartpm/smart-missingok.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-backends/rpm: Identify recommended packages
-
-We identify and store recommended packages (and later throw that data away.)
-
-This is indended to be the starting work to add support for recommended
-packages to smart.
-
-Upstream-status: Inappropriate [ Code isn't finished! ]
-
-Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
-
-Index: smart-1.4.1/smart/backends/rpm/header.py
-===================================================================
---- smart-1.4.1.orig/smart/backends/rpm/header.py
-+++ smart-1.4.1/smart/backends/rpm/header.py
-@@ -292,6 +292,7 @@ class RPMHeaderLoader(Loader):
-                     f = [0]
-                 elif type(f) != list:
-                     f = [f]
-+                recdict = {}
-                 reqdict = {}
-                 for i in range(len(n)):
-                     ni = n[i]
-@@ -308,10 +309,17 @@ class RPMHeaderLoader(Loader):
-                             # RPMSENSE_SCRIPT_PREUN |
-                             # RPMSENSE_SCRIPT_POST |
-                             # RPMSENSE_SCRIPT_POSTUN == 7744
--                            reqdict[(f[i]&7744 and PreReq or Req,
--                                     intern(ni), r, vi)] = True
-+                            if (f[i]&rpm.RPMSENSE_MISSINGOK):
-+                                print "Ignoring Recommend Dependency: %s" % (ni)
-+                                recdict[(f[i]&7744 and PreReq or Req,
-+                                         intern(ni), r, vi)] = True
-+                            else:
-+                                reqdict[(f[i]&7744 and PreReq or Req,
-+                                         intern(ni), r, vi)] = True
-+                recargs = collapse_libc_requires(recdict.keys())
-                 reqargs = collapse_libc_requires(reqdict.keys())
-             else:
-+                recargs = None
-                 reqargs = None
- 
-             n = h[1054] # RPMTAG_CONFLICTNAME
diff --git a/meta/recipes-devtools/python/python-smartpm/smart-recommends.patch b/meta/recipes-devtools/python/python-smartpm/smart-recommends.patch
new file mode 100644
index 0000000..a41b1be
--- /dev/null
+++ b/meta/recipes-devtools/python/python-smartpm/smart-recommends.patch
@@ -0,0 +1,1362 @@
+Handle recommended packages in core and rpm backends
+
+Identify and store recommended packages in the cache, add a query option
+to read them and ignore them if they are not present when installing.
+
+Initial identification code from Mark Hatle <mark.hatle@windriver.com>.
+
+Upstream-Status: Pending
+
+Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
+
+diff --git a/smart/backends/rpm/base.py b/smart/backends/rpm/base.py
+index 0489e11..b9e9cb2 100644
+--- a/smart/backends/rpm/base.py
++++ b/smart/backends/rpm/base.py
+@@ -198,6 +198,29 @@ class RPMPackage(Package):
+                         break
+                 else:
+                     return False
++        srecs = fk(self.recommends)
++        orecs = fk(other.recommends)
++        if srecs != orecs:
++            for srec in srecs:
++                if srec.name[0] == "/" or srec in orecs:
++                    continue
++                for orec in orecs:
++                    if (srec.name == orec.name and
++                        srec.relation == orec.relation and
++                        checkver(srec.version, orec.version)):
++                        break
++                else:
++                    return False
++            for orec in orecs:
++                if orec.name[0] == "/" or orec in srecs:
++                    continue
++                for srec in srecs:
++                    if (srec.name == orec.name and
++                        srec.relation == orec.relation and
++                        checkver(srec.version, orec.version)):
++                        break
++                else:
++                    return False
+         return True
+ 
+     def coexists(self, other):
+diff --git a/smart/backends/rpm/header.py b/smart/backends/rpm/header.py
+index 31786cc..4880f43 100644
+--- a/smart/backends/rpm/header.py
++++ b/smart/backends/rpm/header.py
+@@ -292,6 +292,7 @@ class RPMHeaderLoader(Loader):
+                     f = [0]
+                 elif type(f) != list:
+                     f = [f]
++                recdict = {}
+                 reqdict = {}
+                 for i in range(len(n)):
+                     ni = n[i]
+@@ -308,10 +309,16 @@ class RPMHeaderLoader(Loader):
+                             # RPMSENSE_SCRIPT_PREUN |
+                             # RPMSENSE_SCRIPT_POST |
+                             # RPMSENSE_SCRIPT_POSTUN == 7744
+-                            reqdict[(f[i]&7744 and PreReq or Req,
+-                                     intern(ni), r, vi)] = True
++                            if (f[i]&rpm.RPMSENSE_MISSINGOK):
++                                recdict[(f[i]&7744 and PreReq or Req,
++                                         intern(ni), r, vi)] = True
++                            else:
++                                reqdict[(f[i]&7744 and PreReq or Req,
++                                         intern(ni), r, vi)] = True
++                recargs = collapse_libc_requires(recdict.keys())
+                 reqargs = collapse_libc_requires(reqdict.keys())
+             else:
++                recargs = None
+                 reqargs = None
+ 
+             n = h[1054] # RPMTAG_CONFLICTNAME
+@@ -365,7 +372,7 @@ class RPMHeaderLoader(Loader):
+                 versionarch = "%s@%s" % (distversion, arch)
+ 
+             pkg = self.buildPackage((Pkg, name, versionarch),
+-                                    prvargs, reqargs, upgargs, cnfargs)
++                                    prvargs, reqargs, upgargs, cnfargs, recargs)
+             pkg.loaders[self] = offset
+             self._offsets[offset] = pkg
+             self._groups[pkg] = intern(h[rpm.RPMTAG_GROUP])
+@@ -583,8 +590,8 @@ class URPMILoader(RPMHeaderListLoader):
+     def setErrataFlags(self, flagdict):
+         self._flagdict = flagdict
+     
+-    def buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs):
+-        pkg = Loader.buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs)
++    def buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs, recargs):
++        pkg = Loader.buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs, recargs)
+         name = pkgargs[1]
+         if hasattr(self, '_flagdict') and self._flagdict and name in self._flagdict:
+             if sysconf.getReadOnly():
+diff --git a/smart/backends/rpm/metadata.py b/smart/backends/rpm/metadata.py
+index 2c54f39..568fe06 100644
+--- a/smart/backends/rpm/metadata.py
++++ b/smart/backends/rpm/metadata.py
+@@ -165,6 +165,7 @@ class RPMMetaDataLoader(Loader):
+         distepoch = None
+         info = {}
+         reqdict = {}
++        recdict = {}
+         prvdict = {}
+         upgdict = {}
+         cnfdict = {}
+@@ -287,12 +288,16 @@ class RPMMetaDataLoader(Loader):
+ 
+                     lasttag = queue[-1].tag
+                     if lasttag == REQUIRES:
+-                        if elem.get("pre") == "1":
+-                            reqdict[(RPMPreRequires,
+-                                     ename, erelation, eversion)] = True
++                        if elem.get("missingok") == "1":
++                            recdict[(RPMRequires,
++                                    ename, erelation, eversion)] = True
+                         else:
+-                            reqdict[(RPMRequires,
+-                                     ename, erelation, eversion)] = True
++                            if elem.get("pre") == "1":
++                                reqdict[(RPMPreRequires,
++                                        ename, erelation, eversion)] = True
++                            else:
++                                reqdict[(RPMRequires,
++                                        ename, erelation, eversion)] = True
+ 
+                     elif lasttag == PROVIDES:
+                         if ename[0] == "/":
+@@ -328,6 +333,12 @@ class RPMMetaDataLoader(Loader):
+                                        (RPMProvides, x[1], x[3]) in prvdict or
+                                        system_provides.match(*x[:3]))]
+                     reqargs = collapse_libc_requires(reqargs)
++
++                    recargs = [x for x in recdict
++                               if not ((x[2] is None or "=" in x[2]) and
++                                       (RPMProvides, x[1], x[3]) in prvdict or
++                                       system_provides.match(*x[:3]))]
++
+                     prvargs = prvdict.keys()
+                     cnfargs = cnfdict.keys()
+                     upgargs = upgdict.keys()
+@@ -339,7 +350,7 @@ class RPMMetaDataLoader(Loader):
+                         versionarch = "%s@%s" % (distversion, arch)
+ 
+                     pkg = self.buildPackage((RPMPackage, name, versionarch),
+-                                            prvargs, reqargs, upgargs, cnfargs)
++                                            prvargs, reqargs, upgargs, cnfargs, recargs)
+                     pkg.loaders[self] = info
+ 
+                     # Store the provided files for future usage.
+@@ -362,6 +373,7 @@ class RPMMetaDataLoader(Loader):
+                     distepoch = None
+                     pkgid = None
+                     reqdict.clear()
++                    recdict.clear()
+                     prvdict.clear()
+                     upgdict.clear()
+                     cnfdict.clear()
+diff --git a/smart/cache.py b/smart/cache.py
+index b829825..cec8bb3 100644
+--- a/smart/cache.py
++++ b/smart/cache.py
+@@ -32,7 +32,8 @@ class Package(object):
+         self.name = name
+         self.version = version
+         self.provides = ()
+-        self.requires = ()
++        self.requires = []
++        self.recommends = []
+         self.upgrades = ()
+         self.conflicts = ()
+         self.installed = False
+@@ -55,7 +56,9 @@ class Package(object):
+             fk([x for x in self.provides if x.name[0] != "/"]) !=
+             fk([x for x in other.provides if x.name[0] != "/"]) or
+             fk([x for x in self.requires if x.name[0] != "/"]) !=
+-            fk([x for x in other.requires if x.name[0] != "/"])):
++            fk([x for x in other.requires if x.name[0] != "/"]) or
++            fk([x for x in self.recommends if x.name[0] != "/"]) !=
++            fk([x for x in other.recommends if x.name[0] != "/"])):
+             return False
+         return True
+ 
+@@ -110,6 +113,7 @@ class Package(object):
+                 self.version,
+                 self.provides,
+                 self.requires,
++                self.recommends,
+                 self.upgrades,
+                 self.conflicts,
+                 self.installed,
+@@ -122,6 +126,7 @@ class Package(object):
+          self.version,
+          self.provides,
+          self.requires,
++         self.recommends,
+          self.upgrades,
+          self.conflicts,
+          self.installed,
+@@ -274,6 +279,7 @@ class Provides(object):
+         self.version = version
+         self.packages = []
+         self.requiredby = ()
++        self.recommendedby = ()
+         self.upgradedby = ()
+         self.conflictedby = ()
+ 
+@@ -401,7 +407,7 @@ class Loader(object):
+     def loadFileProvides(self, fndict):
+         pass
+ 
+-    def buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs):
++    def buildPackage(self, pkgargs, prvargs, reqargs, upgargs, cnfargs, recargs = None):
+         cache = self._cache
+         pkg = pkgargs[0](*pkgargs[1:])
+         relpkgs = []
+@@ -427,6 +433,17 @@ class Loader(object):
+                 relpkgs.append(req.packages)
+                 pkg.requires.append(req)
+ 
++        if recargs:
++            pkg.recommends = []
++            for args in recargs:
++                rec = cache._objmap.get(args)
++                if not rec:
++                    rec = args[0](*args[1:])
++                    cache._objmap[args] = rec
++                    cache._recommends.append(rec)
++                relpkgs.append(rec.packages)
++                pkg.recommends.append(rec)
++
+         if upgargs:
+             pkg.upgrades = []
+             for args in upgargs:
+@@ -572,6 +589,7 @@ class Cache(object):
+         self._packages = []
+         self._provides = []
+         self._requires = []
++        self._recommends = []
+         self._upgrades = []
+         self._conflicts = []
+         self._objmap = {}
+@@ -581,6 +599,8 @@ class Cache(object):
+             del prv.packages[:]
+             if prv.requiredby:
+                 del prv.requiredby[:]
++            if prv.recommendedby:
++                del prv.recommendedby[:]
+             if prv.upgradedby:
+                 del prv.upgradedby[:]
+             if prv.conflictedby:
+@@ -589,6 +609,10 @@ class Cache(object):
+             del req.packages[:]
+             if req.providedby:
+                 del req.providedby[:]
++        for rec in self._recommends:
++            del rec.packages[:]
++            if rec.providedby:
++                del rec.providedby[:]
+         for upg in self._upgrades:
+             del upg.packages[:]
+             if upg.providedby:
+@@ -600,6 +624,7 @@ class Cache(object):
+         del self._packages[:]
+         del self._provides[:]
+         del self._requires[:]
++        del self._recommends[:]
+         del self._upgrades[:]
+         del self._conflicts[:]
+         self._objmap.clear()
+@@ -621,6 +646,7 @@ class Cache(object):
+         packages = {}
+         provides = {}
+         requires = {}
++        recommends = {}
+         upgrades = {}
+         conflicts = {}
+         objmap = self._objmap
+@@ -646,6 +672,11 @@ class Cache(object):
+                         if req not in requires:
+                             objmap[req.getInitArgs()] = req
+                             requires[req] = True
++                    for rec in pkg.recommends[:]:
++                        rec.packages.append(pkg)
++                        if rec not in recommends:
++                            objmap[rec.getInitArgs()] = rec
++                            recommends[rec] = True
+                     for upg in pkg.upgrades:
+                         upg.packages.append(pkg)
+                         if upg not in upgrades:
+@@ -659,6 +690,7 @@ class Cache(object):
+         self._packages[:] = packages.keys()
+         self._provides[:] = provides.keys()
+         self._requires[:] = requires.keys()
++        self._recommends[:] = recommends.keys()
+         self._upgrades[:] = upgrades.keys()
+         self._conflicts[:] = conflicts.keys()
+ 
+@@ -710,6 +742,14 @@ class Cache(object):
+                     lst.append(req)
+                 else:
+                     reqnames[name] = [req]
++        recnames = {}
++        for rec in self._recommends:
++            for name in rec.getMatchNames():
++                lst = recnames.get(name)
++                if lst:
++                    lst.append(rec)
++                else:
++                    recnames[name] = [rec]
+         upgnames = {}
+         for upg in self._upgrades:
+             for name in upg.getMatchNames():
+@@ -739,6 +779,18 @@ class Cache(object):
+                             prv.requiredby.append(req)
+                         else:
+                             prv.requiredby = [req]
++            lst = recnames.get(prv.name)
++            if lst:
++                for rec in lst:
++                    if rec.matches(prv):
++                        if rec.providedby:
++                            rec.providedby.append(prv)
++                        else:
++                            rec.providedby = [prv]
++                        if prv.recommendedby:
++                            prv.recommendedby.append(rec)
++                        else:
++                            prv.recommendedby = [rec]
+             lst = upgnames.get(prv.name)
+             if lst:
+                 for upg in lst:
+@@ -782,6 +834,12 @@ class Cache(object):
+         else:
+             return [x for x in self._requires if x.name == name]
+ 
++    def getRecommends(self, name=None):
++        if not name:
++            return self._recommends
++        else:
++            return [x for x in self._recommends if x.name == name]
++
+     def getUpgrades(self, name=None):
+         if not name:
+             return self._upgrades
+@@ -807,6 +865,12 @@ class Cache(object):
+                 for req in self._requires:
+                     if prvname in req.getMatchNames() and req.matches(prv):
+                         searcher.addResult(req)
++        if searcher.recommends:
++            for prv in searcher.recommends:
++                prvname = prv.name
++                for req in self._recommends:
++                    if prvname in req.getMatchNames() and req.matches(prv):
++                        searcher.addResult(req)
+         if searcher.upgrades:
+             for prv in searcher.upgrades:
+                 prvname = prv.name
+@@ -839,6 +903,7 @@ class Cache(object):
+         self._packages = state["_packages"]
+         provides = {}
+         requires = {}
++        recommends = {}
+         upgrades = {}
+         conflicts = {}
+         for pkg in self._packages:
+@@ -848,6 +913,9 @@ class Cache(object):
+             for req in pkg.requires:
+                 req.packages.append(pkg)
+                 requires[req] = True
++            for rec in pkg.recommends:
++                rec.packages.append(pkg)
++                recommends[rec] = True
+             for upg in pkg.upgrades:
+                 upg.packages.append(pkg)
+                 upgrades[upg] = True
+@@ -856,6 +924,7 @@ class Cache(object):
+                 conflicts[cnf] = True
+         self._provides = provides.keys()
+         self._requires = requires.keys()
++        self._recommends = recommends.keys()
+         self._upgrades = upgrades.keys()
+         self._conflicts = conflicts.keys()
+         self._objmap = {}
+diff --git a/smart/ccache.c b/smart/ccache.c
+index 7541e26..7193185 100644
+--- a/smart/ccache.c
++++ b/smart/ccache.c
+@@ -82,6 +82,7 @@ typedef struct {
+     PyObject *version;
+     PyObject *provides;
+     PyObject *requires;
++    PyObject *recommends;
+     PyObject *upgrades;
+     PyObject *conflicts;
+     PyObject *installed;
+@@ -96,6 +97,7 @@ typedef struct {
+     PyObject *version;
+     PyObject *packages;
+     PyObject *requiredby;
++    PyObject *recommendedby;
+     PyObject *upgradedby;
+     PyObject *conflictedby;
+ } ProvidesObject;
+@@ -123,6 +125,7 @@ typedef struct {
+     PyObject *_packages;
+     PyObject *_provides;
+     PyObject *_requires;
++    PyObject *_recommends;
+     PyObject *_upgrades;
+     PyObject *_conflicts;
+     PyObject *_objmap;
+@@ -211,7 +214,8 @@ Package_init(PackageObject *self, PyObject *args)
+     Py_INCREF(self->name);
+     Py_INCREF(self->version);
+     self->provides = PyTuple_New(0);
+-    self->requires = PyTuple_New(0);
++    self->requires = PyList_New(0);
++    self->recommends = PyList_New(0);
+     self->upgrades = PyTuple_New(0);
+     self->conflicts = PyTuple_New(0);
+     Py_INCREF(Py_False);
+@@ -228,6 +232,7 @@ Package_traverse(PackageObject *self, visitproc visit, void *arg)
+ {
+     Py_VISIT(self->provides);
+     Py_VISIT(self->requires);
++    Py_VISIT(self->recommends);
+     Py_VISIT(self->upgrades);
+     Py_VISIT(self->conflicts);
+     Py_VISIT(self->loaders);
+@@ -239,6 +244,7 @@ Package_clear(PackageObject *self)
+ {
+     Py_CLEAR(self->provides);
+     Py_CLEAR(self->requires);
++    Py_CLEAR(self->recommends);
+     Py_CLEAR(self->upgrades);
+     Py_CLEAR(self->conflicts);
+     Py_CLEAR(self->loaders);
+@@ -252,6 +258,7 @@ Package_dealloc(PackageObject *self)
+     Py_XDECREF(self->version);
+     Py_XDECREF(self->provides);
+     Py_XDECREF(self->requires);
++    Py_XDECREF(self->recommends);
+     Py_XDECREF(self->upgrades);
+     Py_XDECREF(self->conflicts);
+     Py_XDECREF(self->installed);
+@@ -453,6 +460,46 @@ Package_equals(PackageObject *self, PackageObject *other)
+         }
+     }
+ 
++    ilen = 0;
++    jlen = 0;
++    for (i = 0; i != PyList_GET_SIZE(self->recommends); i++) {
++        PyObject *item = PyList_GET_ITEM(self->recommends, i);
++        if (!PyObject_IsInstance(item, (PyObject *)&Depends_Type)) {
++            PyErr_SetString(PyExc_TypeError, "Depends instance expected");
++            return NULL;
++        }
++        if (STR(((DependsObject *)item)->name)[0] != '/')
++            ilen += 1;
++    }
++    for (j = 0; j != PyList_GET_SIZE(other->recommends); j++) {
++        PyObject *item = PyList_GET_ITEM(other->recommends, j);
++        if (!PyObject_IsInstance(item, (PyObject *)&Depends_Type)) {
++            PyErr_SetString(PyExc_TypeError, "Depends instance expected");
++            return NULL;
++        }
++        if (STR(((DependsObject *)item)->name)[0] != '/')
++            jlen += 1;
++    }
++    if (ilen != jlen) {
++        ret = Py_False;
++        goto exit;
++    }
++
++    ilen = PyList_GET_SIZE(self->recommends);
++    jlen = PyList_GET_SIZE(other->recommends);
++    for (i = 0; i != ilen; i++) {
++        PyObject *item = PyList_GET_ITEM(self->recommends, i);
++        if (STR(((DependsObject *)item)->name)[0] != '/') {
++            for (j = 0; j != jlen; j++)
++                if (item == PyList_GET_ITEM(other->recommends, j))
++                    break;
++            if (j == jlen) {
++                ret = Py_False;
++                goto exit;
++            }
++        }
++    }
++
+ exit:
+     Py_INCREF(ret);
+     return ret;
+@@ -606,13 +653,14 @@ Package_getPriority(PackageObject *self, PyObject *args)
+ static PyObject *
+ Package__getstate__(PackageObject *self, PyObject *args)
+ {
+-    PyObject *state = PyTuple_New(10);
++    PyObject *state = PyTuple_New(11);
+     if (!state) return NULL;
+ 
+     Py_INCREF(self->name);
+     Py_INCREF(self->version);
+     Py_INCREF(self->provides);
+     Py_INCREF(self->requires);
++    Py_INCREF(self->recommends);
+     Py_INCREF(self->upgrades);
+     Py_INCREF(self->conflicts);
+     Py_INCREF(self->installed);
+@@ -620,16 +668,17 @@ Package__getstate__(PackageObject *self, PyObject *args)
+     Py_INCREF(self->priority);
+     Py_INCREF(self->loaders);
+ 
+-    PyTuple_SET_ITEM(state, 0, self->name);
+-    PyTuple_SET_ITEM(state, 1, self->version);
+-    PyTuple_SET_ITEM(state, 2, self->provides);
+-    PyTuple_SET_ITEM(state, 3, self->requires);
+-    PyTuple_SET_ITEM(state, 4, self->upgrades);
+-    PyTuple_SET_ITEM(state, 5, self->conflicts);
+-    PyTuple_SET_ITEM(state, 6, self->installed);
+-    PyTuple_SET_ITEM(state, 7, self->essential);
+-    PyTuple_SET_ITEM(state, 8, self->priority);
+-    PyTuple_SET_ITEM(state, 9, self->loaders);
++    PyTuple_SET_ITEM(state,  0, self->name);
++    PyTuple_SET_ITEM(state,  1, self->version);
++    PyTuple_SET_ITEM(state,  2, self->provides);
++    PyTuple_SET_ITEM(state,  3, self->requires);
++    PyTuple_SET_ITEM(state,  4, self->recommends);
++    PyTuple_SET_ITEM(state,  5, self->upgrades);
++    PyTuple_SET_ITEM(state,  6, self->conflicts);
++    PyTuple_SET_ITEM(state,  7, self->installed);
++    PyTuple_SET_ITEM(state,  8, self->essential);
++    PyTuple_SET_ITEM(state,  9, self->priority);
++    PyTuple_SET_ITEM(state, 10, self->loaders);
+ 
+     return state;
+ }
+@@ -637,7 +686,7 @@ Package__getstate__(PackageObject *self, PyObject *args)
+ static PyObject *
+ Package__setstate__(PackageObject *self, PyObject *state)
+ {
+-    if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != 10) {
++    if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != 11) {
+         PyErr_SetString(StateVersionError, "");
+         return NULL;
+     }
+@@ -645,18 +694,20 @@ Package__setstate__(PackageObject *self, PyObject *state)
+     self->version = PyTuple_GET_ITEM(state, 1);
+     self->provides = PyTuple_GET_ITEM(state, 2);
+     self->requires = PyTuple_GET_ITEM(state, 3);
+-    self->upgrades = PyTuple_GET_ITEM(state, 4);
+-    self->conflicts = PyTuple_GET_ITEM(state, 5);
+-    self->installed = PyTuple_GET_ITEM(state, 6);
+-    self->essential = PyTuple_GET_ITEM(state, 7);
+-    self->priority = PyTuple_GET_ITEM(state, 8);
+-    self->loaders = PyTuple_GET_ITEM(state, 9);
++    self->recommends = PyTuple_GET_ITEM(state, 4);
++    self->upgrades = PyTuple_GET_ITEM(state, 5);
++    self->conflicts = PyTuple_GET_ITEM(state, 6);
++    self->installed = PyTuple_GET_ITEM(state, 7);
++    self->essential = PyTuple_GET_ITEM(state, 8);
++    self->priority = PyTuple_GET_ITEM(state, 9);
++    self->loaders = PyTuple_GET_ITEM(state, 10);
+ 
+ 
+     Py_INCREF(self->name);
+     Py_INCREF(self->version);
+     Py_INCREF(self->provides);
+     Py_INCREF(self->requires);
++    Py_INCREF(self->recommends);
+     Py_INCREF(self->upgrades);
+     Py_INCREF(self->conflicts);
+     Py_INCREF(self->installed);
+@@ -686,6 +737,7 @@ static PyMemberDef Package_members[] = {
+     {"version", T_OBJECT, OFF(version), 0, 0},
+     {"provides", T_OBJECT, OFF(provides), 0, 0},
+     {"requires", T_OBJECT, OFF(requires), 0, 0},
++    {"recommends", T_OBJECT, OFF(recommends), 0, 0},
+     {"upgrades", T_OBJECT, OFF(upgrades), 0, 0},
+     {"conflicts", T_OBJECT, OFF(conflicts), 0, 0},
+     {"installed", T_OBJECT, OFF(installed), 0, 0},
+@@ -750,6 +802,7 @@ Provides_init(ProvidesObject *self, PyObject *args)
+     Py_INCREF(self->version);
+     self->packages = PyList_New(0);
+     self->requiredby = PyTuple_New(0);
++    self->recommendedby = PyTuple_New(0);
+     self->upgradedby = PyTuple_New(0);
+     self->conflictedby = PyTuple_New(0);
+     return 0;
+@@ -760,6 +813,7 @@ Provides_traverse(ProvidesObject *self, visitproc visit, void *arg)
+ {
+     Py_VISIT(self->packages);
+     Py_VISIT(self->requiredby);
++    Py_VISIT(self->recommendedby);
+     Py_VISIT(self->upgradedby);
+     Py_VISIT(self->conflictedby);
+     return 0;
+@@ -770,6 +824,7 @@ Provides_clear(ProvidesObject *self)
+ {
+     Py_CLEAR(self->packages);
+     Py_CLEAR(self->requiredby);
++    Py_CLEAR(self->recommendedby);
+     Py_CLEAR(self->upgradedby);
+     Py_CLEAR(self->conflictedby);
+     return 0;
+@@ -782,6 +837,7 @@ Provides_dealloc(ProvidesObject *self)
+     Py_XDECREF(self->version);
+     Py_XDECREF(self->packages);
+     Py_XDECREF(self->requiredby);
++    Py_XDECREF(self->recommendedby);
+     Py_XDECREF(self->upgradedby);
+     Py_XDECREF(self->conflictedby);
+     self->ob_type->tp_free((PyObject *)self);
+@@ -960,6 +1016,7 @@ static PyMemberDef Provides_members[] = {
+     {"version", T_OBJECT, OFF(version), 0, 0},
+     {"packages", T_OBJECT, OFF(packages), 0, 0},
+     {"requiredby", T_OBJECT, OFF(requiredby), 0, 0},
++    {"recommendedby", T_OBJECT, OFF(recommendedby), 0, 0},
+     {"upgradedby", T_OBJECT, OFF(upgradedby), 0, 0},
+     {"conflictedby", T_OBJECT, OFF(conflictedby), 0, 0},
+     {NULL}
+@@ -1555,6 +1612,7 @@ Loader_buildPackage(LoaderObject *self, PyObject *args)
+     PyObject *reqargs;
+     PyObject *upgargs;
+     PyObject *cnfargs;
++    PyObject *recargs = NULL;
+     PyObject *callargs;
+     
+     PyObject *pkg;
+@@ -1574,9 +1632,10 @@ Loader_buildPackage(LoaderObject *self, PyObject *args)
+ 
+     cache = (CacheObject *)self->_cache;
+ 
+-    if (!PyArg_ParseTuple(args, "O!O&O&O&O&", &PyTuple_Type, &pkgargs,
++    if (!PyArg_ParseTuple(args, "O!O&O&O&O&|O&", &PyTuple_Type, &pkgargs,
+                           mylist, &prvargs, mylist, &reqargs,
+-                          mylist, &upgargs, mylist, &cnfargs))
++                          mylist, &upgargs, mylist, &cnfargs,
++                          mylist, &recargs))
+         return NULL;
+ 
+     if (PyTuple_GET_SIZE(pkgargs) < 2) {
+@@ -1701,6 +1760,59 @@ Loader_buildPackage(LoaderObject *self, PyObject *args)
+         }
+     }
+ 
++    /* if recargs: */
++    if (recargs) {
++        int i = 0;
++        int len = PyList_GET_SIZE(recargs);
++        /* pkg.recommends = [] */
++        Py_DECREF(pkgobj->recommends);
++        pkgobj->recommends = PyList_New(len);
++        /* for args in recargs: */
++        for (; i != len; i++) {
++            PyObject *args = PyList_GET_ITEM(recargs, i);
++            DependsObject *recobj;
++            PyObject *rec;
++            
++            if (!PyTuple_Check(args)) {
++                PyErr_SetString(PyExc_TypeError,
++                                "Item in recargs is not a tuple");
++                return NULL;
++            }
++
++            /* rec = cache._objmap.get(args) */
++            rec = PyDict_GetItem(cache->_objmap, args);
++            recobj = (DependsObject *)rec;
++
++            /* if not rec: */
++            if (!rec) {
++                if (!PyTuple_Check(args) || PyTuple_GET_SIZE(args) < 2) {
++                    PyErr_SetString(PyExc_ValueError, "Invalid recargs tuple");
++                    return NULL;
++                }
++                /* rec = args[0](*args[1:]) */
++                callargs = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
++                rec = PyObject_CallObject(PyTuple_GET_ITEM(args, 0), callargs);
++                Py_DECREF(callargs);
++                if (!rec) return NULL;
++                recobj = (DependsObject *)rec;
++
++                /* cache._objmap[args] = rec */
++                PyDict_SetItem(cache->_objmap, args, rec);
++                Py_DECREF(rec);
++
++                /* cache._recommends.append(rec) */
++                PyList_Append(cache->_recommends, rec);
++            }
++
++            /* relpkgs.append(rec.packages) */
++            PyList_Append(relpkgs, recobj->packages);
++
++            /* pkg.recommends.append(rec) */
++            Py_INCREF(rec);
++            PyList_SET_ITEM(pkgobj->recommends, i, rec);
++        }
++    }
++
+     /* if upgargs: */
+     if (upgargs) {
+         int i = 0;
+@@ -2391,6 +2503,7 @@ Cache_init(CacheObject *self, PyObject *args)
+     self->_packages = PyList_New(0);
+     self->_provides = PyList_New(0);
+     self->_requires = PyList_New(0);
++    self->_recommends = PyList_New(0);
+     self->_upgrades = PyList_New(0);
+     self->_conflicts = PyList_New(0);
+     self->_objmap = PyDict_New();
+@@ -2404,6 +2517,7 @@ Cache_traverse(CacheObject *self, visitproc visit, void *arg)
+     Py_VISIT(self->_packages);
+     Py_VISIT(self->_provides);
+     Py_VISIT(self->_requires);
++    Py_VISIT(self->_recommends);
+     Py_VISIT(self->_upgrades);
+     Py_VISIT(self->_conflicts);
+     Py_VISIT(self->_objmap);
+@@ -2417,6 +2531,7 @@ Cache_clear(CacheObject *self)
+     Py_CLEAR(self->_packages);
+     Py_CLEAR(self->_provides);
+     Py_CLEAR(self->_requires);
++    Py_CLEAR(self->_recommends);
+     Py_CLEAR(self->_upgrades);
+     Py_CLEAR(self->_conflicts);
+     Py_CLEAR(self->_objmap);
+@@ -2430,6 +2545,7 @@ Cache_dealloc(CacheObject *self)
+     Py_XDECREF(self->_packages);
+     Py_XDECREF(self->_provides);
+     Py_XDECREF(self->_requires);
++    Py_XDECREF(self->_recommends);
+     Py_XDECREF(self->_upgrades);
+     Py_XDECREF(self->_conflicts);
+     Py_XDECREF(self->_objmap);
+@@ -2449,6 +2565,8 @@ Cache_reset(CacheObject *self, PyObject *args)
+         LIST_CLEAR(prvobj->packages);
+         if (PyList_Check(prvobj->requiredby))
+             LIST_CLEAR(prvobj->requiredby);
++        if (PyList_Check(prvobj->recommendedby))
++            LIST_CLEAR(prvobj->recommendedby);
+         if (PyList_Check(prvobj->upgradedby))
+             LIST_CLEAR(prvobj->upgradedby);
+         if (PyList_Check(prvobj->conflictedby))
+@@ -2464,6 +2582,16 @@ Cache_reset(CacheObject *self, PyObject *args)
+         if (PyList_Check(reqobj->providedby))
+             LIST_CLEAR(reqobj->providedby);
+     }
++    len = PyList_GET_SIZE(self->_recommends);
++    for (i = 0; i != len; i++) {
++        DependsObject *reqobj;
++        PyObject *req;
++        req = PyList_GET_ITEM(self->_recommends, i);
++        reqobj = (DependsObject *)req;
++        LIST_CLEAR(reqobj->packages);
++        if (PyList_Check(reqobj->providedby))
++            LIST_CLEAR(reqobj->providedby);
++    }
+     len = PyList_GET_SIZE(self->_upgrades);
+     for (i = 0; i != len; i++) {
+         DependsObject *upgobj;
+@@ -2487,6 +2615,7 @@ Cache_reset(CacheObject *self, PyObject *args)
+     LIST_CLEAR(self->_packages);
+     LIST_CLEAR(self->_provides);
+     LIST_CLEAR(self->_requires);
++    LIST_CLEAR(self->_recommends);
+     LIST_CLEAR(self->_upgrades);
+     LIST_CLEAR(self->_conflicts);
+     PyDict_Clear(self->_objmap);
+@@ -2534,6 +2663,7 @@ Cache__reload(CacheObject *self, PyObject *args)
+       packages = {}
+       provides = {}
+       requires = {}
++      recommends = {}
+       upgrades = {}
+       conflicts = {}
+       objmap = self._objmap
+@@ -2541,11 +2671,12 @@ Cache__reload(CacheObject *self, PyObject *args)
+     PyObject *packages = PyDict_New();
+     PyObject *provides = PyDict_New();
+     PyObject *requires = PyDict_New();
++    PyObject *recommends = PyDict_New();
+     PyObject *upgrades = PyDict_New();
+     PyObject *conflicts = PyDict_New();
+     PyObject *objmap = self->_objmap;
+     int i, ilen;
+-    if (!packages || !provides || !requires || !conflicts)
++    if (!packages || !provides || !requires || !recommends || !conflicts )
+         return NULL;
+ 
+     /* for loader in loaders: */
+@@ -2679,6 +2810,30 @@ Cache__reload(CacheObject *self, PyObject *args)
+                 }
+ 
+                 /*
++                   for rec in pkg.recommends:
++                       rec.packages.append(pkg)
++                       if rec not in recommends:
++                           recommends[rec] = True
++                           objmap[rec.getInitArgs()] = rec
++                */
++                if (PyList_Check(pkg->recommends)) {
++                    klen = PyList_GET_SIZE(pkg->recommends);
++                    for (k = 0; k != klen; k++) {
++                        PyObject *rec = PyList_GET_ITEM(pkg->recommends, k);
++                        PyList_Append(((DependsObject *)rec)->packages,
++                                      (PyObject *)pkg);
++                        if (!PyDict_GetItem(recommends, rec)) {
++                            PyDict_SetItem(recommends, rec, Py_True);
++                            args = PyObject_CallMethod(rec, "getInitArgs",
++                                                       NULL);
++                            if (!args) return NULL;
++                            PyDict_SetItem(objmap, args, rec);
++                            Py_DECREF(args);
++                        }
++                    }
++                }
++
++                /*
+                    for upg in pkg.upgrades:
+                        upg.packages.append(pkg)
+                        if upg not in upgrades:
+@@ -2747,6 +2902,11 @@ Cache__reload(CacheObject *self, PyObject *args)
+     self->_requires = PyDict_Keys(requires);
+     Py_DECREF(requires);
+ 
++    /* self._recommends[:] = recommends.keys() */
++    Py_DECREF(self->_recommends);
++    self->_recommends = PyDict_Keys(recommends);
++    Py_DECREF(recommends);
++
+     /* self._upgrades[:] = upgrades.keys() */
+     Py_DECREF(self->_upgrades);
+     self->_upgrades = PyDict_Keys(upgrades);
+@@ -2852,7 +3012,7 @@ PyObject *
+ Cache_linkDeps(CacheObject *self, PyObject *args)
+ {
+     int i, j, len;
+-    PyObject *reqnames, *upgnames, *cnfnames;
++    PyObject *reqnames, *recnames, *upgnames, *cnfnames;
+     PyObject *lst;
+ 
+     /* reqnames = {} */
+@@ -2896,6 +3056,47 @@ Cache_linkDeps(CacheObject *self, PyObject *args)
+         Py_DECREF(seq);
+     }
+ 
++    /* recnames = {} */
++    recnames = PyDict_New();
++    /* for rec in self._recommends: */
++    len = PyList_GET_SIZE(self->_recommends);
++    for (i = 0; i != len; i++) {
++        PyObject *rec = PyList_GET_ITEM(self->_recommends, i);
++
++        /* for name in rec.getMatchNames(): */
++        PyObject *names = PyObject_CallMethod(rec, "getMatchNames", NULL);
++        PyObject *seq = PySequence_Fast(names, "getMatchNames() returned "
++                                               "non-sequence object");
++        int nameslen;
++        if (!seq) return NULL;
++        nameslen = PySequence_Fast_GET_SIZE(seq);
++        for (j = 0; j != nameslen; j++) {
++            PyObject *name = PySequence_Fast_GET_ITEM(seq, j);
++            
++            /* lst = recnames.get(name) */
++            lst = PyDict_GetItem(recnames, name);
++
++            /* 
++               if lst:
++                   lst.append(rec)
++               else:
++                   recnames[name] = [rec]
++            */
++            if (lst) {
++                PyList_Append(lst, rec);
++            } else {
++                lst = PyList_New(1);
++                Py_INCREF(rec);
++                PyList_SET_ITEM(lst, 0, rec);
++                PyDict_SetItem(recnames, name, lst);
++                Py_DECREF(lst);
++            }
++        }
++
++        Py_DECREF(names);
++        Py_DECREF(seq);
++    }
++
+     /* upgnames = {} */
+     upgnames = PyDict_New();
+     /* for upg in self._upgrades: */
+@@ -3035,6 +3236,56 @@ Cache_linkDeps(CacheObject *self, PyObject *args)
+             }
+         }
+ 
++        /* lst = recnames.get(prv.name) */
++        lst = PyDict_GetItem(recnames, prv->name);
++
++        /* if lst: */
++        if (lst) {
++            /* for rec in lst: */
++            int reclen = PyList_GET_SIZE(lst);
++            for (j = 0; j != reclen; j++) {
++                DependsObject *rec = (DependsObject *)PyList_GET_ITEM(lst, j);
++                /* if rec.matches(prv): */
++                PyObject *ret = PyObject_CallMethod((PyObject *)rec, "matches",
++                                                    "O", (PyObject *)prv);
++                if (!ret) return NULL;
++                if (PyObject_IsTrue(ret)) {
++                    /*
++                       if rec.providedby:
++                           rec.providedby.append(prv)
++                       else:
++                           rec.providedby = [prv]
++                    */
++                    if (PyList_Check(rec->providedby)) {
++                        PyList_Append(rec->providedby, (PyObject *)prv);
++                    } else {
++                        PyObject *_lst = PyList_New(1);
++                        Py_INCREF(prv);
++                        PyList_SET_ITEM(_lst, 0, (PyObject *)prv);
++                        Py_DECREF(rec->providedby);
++                        rec->providedby = _lst;
++                    }
++
++                    /*
++                       if prv.recommendedby:
++                           prv.recommendedby.append(prv)
++                       else:
++                           prv.recommendedby = [prv]
++                    */
++                    if (PyList_Check(prv->recommendedby)) {
++                        PyList_Append(prv->recommendedby, (PyObject *)rec);
++                    } else {
++                        PyObject *_lst = PyList_New(1);
++                        Py_INCREF(rec);
++                        PyList_SET_ITEM(_lst, 0, (PyObject *)rec);
++                        Py_DECREF(prv->recommendedby);
++                        prv->recommendedby = _lst;
++                    }
++                }
++                Py_DECREF(ret);
++            }
++        }
++
+         /* lst = upgnames.get(prv.name) */
+         lst = PyDict_GetItem(upgnames, prv->name);
+ 
+@@ -3139,6 +3390,7 @@ Cache_linkDeps(CacheObject *self, PyObject *args)
+     }
+ 
+     Py_DECREF(reqnames);
++    Py_DECREF(recnames);
+     Py_DECREF(upgnames);
+     Py_DECREF(cnfnames);
+ 
+@@ -3215,6 +3467,29 @@ Cache_getRequires(CacheObject *self, PyObject *args)
+ }
+ 
+ PyObject *
++Cache_getRecommends(CacheObject *self, PyObject *args)
++{
++    const char *name = NULL;
++    PyObject *lst;
++    int i, len;
++    if (!PyArg_ParseTuple(args, "|s", &name))
++        return NULL;
++    if (!name) {
++        Py_INCREF(self->_recommends);
++        return self->_recommends;
++    }
++    lst = PyList_New(0);
++    len = PyList_GET_SIZE(self->_recommends);
++    for (i = 0; i != len; i++) {
++        DependsObject *rec =
++            (DependsObject*)PyList_GET_ITEM(self->_recommends, i);
++        if (strcmp(STR(rec->name), name) == 0)
++            PyList_Append(lst, (PyObject *)rec);
++    }
++    return lst;
++}
++
++PyObject *
+ Cache_getUpgrades(CacheObject *self, PyObject *args)
+ {
+     const char *name = NULL;
+@@ -3324,6 +3599,38 @@ Cache_search(CacheObject *self, PyObject *searcher)
+     }
+     Py_DECREF(lst);
+ 
++    lst = PyObject_GetAttrString(searcher, "recommends");
++    if (lst == NULL || !PyList_Check(lst)) {
++        PyErr_SetString(PyExc_TypeError, "Invalid recommends attribute");
++        return NULL;
++    }
++    for (i = 0; i != PyList_GET_SIZE(lst); i++) {
++        ProvidesObject *prv = (ProvidesObject *)PyList_GET_ITEM(lst, i);
++        for (j = 0; j != PyList_GET_SIZE(self->_recommends); j++) {
++            PyObject *rec = PyList_GET_ITEM(self->_recommends, j);
++            PyObject *names = PyObject_CallMethod(rec, "getMatchNames", NULL);
++            PyObject *seq = PySequence_Fast(names, "getMatchNames() returned "
++                                                   "non-sequence object");
++            if (seq == NULL) return NULL;
++            for (k = 0; k != PySequence_Fast_GET_SIZE(seq); k++) {
++                if (strcmp(PyString_AS_STRING(PySequence_Fast_GET_ITEM(seq, k)),
++                           PyString_AS_STRING(prv->name)) == 0) {
++                    res = PyObject_CallMethod(rec, "matches", "O", prv);
++                    if (res == NULL)
++                        return NULL;
++                    if (PyObject_IsTrue(res))
++                        CALLMETHOD(searcher, "addResult", "O", rec);
++                    Py_DECREF(res);
++                    break;
++                }
++            }
++
++            Py_DECREF(names);
++            Py_DECREF(seq);
++        }
++    }
++    Py_DECREF(lst);
++
+     lst = PyObject_GetAttrString(searcher, "upgrades");
+     if (lst == NULL || !PyList_Check(lst)) {
+         PyErr_SetString(PyExc_TypeError, "Invalid upgrades attribute");
+@@ -3420,7 +3727,7 @@ Cache__getstate__(CacheObject *self, PyObject *args)
+ static PyObject *
+ Cache__setstate__(CacheObject *self, PyObject *state)
+ {
+-    PyObject *provides, *requires, *upgrades, *conflicts;
++    PyObject *provides, *requires, *recommends, *upgrades, *conflicts;
+     int i, ilen;
+     int j, jlen;
+     
+@@ -3452,11 +3759,13 @@ Cache__setstate__(CacheObject *self, PyObject *state)
+     /*
+        provides = {}
+        requires = {}
++       recommends = {}
+        upgrades = {}
+        conflicts = {}
+     */
+     provides = PyDict_New();
+     requires = PyDict_New();
++    recommends = PyDict_New();
+     upgrades = PyDict_New();
+     conflicts = PyDict_New();
+ 
+@@ -3497,6 +3806,21 @@ Cache__setstate__(CacheObject *self, PyObject *state)
+         }
+ 
+         /*
++           for rec in pkg.recommends:
++               rec.packages.append(pkg)
++               recommends[rec] = True
++        */
++        if (PyList_Check(pkgobj->recommends)) {
++            jlen = PyList_GET_SIZE(pkgobj->recommends);
++            for (j = 0; j != jlen; j++) {
++                PyObject *rec = PyList_GET_ITEM(pkgobj->recommends, j);
++                DependsObject *recobj = (DependsObject *)rec;
++                PyList_Append(recobj->packages, pkg);
++                PyDict_SetItem(recommends, rec, Py_True);
++            }
++        }
++
++        /*
+            for upg in pkg.upgrades:
+                upg.packages.append(pkg)
+                upgrades[upg] = True
+@@ -3525,6 +3849,7 @@ Cache__setstate__(CacheObject *self, PyObject *state)
+                 PyDict_SetItem(conflicts, cnf, Py_True);
+             }
+         }
++
+     }
+ 
+     /* self._provides = provides.keys() */
+@@ -3535,6 +3860,10 @@ Cache__setstate__(CacheObject *self, PyObject *state)
+     self->_requires = PyDict_Keys(requires);
+     Py_DECREF(requires);
+ 
++    /* self._recommends = recommends.keys() */
++    self->_recommends = PyDict_Keys(recommends);
++    Py_DECREF(recommends);
++
+     /* self._upgrades = upgrades.keys() */
+     self->_upgrades = PyDict_Keys(upgrades);
+     Py_DECREF(upgrades);
+@@ -3562,6 +3891,7 @@ static PyMethodDef Cache_methods[] = {
+     {"getPackages", (PyCFunction)Cache_getPackages, METH_VARARGS, NULL},
+     {"getProvides", (PyCFunction)Cache_getProvides, METH_VARARGS, NULL},
+     {"getRequires", (PyCFunction)Cache_getRequires, METH_VARARGS, NULL},
++    {"getRecommends", (PyCFunction)Cache_getRecommends, METH_VARARGS, NULL},
+     {"getUpgrades", (PyCFunction)Cache_getUpgrades, METH_VARARGS, NULL},
+     {"getConflicts", (PyCFunction)Cache_getConflicts, METH_VARARGS, NULL},
+     {"search", (PyCFunction)Cache_search, METH_O, NULL},
+@@ -3576,6 +3906,7 @@ static PyMemberDef Cache_members[] = {
+     {"_packages", T_OBJECT, OFF(_packages), RO, 0},
+     {"_provides", T_OBJECT, OFF(_provides), RO, 0},
+     {"_requires", T_OBJECT, OFF(_requires), RO, 0},
++    {"_recommends", T_OBJECT, OFF(_recommends), RO, 0},
+     {"_upgrades", T_OBJECT, OFF(_upgrades), RO, 0},
+     {"_conflicts", T_OBJECT, OFF(_conflicts), RO, 0},
+     {"_objmap", T_OBJECT, OFF(_objmap), RO, 0},
+diff --git a/smart/commands/query.py b/smart/commands/query.py
+index 808e53a..9265cd9 100644
+--- a/smart/commands/query.py
++++ b/smart/commands/query.py
+@@ -107,6 +107,8 @@ def option_parser(**kwargs):
+                       help=_("show requires for the given packages"))
+     parser.add_option("--show-prerequires", action="store_true",
+                       help=_("show requires selecting only pre-dependencies"))
++    parser.add_option("--show-recommends", action="store_true",
++                      help=_("show recommends for the given packages"))
+     parser.add_option("--show-upgrades", action="store_true",
+                       help=_("show upgrades for the given packages"))
+     parser.add_option("--show-conflicts", action="store_true",
+@@ -488,6 +490,19 @@ def main(ctrl, opts, reloadchannels=True):
+                                 continue
+                             output.showRequiresProvidedBy(pkg, req,
+                                                           prv, prvpkg)
++        if pkg.recommends and (opts.show_recommends):
++            pkg.recommends.sort()
++            first = True
++            for req in pkg.recommends:
++                output.showRecommends(pkg, req)
++                if opts.show_providedby and req.providedby:
++                    for prv in req.providedby:
++                        prv.packages.sort()
++                        for prvpkg in prv.packages:
++                            if opts.installed and not prvpkg.installed:
++                                continue
++                            output.showRecommendsProvidedBy(pkg, req,
++                                                          prv, prvpkg)
+         if pkg.upgrades and (opts.show_upgrades or whoupgrades):
+             pkg.upgrades.sort()
+             first = True
+@@ -594,6 +609,12 @@ class NullOutput(object):
+     def showRequiresProvidedBy(self, pkg, req, prv, prvpkg):
+         pass
+ 
++    def showRecommends(self, pkg, req):
++        pass
++
++    def showRecommendsProvidedBy(self, pkg, req, prv, prvpkg):
++        pass
++
+     def showUpgrades(self, pkg, upg):
+         pass
+ 
+@@ -619,6 +640,8 @@ class TextOutput(NullOutput):
+         self._firstconflictedby = True
+         self._firstrequires = True
+         self._firstrequiresprovidedby = True
++        self._firstrecommends = True
++        self._firstrecommendsprovidedby = True
+         self._firstupgrades = True
+         self._firstupgradesprovidedby = True
+         self._firstconflicts = True
+@@ -711,6 +734,22 @@ class TextOutput(NullOutput):
+             name = str(prvpkg)
+         print "       ", "%s (%s)" % (name, prv)
+ 
++    def showRecommends(self, pkg, rec):
++        if self._firstrecommends:
++            self._firstrecommends = False
++            print " ", _("Recommends:")
++        print "   ", rec
++
++    def showRecommendsProvidedBy(self, pkg, req, prv, prvpkg):
++        if self._firstrecommendsprovidedby:
++            self._firstrecommendsprovidedby = False
++            print "     ", _("Provided By:")
++        if self.opts.hide_version:
++            name = prvpkg.name
++        else:
++            name = str(prvpkg)
++        print "       ", "%s (%s)" % (name, prv)
++
+     def showUpgrades(self, pkg, upg):
+         if self._firstupgrades:
+             self._firstupgrades = False
+@@ -797,6 +836,18 @@ class GraphVizOutput(NullOutput):
+             self._shown[req, prv] = True
+             print '    "Requires: %s" -> "Provides: %s";' % (req, prv)
+ 
++    def showRecommends(self, pkg, req):
++        if (pkg, req) not in self._shown:
++            self._shown[pkg, req] = True
++            print '    "%s" -> "Recommends: %s";' % (pkg, req)
++
++    def showRecommendsProvidedBy(self, pkg, req, prv, prvpkg):
++        self.showPackage(prvpkg)
++        self.showProvides(prvpkg, prv)
++        if (req, prv) not in self._shown:
++            self._shown[req, prv] = True
++            print '    "Recommends: %s" -> "Provides: %s";' % (req, prv)
++
+     def showUpgrades(self, pkg, upg):
+         if (pkg, upg) not in self._shown:
+             self._shown[pkg, upg] = True
+diff --git a/smart/control.py b/smart/control.py
+index fd7083a..d44abe7 100644
+--- a/smart/control.py
++++ b/smart/control.py
+@@ -447,7 +447,7 @@ class Control(object):
+         queue = marked.keys()
+         while queue:
+             pkg = queue.pop(0)
+-            for req in pkg.requires:
++            for req in pkg.requires + pkg.recommends:
+                 for prv in req.providedby:
+                     for prvpkg in prv.packages:
+                         if (prvpkg.installed and
+@@ -794,7 +794,7 @@ class Control(object):
+         pkglst = []
+         for pkg in changeset:
+             n = 0
+-            for req in pkg.requires:
++            for req in pkg.requires + pkg.recommends:
+                 for prv in req.providedby:
+                     for prvpkg in prv.packages:
+                         if changeset.get(prvpkg) is INSTALL:
+diff --git a/smart/searcher.py b/smart/searcher.py
+index 216f4ce..32eb825 100644
+--- a/smart/searcher.py
++++ b/smart/searcher.py
+@@ -45,9 +45,9 @@ class Searcher(object):
+ 
+     - provides is matched in Provides.search(), for the same reason.
+ 
+-    - requires, upgrades, and conflicts don't have special searching
+-      methods. Instead, their usual match() method is given an instance
+-      of the Provides type.
++    - requires, recommends, upgrades, and conflicts don't have special
++      searching methods. Instead, their usual match() method is given
++      an instance of the Provides type.
+ 
+     - group, path, url, and other information which is found by
+       PackageInfo, is searched by the Loader.search() method and
+@@ -62,6 +62,7 @@ class Searcher(object):
+         self.nameversion = []
+         self.provides = []
+         self.requires = []
++        self.recommends = []
+         self.upgrades = []
+         self.conflicts = []
+         self.path = []
+@@ -76,6 +77,7 @@ class Searcher(object):
+         del self.nameversion[:]
+         del self.provides[:]
+         del self.requires[:]
++        del self.recommends[:]
+         del self.upgrades[:]
+         del self.conflicts[:]
+         del self.path[:]
+@@ -122,6 +124,8 @@ class Searcher(object):
+             self.addProvides(s[9:], cutoff)
+         elif s.startswith("requires:"):
+             self.addRequires(s[9:])
++        elif s.startswith("recommends:"):
++            self.addRecommends(s[11:])
+         elif s.startswith("upgrades:"):
+             self.addUpgrades(s[9:])
+         elif s.startswith("conflicts:"):
+@@ -151,6 +155,7 @@ class Searcher(object):
+         return s and (
+                 s.startswith("provides:") or
+                 s.startswith("requires:") or
++                s.startswith("recommends:") or
+                 s.startswith("upgrades:") or
+                 s.startswith("conflicts:") or
+                 s.startswith("url:") or
+@@ -182,6 +187,9 @@ class Searcher(object):
+     def addRequires(self, s):
+         self.requires.append(self._buildProvides(s))
+ 
++    def addRecommends(self, s):
++        self.recommends.append(self._buildProvides(s))
++
+     def addUpgrades(self, s):
+         self.upgrades.append(self._buildProvides(s))
+ 
+diff --git a/smart/transaction.py b/smart/transaction.py
+index eb320d2..300b9cc 100644
+--- a/smart/transaction.py
++++ b/smart/transaction.py
+@@ -573,7 +573,7 @@ class Transaction(object):
+                 self._remove(namepkg, changeset, locked, pending, depth)
+ 
+         # Install packages required by this one.
+-        for req in pkg.requires:
++        for req in pkg.requires + pkg.recommends:
+ 
+             # Check if someone is already providing it.
+             prvpkgs = {}
+@@ -596,8 +596,12 @@ class Transaction(object):
+ 
+             if not prvpkgs:
+                 # No packages provide it at all. Give up.
+-                raise Failed, _("Can't install %s: no package provides %s") % \
+-                              (pkg, req)
++                if req in pkg.requires:
++                    raise Failed, _("Can't install %s: no package provides %s") % \
++                                (pkg, req)
++                else:
++                    # It's only a recommend, skip
++                    continue
+ 
+             if len(prvpkgs) == 1:
+                 # Don't check locked here. prvpkgs was
+@@ -1359,7 +1363,7 @@ class ChangeSetSplitter(object):
+         set = self._changeset
+ 
+         # Check all dependencies needed by this package.
+-        for req in pkg.requires:
++        for req in pkg.requires + pkg.recommends:
+ 
+             # Check if any already installed or to be installed
+             # package will solve the problem.
+@@ -1424,8 +1428,9 @@ class ChangeSetSplitter(object):
+ 
+             # There are no solutions for the problem.
+             # Should we really care about it?
+-            if (self._forcerequires or
+-                isinstance(req, PreRequires)):
++            if ((self._forcerequires or
++                isinstance(req, PreRequires))
++                and req in pkg.requires):
+                 raise Error, _("No providers for '%s', "
+                                "required by '%s'") % (req, pkg)
+ 
+@@ -1625,7 +1630,7 @@ def recursiveInternalRequires(pkgmap, pkg, numrel, done=None):
+     return n
+ 
+ def forwardRequires(pkg, map):
+-    for req in pkg.requires:
++    for req in pkg.requires + pkg.recommends:
+         if req not in map:
+             map[req] = True
+             for prv in req.providedby:
+@@ -1794,6 +1799,15 @@ def checkPackages(cache, checkset, relateset, report=False):
+                 iface.info(_("Unsatisfied dependency: %s requires %s") %
+                            (pkg, req))
+ 
++        for req in pkg.recommends:
++            for prv in req.providedby:
++                for prvpkg in prv.packages:
++                    if prvpkg in relateset:
++                        break
++                else:
++                    continue
++                break
++
+         if not pkg.installed:
+             continue
+ 
+-- 
+1.7.9.5
+
diff --git a/meta/recipes-devtools/python/python-smartpm_1.4.1.bb b/meta/recipes-devtools/python/python-smartpm_1.4.1.bb
index 254318c..9048bc8 100644
--- a/meta/recipes-devtools/python/python-smartpm_1.4.1.bb
+++ b/meta/recipes-devtools/python/python-smartpm_1.4.1.bb
@@ -18,7 +18,7 @@ SRC_URI = "\
           http://launchpad.net/smart/trunk/${PV}/+download/${SRCNAME}-${PV}.tar.bz2 \
           file://smartpm-rpm5-nodig.patch \
           file://smart-rpm-root.patch \
-          file://smart-missingok.patch \
+          file://smart-recommends.patch \
           "
 
 SRC_URI[md5sum] = "573ef32ba177a6b3c4bf7ef04873fcb6"
