make repodata_stringify return the result string
[platform/upstream/libsolv.git] / bindings / solv.i
index 556228a..3f88a8b 100644 (file)
@@ -4,21 +4,59 @@
 # on the generated c code
 #
 
-#
-##if defined(SWIGRUBY)
-#  %rename("to_s") string();
-##endif
-##if defined(SWIGPYTHON)
-#  %rename("__str__") string();
-##endif
-#
-
 %module solv
 
 #ifdef SWIGRUBY
 %markfunc Pool "mark_Pool";
 #endif
 
+#
+# binaryblob handling
+#
+
+%{
+typedef struct {
+  const void *data;
+  size_t len;
+} BinaryBlob;
+%}
+
+%typemap(in,noblock=1,fragment="SWIG_AsCharPtrAndSize") (const unsigned char *str, size_t len) (int res, char *buf = 0, size_t size = 0, int alloc = 0) {
+  res = SWIG_AsCharPtrAndSize($input, &buf, &size, &alloc);
+  if (!SWIG_IsOK(res)) {
+#if defined(SWIGPYTHON)
+    const void *pybuf = 0;
+    Py_ssize_t pysize = 0;
+    res = PyObject_AsReadBuffer($input, &pybuf, &pysize);
+    if (res < 0) {
+      %argument_fail(res, "BinaryBlob", $symname, $argnum);
+    } else {
+      buf = (void *)pybuf;
+      size = pysize;
+    }
+#else
+    %argument_fail(res, "const char *", $symname, $argnum);
+#endif
+  }
+  $1 = (unsigned char *)buf;
+  $2 = size;
+}
+
+%typemap(freearg,noblock=1,match="in") (const unsigned char *str, int len) {
+  if (alloc$argnum == SWIG_NEWOBJ) %delete_array(buf$argnum);
+}
+
+%typemap(out,noblock=1,fragment="SWIG_FromCharPtrAndSize") BinaryBlob {
+#if defined(SWIGPYTHON) && defined(PYTHON3)
+  $result = $1.data ? Py_BuildValue("y#", $1.data, $1.len) : SWIG_Py_Void();
+#else
+  $result = SWIG_FromCharPtrAndSize($1.data, $1.len);
+#if defined(SWIGPERL)
+  argvi++;
+#endif
+#endif
+}
+
 #if defined(SWIGPYTHON)
 %typemap(in) Queue {
   /* Check if is a list */
 
 #endif
 
-
 #if defined(SWIGPERL)
 %typemap(in) Queue {
   AV *av;
 #
 %typemap(out) Queue {
   int i;
-  if (argvi + $1.count + 1>= items) {
-    EXTEND(sp, items - (argvi + $1.count + 1) + 1);
+  if (argvi + $1.count + 1 >= items) {
+    EXTEND(sp, (argvi + $1.count + 1) - items + 1);
   }
   for (i = 0; i < $1.count; i++)
     ST(argvi++) = SvREFCNT_inc(SWIG_From_int($1.elements[i]));
   int cnt = $1.count / step;
   Id *idp = $1.elements;
   if (argvi + cnt + 1 >= items) {
-    EXTEND(sp, items - (argvi + cnt + 1) + 1);
+    EXTEND(sp, (argvi + cnt + 1) - items + 1);
   }
   for (i = 0; i < cnt; i++, idp += step)
     {
 # work around a swig bug
 %{
 #undef SWIG_CALLXS
-#ifdef PERL_OBJECT 
-#  define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(cv,pPerl) 
-#else 
-#  ifndef MULTIPLICITY 
-#    define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(cv) 
-#  else 
-#    define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(PERL_GET_THX, cv) 
-#  endif 
-#endif 
+#ifdef PERL_OBJECT
+#  define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(cv,pPerl)
+#else
+#  ifndef MULTIPLICITY
+#    define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(cv)
+#  else
+#    define SWIG_CALLXS(_name) TOPMARK=MARK-PL_stack_base;_name(PERL_GET_THX, cv)
+#  endif
+#endif
 %}
 
 
@@ -295,7 +332,6 @@ SWIG_Perl_NewArrayObj(SWIG_MAYBE_PERL_OBJECT void *ptr, swig_type_info *t, int f
 #endif
 
 
-
 #if defined(SWIGPYTHON)
 typedef PyObject *AppObjectPtr;
 %typemap(out) AppObjectPtr {
@@ -324,16 +360,98 @@ typedef VALUE AppObjectPtr;
 #endif
 
 
-%include "cdata.i"
-#ifndef SWIGPERL
+#ifdef SWIGPYTHON
 %include "file.i"
+#else
+%fragment("SWIG_AsValFilePtr","header") {}
+#endif
+
+
+%fragment("SWIG_AsValSolvFpPtr","header", fragment="SWIG_AsValFilePtr") {
+
+SWIGINTERN int
+#ifdef SWIGRUBY
+SWIG_AsValSolvFpPtr(VALUE obj, FILE **val) {
+#else
+SWIG_AsValSolvFpPtr(void *obj, FILE **val) {
+#endif
+  static swig_type_info* desc = 0;
+  void *vptr = 0;
+  int ecode;
+
+  if (!desc) desc = SWIG_TypeQuery("SolvFp *");
+  if ((SWIG_ConvertPtr(obj, &vptr, desc, 0)) == SWIG_OK) {
+    if (val)
+      *val = vptr ? ((SolvFp *)vptr)->fp : 0;
+    return SWIG_OK;
+  }
+#ifdef SWIGPYTHON
+  ecode = SWIG_AsValFilePtr(obj, val);
+  if (ecode == SWIG_OK)
+    return ecode;
 #endif
+  return SWIG_TypeError;
+}
+
+}
+
+
+%fragment("SWIG_AsValDepId","header") {
+
+SWIGINTERN int
+#ifdef SWIGRUBY
+SWIG_AsValDepId(VALUE obj, int *val) {
+#else
+SWIG_AsValDepId(void *obj, int *val) {
+#endif
+  static swig_type_info* desc = 0;
+  void *vptr = 0;
+  int ecode;
+  if (!desc) desc = SWIG_TypeQuery("Dep *");
+  ecode = SWIG_AsVal_int(obj, val);
+  if (SWIG_IsOK(ecode))
+    return ecode;
+  if ((SWIG_ConvertPtr(obj, &vptr, desc, 0)) == SWIG_OK) {
+    if (val)
+      *val = vptr ? ((Dep *)vptr)->id : 0;
+    return SWIG_OK;
+  }
+  return SWIG_TypeError;
+}
+
+}
+
+%typemap(out) disown_helper {
+#ifdef SWIGRUBY
+  SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_Pool, SWIG_POINTER_DISOWN |  0 );
+#endif
+#ifdef SWIGPYTHON
+  SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Pool, SWIG_POINTER_DISOWN |  0 );
+#endif
+#ifdef SWIGPERL
+  SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_Pool, SWIG_POINTER_DISOWN |  0 );
+#endif
+  $result = SWIG_From_int((int)(0));
+}
+
 %include "typemaps.i"
 
+%typemap(in,numinputs=0,noblock=1) XRule **OUTPUT ($*1_ltype temp) {
+  $1 = &temp;
+}
+%typemap(argout,noblock=1) XRule **OUTPUT {
+  %append_output(SWIG_NewPointerObj((void*)(*$1), SWIGTYPE_p_XRule, SWIG_POINTER_OWN | %newpointer_flags));
+}
+
+%typemaps_asval(%checkcode(POINTER), SWIG_AsValSolvFpPtr, "SWIG_AsValSolvFpPtr", FILE*);
+%typemaps_asval(%checkcode(INT32), SWIG_AsValDepId, "SWIG_AsValDepId", DepId);
+
+
 %{
 #include <stdbool.h>
 #include <stdio.h>
 #include <sys/stat.h>
+#include <sys/utsname.h>
 #include <sys/types.h>
 #include <unistd.h>
 
@@ -344,6 +462,7 @@ typedef int bool;
 
 #include "pool.h"
 #include "poolarch.h"
+#include "evr.h"
 #include "solver.h"
 #include "policy.h"
 #include "solverdebug.h"
@@ -355,6 +474,9 @@ typedef int bool;
 #ifdef ENABLE_RPMDB
 #include "repo_rpmdb.h"
 #endif
+#ifdef ENABLE_PUBKEY
+#include "repo_pubkey.h"
+#endif
 #ifdef ENABLE_DEBIAN
 #include "repo_deb.h"
 #endif
@@ -390,9 +512,10 @@ typedef int bool;
 #define SOLVER_SOLUTION_REPLACE_DOWNGRADE       -102
 #define SOLVER_SOLUTION_REPLACE_ARCHCHANGE      -103
 #define SOLVER_SOLUTION_REPLACE_VENDORCHANGE    -104
+#define SOLVER_SOLUTION_REPLACE_NAMECHANGE      -105
 
-typedef struct chksum Chksum;
 typedef void *AppObjectPtr;
+typedef Id DepId;
 
 typedef struct {
   Pool *pool;
@@ -463,7 +586,7 @@ typedef struct {
   Id type;
   Id source;
   Id target;
-  Id dep;
+  Id dep_id;
 } Ruleinfo;
 
 typedef struct {
@@ -481,8 +604,14 @@ typedef struct {
   int flags;
 } Selection;
 
+typedef struct {
+  FILE *fp;
+} SolvFp;
+
 typedef Dataiterator Datamatch;
 
+typedef int disown_helper;
+
 %}
 
 #ifdef SWIGRUBY
@@ -514,6 +643,10 @@ typedef struct {
   Id const id;
 } Dep;
 
+# put before pool/repo so we can access the constructor
+%nodefaultdtor Dataiterator;
+typedef struct {} Dataiterator;
+
 typedef struct {
   Pool* const pool;
   Id const id;
@@ -522,7 +655,7 @@ typedef struct {
 typedef struct {
   Solver* const solv;
   Id const type;
-  Id const dep;
+  Id const dep_id;
 } Ruleinfo;
 
 typedef struct {
@@ -535,9 +668,6 @@ typedef struct {
   Id const id;
 } XRepodata;
 
-# put before pool/repo so we can access the constructor
-%nodefaultdtor Dataiterator;
-typedef struct {} Dataiterator;
 typedef struct {} Pool_solvable_iterator;
 typedef struct {} Pool_repo_iterator;
 typedef struct {} Repo_solvable_iterator;
@@ -587,28 +717,49 @@ typedef struct {
 typedef struct {
 } Chksum;
 
-%rename(xfopen) solv_xfopen;
-%rename(xfopen_fd) solv_xfopen_fd;
-%rename(xfopen_dup) solv_xfopen_dup;
-%rename(xfclose) solv_xfclose;
-%rename(xfileno) solv_xfileno;
+#ifdef ENABLE_PUBKEY
+typedef struct {
+  Id const htype;
+  unsigned int const created;
+  unsigned int const expires;
+  const char * const keyid;
+} Solvsig;
+#endif
+
+%rename(xfopen) solvfp_xfopen;
+%rename(xfopen_fd) solvfp_xfopen_fd;
 
-FILE *solv_xfopen(const char *fn, const char *mode = 0);
-FILE *solv_xfopen_fd(const char *fn, int fd, const char *mode = 0);
-FILE *solv_xfopen_dup(const char *fn, int fd, const char *mode = 0);
-int solv_xfclose(FILE *fp);
-int solv_xfileno(FILE *fp);
+%nodefaultctor SolvFp;
+typedef struct {
+} SolvFp;
+
+%newobject solvfp_xfopen;
+%newobject solvfp_xfopen_fd;
+
+SolvFp *solvfp_xfopen(const char *fn, const char *mode = 0);
+SolvFp *solvfp_xfopen_fd(const char *fn, int fd, const char *mode = 0);
 
 %{
-  SWIGINTERN int solv_xfclose(FILE *fp) {
-    return fclose(fp);
-  }
-  SWIGINTERN int solv_xfileno(FILE *fp) {
-    return fileno(fp);
-  }
-  SWIGINTERN FILE *solv_xfopen_dup(const char *fn, int fd, const char *mode) {
+  SWIGINTERN SolvFp *solvfp_xfopen_fd(const char *fn, int fd, const char *mode) {
+    SolvFp *sfp;
+    FILE *fp;
     fd = dup(fd);
-    return fd == -1 ? 0 : solv_xfopen_fd(fn, fd, mode);
+    fp = fd == -1 ? 0 : solv_xfopen_fd(fn, fd, mode);
+    if (!fp)
+      return 0;
+    sfp = solv_calloc(1, sizeof(SolvFp));
+    sfp->fp = fp;
+    return sfp;
+  }
+  SWIGINTERN SolvFp *solvfp_xfopen(const char *fn, const char *mode) {
+    SolvFp *sfp;
+    FILE *fp;
+    fp = solv_xfopen(fn, mode);
+    if (!fp)
+      return 0;
+    sfp = solv_calloc(1, sizeof(SolvFp));
+    sfp->fp = fp;
+    return sfp;
   }
 %}
 
@@ -645,6 +796,32 @@ typedef struct {
   int const count;
 } TransactionClass;
 
+%extend SolvFp {
+  ~SolvFp() {
+    if ($self->fp)
+      fclose($self->fp);
+    free($self);
+  }
+  int fileno() {
+    return $self->fp ? fileno($self->fp) : -1;
+  }
+  int dup() {
+    return $self->fp ? dup(fileno($self->fp)) : -1;
+  }
+  bool flush() {
+    if (!$self->fp)
+      return 1;
+    return fflush($self->fp) == 0;
+  }
+  bool close() {
+    bool ret;
+    if (!$self->fp)
+      return 1;
+    ret = fclose($self->fp) == 0;
+    $self->fp = 0;
+    return ret;
+  }
+}
 
 %extend Job {
   static const Id SOLVER_SOLVABLE = SOLVER_SOLVABLE;
@@ -659,7 +836,7 @@ typedef struct {
   static const Id SOLVER_ERASE = SOLVER_ERASE;
   static const Id SOLVER_UPDATE = SOLVER_UPDATE;
   static const Id SOLVER_WEAKENDEPS = SOLVER_WEAKENDEPS;
-  static const Id SOLVER_NOOBSOLETES = SOLVER_NOOBSOLETES;
+  static const Id SOLVER_MULTIVERSION = SOLVER_MULTIVERSION;
   static const Id SOLVER_LOCK = SOLVER_LOCK;
   static const Id SOLVER_DISTUPGRADE = SOLVER_DISTUPGRADE;
   static const Id SOLVER_VERIFY = SOLVER_VERIFY;
@@ -669,11 +846,15 @@ typedef struct {
   static const Id SOLVER_WEAK = SOLVER_WEAK;
   static const Id SOLVER_ESSENTIAL = SOLVER_ESSENTIAL;
   static const Id SOLVER_CLEANDEPS = SOLVER_CLEANDEPS;
+  static const Id SOLVER_FORCEBEST = SOLVER_FORCEBEST;
+  static const Id SOLVER_TARGETED = SOLVER_TARGETED;
+  static const Id SOLVER_NOTBYUSER = SOLVER_NOTBYUSER;
   static const Id SOLVER_SETEV = SOLVER_SETEV;
   static const Id SOLVER_SETEVR = SOLVER_SETEVR;
   static const Id SOLVER_SETARCH = SOLVER_SETARCH;
   static const Id SOLVER_SETVENDOR = SOLVER_SETVENDOR;
   static const Id SOLVER_SETREPO = SOLVER_SETREPO;
+  static const Id SOLVER_SETNAME = SOLVER_SETNAME;
   static const Id SOLVER_NOAUTOSET = SOLVER_NOAUTOSET;
   static const Id SOLVER_SETMASK = SOLVER_SETMASK;
 
@@ -693,6 +874,12 @@ typedef struct {
     pool_job2solvables($self->pool, &q, $self->how, $self->what);
     return q;
   }
+#ifdef SWIGRUBY
+  %rename("isemptyupdate?") isemptyupdate;
+#endif
+  bool isemptyupdate() {
+    return pool_isemptyupdatejob($self->pool, $self->how, $self->what);
+  }
 
   bool __eq__(Job *j) {
     return $self->pool == j->pool && $self->how == j->how && $self->what == j->what;
@@ -716,10 +903,15 @@ typedef struct {
   static const Id SELECTION_NAME = SELECTION_NAME;
   static const Id SELECTION_PROVIDES = SELECTION_PROVIDES;
   static const Id SELECTION_FILELIST = SELECTION_FILELIST;
-  static const Id SELECTION_GLOB = SELECTION_GLOB;
-  static const Id SELECTION_NOCASE = SELECTION_NOCASE;
+  static const Id SELECTION_CANON = SELECTION_CANON;
+  static const Id SELECTION_DOTARCH = SELECTION_DOTARCH;
+  static const Id SELECTION_REL = SELECTION_REL;
   static const Id SELECTION_INSTALLED_ONLY = SELECTION_INSTALLED_ONLY;
+  static const Id SELECTION_GLOB = SELECTION_GLOB;
   static const Id SELECTION_FLAT = SELECTION_FLAT;
+  static const Id SELECTION_NOCASE = SELECTION_NOCASE;
+  static const Id SELECTION_SOURCE_ONLY = SELECTION_SOURCE_ONLY;
+  static const Id SELECTION_WITH_SOURCE = SELECTION_WITH_SOURCE;
 
   Selection(Pool *pool) {
     Selection *s;
@@ -735,20 +927,17 @@ typedef struct {
   int flags() {
     return $self->flags;
   }
-  void make(const char *name, int flags) {
-    $self->flags = selection_make($self->pool, &$self->q, name, flags);
-  }
 #ifdef SWIGRUBY
   %rename("isempty?") isempty;
 #endif
   bool isempty() {
     return $self->q.count == 0;
   }
-  void limit(Selection *lsel) {
+  void filter(Selection *lsel) {
     if ($self->pool != lsel->pool)
       queue_empty(&$self->q);
     else
-      selection_limit($self->pool, &$self->q, &lsel->q);
+      selection_filter($self->pool, &$self->q, &lsel->q);
   }
   void add(Selection *lsel) {
     if ($self->pool == lsel->pool)
@@ -757,7 +946,7 @@ typedef struct {
         $self->flags |= lsel->flags;
       }
   }
-  void addsimple(Id how, Id what) {
+  void add_raw(Id how, Id what) {
     queue_push2(&$self->q, how, what);
   }
   %typemap(out) Queue jobs Queue2Array(Job *, 2, new_Job(arg1->pool, id, idp[1]));
@@ -794,7 +983,7 @@ typedef struct {
 
 %extend Chksum {
   Chksum(Id type) {
-    return (Chksum *)solv_chksum_create(type);
+    return solv_chksum_create(type);
   }
   Chksum(Id type, const char *hex) {
     unsigned char buf[64];
@@ -803,19 +992,19 @@ typedef struct {
       return 0;
     if (solv_hex2bin(&hex, buf, sizeof(buf)) != l || hex[0])
       return 0;
-    return (Chksum *)solv_chksum_create_from_bin(type, buf);
+    return solv_chksum_create_from_bin(type, buf);
   }
   ~Chksum() {
     solv_chksum_free($self, 0);
   }
   Id const type;
   %{
-  SWIGINTERN Id Chksum_type_get(Chksum *chksum) {
-    return solv_chksum_get_type(chksum);
+  SWIGINTERN Id Chksum_type_get(Chksum *chk) {
+    return solv_chksum_get_type(chk);
   }
   %}
-  void add(const char *str) {
-    solv_chksum_add($self, str, strlen((char *)str));
+  void add(const unsigned char *str, size_t len) {
+    solv_chksum_add($self, str, (int)len);
   }
   void add_fp(FILE *fp) {
     char buf[4096];
@@ -849,11 +1038,14 @@ typedef struct {
     solv_chksum_add($self, &stb.st_size, sizeof(stb.st_size));
     solv_chksum_add($self, &stb.st_mtime, sizeof(stb.st_mtime));
   }
-  SWIGCDATA raw() {
+  BinaryBlob raw() {
+    BinaryBlob bl;
     int l;
     const unsigned char *b;
     b = solv_chksum_get($self, &l);
-    return cdata_void((void *)b, l);
+    bl.data = b;
+    bl.len = l;
+    return bl;
   }
   %newobject hex;
   char *hex() {
@@ -866,6 +1058,9 @@ typedef struct {
     solv_bin2hex(b, l, ret);
     return ret;
   }
+  const char *typestr() {
+    return solv_chksum_type2str(solv_chksum_get_type($self));
+  }
 
   bool __eq__(Chksum *chk) {
     int l;
@@ -883,7 +1078,6 @@ typedef struct {
   }
 #if defined(SWIGRUBY)
   %rename("to_s") __str__;
-  %rename("inspect") __repr__;
 #endif
 #if defined(SWIGPERL)
   %rename("str") __str__;
@@ -908,12 +1102,20 @@ typedef struct {
 }
 
 %extend Pool {
+  static const int POOL_FLAG_PROMOTEEPOCH = POOL_FLAG_PROMOTEEPOCH;
+  static const int POOL_FLAG_FORBIDSELFCONFLICTS = POOL_FLAG_FORBIDSELFCONFLICTS;
+  static const int POOL_FLAG_OBSOLETEUSESPROVIDES = POOL_FLAG_OBSOLETEUSESPROVIDES;
+  static const int POOL_FLAG_IMPLICITOBSOLETEUSESPROVIDES = POOL_FLAG_IMPLICITOBSOLETEUSESPROVIDES;
+  static const int POOL_FLAG_OBSOLETEUSESCOLORS = POOL_FLAG_OBSOLETEUSESCOLORS;
+  static const int POOL_FLAG_IMPLICITOBSOLETEUSESCOLORS = POOL_FLAG_IMPLICITOBSOLETEUSESCOLORS;
+  static const int POOL_FLAG_NOINSTALLEDOBSOLETES = POOL_FLAG_NOINSTALLEDOBSOLETES;
+  static const int POOL_FLAG_HAVEDISTEPOCH = POOL_FLAG_HAVEDISTEPOCH;
+  static const int POOL_FLAG_NOOBSOLETESMULTIVERSION = POOL_FLAG_NOOBSOLETESMULTIVERSION;
+
   Pool() {
     Pool *pool = pool_create();
     return pool;
   }
-  ~Pool() {
-  }
   void set_debuglevel(int level) {
     pool_setdebuglevel($self, level);
   }
@@ -1013,13 +1215,22 @@ typedef struct {
   }
 #endif
 
-  void free() {
+  ~Pool() {
+    Pool_set_loadcallback($self, 0);
+    pool_free($self);
+  }
+  disown_helper free() {
     Pool_set_loadcallback($self, 0);
     pool_free($self);
+    return 0;
+  }
+  disown_helper disown() {
+    return 0;
   }
   Id str2id(const char *str, bool create=1) {
     return pool_str2id($self, str, create);
   }
+  %newobject Dep;
   Dep *Dep(const char *str, bool create=1) {
     Id id = pool_str2id($self, str, create);
     return new_Dep($self, id);
@@ -1036,7 +1247,15 @@ typedef struct {
   Id id2langid(Id id, const char *lang, bool create=1) {
     return pool_id2langid($self, id, lang, create);
   }
-  void setarch(const char *arch) {
+  void setarch(const char *arch = 0) {
+    struct utsname un;
+    if (!arch) {
+      if (uname(&un)) {
+        perror("uname");
+        return;
+      }
+      arch = un.machine;
+    }
     pool_setarch($self, arch);
   }
   Repo *add_repo(const char *name) {
@@ -1048,7 +1267,7 @@ typedef struct {
   Id lookup_id(Id entry, Id keyname) {
     return pool_lookup_id($self, entry, keyname);
   }
-  unsigned int lookup_num(Id entry, Id keyname, unsigned int notfound = 0) {
+  unsigned long long lookup_num(Id entry, Id keyname, unsigned long long notfound = 0) {
     return pool_lookup_num($self, entry, keyname, notfound);
   }
   bool lookup_void(Id entry, Id keyname) {
@@ -1062,7 +1281,11 @@ typedef struct {
   }
 
   %newobject Dataiterator;
-  Dataiterator *Dataiterator(Id p, Id key, const char *match, int flags) {
+  Dataiterator *Dataiterator(Id key, const char *match = 0, int flags = 0) {
+    return new_Dataiterator($self, 0, 0, key, match, flags);
+  }
+  %newobject Dataiterator_solvid;
+  Dataiterator *Dataiterator_solvid(Id p, Id key, const char *match = 0, int flags = 0) {
     return new_Dataiterator($self, 0, p, key, match, flags);
   }
   const char *solvid2str(Id solvid) {
@@ -1081,6 +1304,7 @@ typedef struct {
     pool_createwhatprovides($self);
   }
 
+  %newobject id2solvable;
   XSolvable *id2solvable(Id id) {
     return new_XSolvable($self, id);
   }
@@ -1101,6 +1325,7 @@ typedef struct {
       return 0;
     return pool_id2repo($self, id);
   }
+
   %newobject repos;
   Pool_repo_iterator * const repos;
   %{
@@ -1114,6 +1339,7 @@ typedef struct {
   }
 
   Repo *installed;
+  const char * const errstr;
   %{
   SWIGINTERN void Pool_installed_set(Pool *pool, Repo *installed) {
     pool_set_installed(pool, installed);
@@ -1121,6 +1347,9 @@ typedef struct {
   Repo *Pool_installed_get(Pool *pool) {
     return pool->installed;
   }
+  const char *Pool_errstr_get(Pool *pool) {
+    return pool_errstr(pool);
+  }
   %}
 
   Queue matchprovidingids(const char *match, int flags) {
@@ -1144,13 +1373,14 @@ typedef struct {
     return q;
   }
 
+  %newobject Job;
   Job *Job(int how, Id what) {
     return new_Job($self, how, what);
   }
 
   %typemap(out) Queue whatprovides Queue2Array(XSolvable *, 1, new_XSolvable(arg1, id));
   %newobject whatprovides;
-  Queue whatprovides(Id dep) {
+  Queue whatprovides(DepId dep) {
     Pool *pool = $self;
     Queue q;
     Id p, pp;
@@ -1167,7 +1397,7 @@ typedef struct {
 #ifdef SWIGRUBY
   %rename("isknownarch?") isknownarch;
 #endif
-  bool isknownarch(Id id) {
+  bool isknownarch(DepId id) {
     Pool *pool = $self;
     if (!id || id == ID_EMPTY)
       return 0;
@@ -1187,12 +1417,61 @@ typedef struct {
   Selection *Selection() {
     return new_Selection($self);
   }
+  %newobject Selection_all;
+  Selection *Selection_all(int setflags=0) {
+    Selection *sel = new_Selection($self);
+    queue_push2(&sel->q, SOLVER_SOLVABLE_ALL | setflags, 0);
+    return sel;
+  }
   %newobject select;
   Selection *select(const char *name, int flags) {
     Selection *sel = new_Selection($self);
     sel->flags = selection_make($self, &sel->q, name, flags);
     return sel;
   }
+
+  void setpooljobs_helper(Queue jobs) {
+    queue_free(&$self->pooljobs);
+    queue_init_clone(&$self->pooljobs, &jobs);
+  }
+  %typemap(out) Queue getpooljobs Queue2Array(Job *, 2, new_Job(arg1, id, idp[1]));
+  %newobject getpooljobs;
+  Queue getpooljobs() {
+    Queue q;
+    queue_init_clone(&q, &$self->pooljobs);
+    return q;
+  }
+
+#if defined(SWIGPYTHON)
+  %pythoncode {
+    def setpooljobs(self, jobs):
+      j = []
+      for job in jobs: j += [job.how, job.what]
+      self.setpooljobs_helper(j)
+  }
+#endif
+#if defined(SWIGPERL)
+  %perlcode {
+    sub solv::Solver::setpooljobs {
+      my ($self, $jobs) = @_;
+      my @j = map {($_->{'how'}, $_->{'what'})} @$jobs;
+      return $self->setpooljobs_helper(\@j);
+    }
+  }
+#endif
+#if defined(SWIGRUBY)
+%init %{
+rb_eval_string(
+    "class Solv::Pool\n"
+    "  def setpooljobs(jobs)\n"
+    "    jl = []\n"
+    "    jobs.each do |j| ; jl << j.how << j.what ; end\n"
+    "    setpooljobs_helper(jl)\n"
+    "  end\n"
+    "end\n"
+  );
+%}
+#endif
 }
 
 %extend Repo {
@@ -1201,7 +1480,8 @@ typedef struct {
   static const int REPO_LOCALPOOL = REPO_LOCALPOOL;
   static const int REPO_USE_LOADING = REPO_USE_LOADING;
   static const int REPO_EXTEND_SOLVABLES = REPO_EXTEND_SOLVABLES;
-  static const int REPO_USE_ROOTDIR  = REPO_USE_ROOTDIR;
+  static const int REPO_USE_ROOTDIR = REPO_USE_ROOTDIR;
+  static const int REPO_NO_LOCATION = REPO_NO_LOCATION;
   static const int SOLV_ADD_NO_STUBS = SOLV_ADD_NO_STUBS;       /* repo_solv */
 #ifdef ENABLE_SUSEREPO
   static const int SUSETAGS_RECORD_SHARES = SUSETAGS_RECORD_SHARES;     /* repo_susetags */
@@ -1232,95 +1512,121 @@ typedef struct {
     return repo_add_solv($self, fp, flags) == 0;
   }
 
+  %newobject add_solvable;
   XSolvable *add_solvable() {
     Id solvid = repo_add_solvable($self);
     return new_XSolvable($self->pool, solvid);
   }
 
 #ifdef ENABLE_RPMDB
-  bool add_rpmdb(Repo *ref, int flags = 0) {
-    return repo_add_rpmdb($self, ref, flags);
+  bool add_rpmdb(int flags = 0) {
+    return repo_add_rpmdb($self, 0, flags) == 0;
+  }
+  bool add_rpmdb_reffp(FILE *reffp, int flags = 0) {
+    return repo_add_rpmdb_reffp($self, reffp, flags) == 0;
+  }
+  %newobject add_rpm;
+  XSolvable *add_rpm(const char *name, int flags = 0) {
+    return new_XSolvable($self->pool, repo_add_rpm($self, name, flags));
+  }
+#endif
+#ifdef ENABLE_PUBKEY
+#ifdef ENABLE_RPMDB
+  bool add_rpmdb_pubkeys(int flags = 0) {
+    return repo_add_rpmdb_pubkeys($self, flags) == 0;
+  }
+#endif
+  %newobject add_pubkey;
+  XSolvable *add_pubkey(const char *keyfile, int flags = 0) {
+    return new_XSolvable($self->pool, repo_add_pubkey($self, keyfile, flags));
+  }
+  bool add_keyring(FILE *fp, int flags = 0) {
+    return repo_add_keyring($self, fp, flags);
   }
-  Id add_rpm(const char *name, int flags = 0) {
-    return repo_add_rpm($self, name, flags);
+  bool add_keydir(const char *keydir, const char *suffix, int flags = 0) {
+    return repo_add_keydir($self, keydir, suffix, flags);
   }
 #endif
 #ifdef ENABLE_RPMMD
   bool add_rpmmd(FILE *fp, const char *language, int flags = 0) {
-    return repo_add_rpmmd($self, fp, language, flags);
+    return repo_add_rpmmd($self, fp, language, flags) == 0;
   }
   bool add_repomdxml(FILE *fp, int flags = 0) {
-    return repo_add_repomdxml($self, fp, flags);
+    return repo_add_repomdxml($self, fp, flags) == 0;
   }
   bool add_updateinfoxml(FILE *fp, int flags = 0) {
-    return repo_add_updateinfoxml($self, fp, flags);
+    return repo_add_updateinfoxml($self, fp, flags) == 0;
   }
   bool add_deltainfoxml(FILE *fp, int flags = 0) {
-    return repo_add_deltainfoxml($self, fp, flags);
+    return repo_add_deltainfoxml($self, fp, flags) == 0;
   }
 #endif
 #ifdef ENABLE_DEBIAN
   bool add_debdb(int flags = 0) {
-    return repo_add_debdb($self, flags);
+    return repo_add_debdb($self, flags) == 0;
   }
-  Id add_deb(const char *name, int flags = 0) {
-    return repo_add_deb($self, name, flags);
+  bool add_debpackages(FILE *fp, int flags = 0) {
+    return repo_add_debpackages($self, fp, flags) == 0;
+  }
+  %newobject add_deb;
+  XSolvable *add_deb(const char *name, int flags = 0) {
+    return new_XSolvable($self->pool, repo_add_deb($self, name, flags));
   }
 #endif
 #ifdef ENABLE_SUSEREPO
   bool add_susetags(FILE *fp, Id defvendor, const char *language, int flags = 0) {
-    return repo_add_susetags($self, fp, defvendor, language, flags);
+    return repo_add_susetags($self, fp, defvendor, language, flags) == 0;
   }
   bool add_content(FILE *fp, int flags = 0) {
-    return repo_add_content($self, fp, flags);
+    return repo_add_content($self, fp, flags) == 0;
   }
   bool add_products(const char *proddir, int flags = 0) {
-    return repo_add_products($self, proddir, flags);
+    return repo_add_products($self, proddir, flags) == 0;
   }
 #endif
 #ifdef ENABLE_MDKREPO
   bool add_mdk(FILE *fp, int flags = 0) {
-    return repo_add_mdk($self, fp, flags);
+    return repo_add_mdk($self, fp, flags) == 0;
   }
   bool add_mdk_info(FILE *fp, int flags = 0) {
-    return repo_add_mdk($self, fp, flags);
+    return repo_add_mdk_info($self, fp, flags) == 0;
   }
 #endif
 #ifdef ENABLE_ARCHREPO
   bool add_arch_repo(FILE *fp, int flags = 0) {
-    return repo_add_arch_repo($self, fp, flags);
+    return repo_add_arch_repo($self, fp, flags) == 0;
+  }
+  bool add_arch_local(const char *dir, int flags = 0) {
+    return repo_add_arch_local($self, dir, flags) == 0;
   }
-  Id add_arch_pkg(const char *name, int flags = 0) {
-    return repo_add_arch_pkg($self, name, flags);
+  %newobject add_arch_pkg;
+  XSolvable *add_arch_pkg(const char *name, int flags = 0) {
+    return new_XSolvable($self->pool, repo_add_arch_pkg($self, name, flags));
   }
 #endif
   void internalize() {
     repo_internalize($self);
   }
-  const char *lookup_str(Id entry, Id keyname) {
-    return repo_lookup_str($self, entry, keyname);
-  }
-  Id lookup_id(Id entry, Id keyname) {
-    return repo_lookup_id($self, entry, keyname);
-  }
-  unsigned long long lookup_num(Id entry, Id keyname, unsigned long long notfound = 0) {
-    return repo_lookup_num($self, entry, keyname, notfound);
-  }
-  void write(FILE *fp) {
-    repo_write($self, fp);
+  bool write(FILE *fp) {
+    return repo_write($self, fp) == 0;
   }
   # HACK, remove if no longer needed!
   bool write_first_repodata(FILE *fp) {
     int oldnrepodata = $self->nrepodata;
+    int res;
     $self->nrepodata = oldnrepodata > 2 ? 2 : oldnrepodata;
-    repo_write($self, fp);
+    res = repo_write($self, fp);
     $self->nrepodata = oldnrepodata;
-    return 1;
+    return res == 0;
   }
 
   %newobject Dataiterator;
-  Dataiterator *Dataiterator(Id p, Id key, const char *match, int flags) {
-    return new_Dataiterator($self->pool, $self, p, key, match, flags);
+  Dataiterator *Dataiterator(Id key, const char *match = 0, int flags = 0) {
+    return new_Dataiterator($self->pool, $self, 0, key, match, flags);
+  }
+  %newobject Dataiterator_meta;
+  Dataiterator *Dataiterator_meta(Id key, const char *match = 0, int flags = 0) {
+    return new_Dataiterator($self->pool, $self, SOLVID_META, key, match, flags);
   }
 
   Id const id;
@@ -1329,17 +1635,30 @@ typedef struct {
     return repo->repoid;
   }
   %}
+  %newobject solvables;
   Repo_solvable_iterator * const solvables;
   %{
   SWIGINTERN Repo_solvable_iterator * Repo_solvables_get(Repo *repo) {
     return new_Repo_solvable_iterator(repo);
   }
   %}
+  %newobject meta;
+  Datapos * const meta;
+  %{
+  SWIGINTERN Datapos * Repo_meta_get(Repo *repo) {
+    Datapos *pos = solv_calloc(1, sizeof(*pos));
+    pos->solvid = SOLVID_META;
+    pos->repo = repo;
+    return pos;
+  }
+  %}
+
   %newobject solvables_iter;
   Repo_solvable_iterator *solvables_iter() {
     return new_Repo_solvable_iterator($self);
   }
 
+  %newobject add_repodata;
   XRepodata *add_repodata(int flags = 0) {
     Repodata *rd = repo_add_repodata($self, flags);
     return new_XRepodata($self, rd->repodataid);
@@ -1351,7 +1670,7 @@ typedef struct {
       return;
     data = repo_id2repodata($self, $self->nrepodata - 1);
     if (data->state != REPODATA_STUB)
-      repodata_create_stubs(data);
+      (void)repodata_create_stubs(data);
   }
 #ifdef SWIGRUBY
   %rename("iscontiguous?") iscontiguous;
@@ -1363,6 +1682,7 @@ typedef struct {
         return 0;
     return 1;
   }
+  %newobject first_repodata;
   XRepodata *first_repodata() {
     Repodata *data;
     int i;
@@ -1381,6 +1701,21 @@ typedef struct {
     return new_XRepodata($self, 1);
   }
 
+  %newobject Selection;
+  Selection *Selection(int setflags=0) {
+    Selection *sel = new_Selection($self->pool);
+    setflags |= SOLVER_SETREPO;
+    queue_push2(&sel->q, SOLVER_SOLVABLE_REPO | setflags, $self->repoid);
+    return sel;
+  }
+
+#ifdef ENABLE_PUBKEY
+  %newobject find_pubkey;
+  XSolvable *find_pubkey(const char *keyid) {
+    return new_XSolvable($self->pool, repo_find_pubkey($self, keyid));
+  }
+#endif
+
   bool __eq__(Repo *repo) {
     return $self == repo;
   }
@@ -1413,12 +1748,15 @@ typedef struct {
 
 %extend Dataiterator {
   static const int SEARCH_STRING = SEARCH_STRING;
+  static const int SEARCH_STRINGSTART = SEARCH_STRINGSTART;
+  static const int SEARCH_STRINGEND = SEARCH_STRINGEND;
   static const int SEARCH_SUBSTRING = SEARCH_SUBSTRING;
   static const int SEARCH_GLOB = SEARCH_GLOB;
   static const int SEARCH_REGEX = SEARCH_REGEX;
   static const int SEARCH_NOCASE = SEARCH_NOCASE;
   static const int SEARCH_FILES = SEARCH_FILES;
   static const int SEARCH_COMPLETE_FILELIST = SEARCH_COMPLETE_FILELIST;
+  static const int SEARCH_CHECKSUMS = SEARCH_CHECKSUMS;
 
   Dataiterator(Pool *pool, Repo *repo, Id p, Id key, const char *match, int flags) {
     Dataiterator *di = solv_calloc(1, sizeof(*di));
@@ -1430,14 +1768,12 @@ typedef struct {
     solv_free($self);
   }
 #if defined(SWIGPYTHON)
-  %newobject __iter__;
-  Dataiterator *__iter__() {
-    Dataiterator *ndi;
-    ndi = solv_calloc(1, sizeof(*ndi));
-    dataiterator_init_clone(ndi, $self);
-    return ndi;
+  %pythoncode {
+    def __iter__(self): return self
   }
+#ifndef PYTHON3
   %rename("next") __next__();
+#endif
   %exception __next__ {
     $action
     if (!result) {
@@ -1446,11 +1782,9 @@ typedef struct {
     }
   }
 #endif
-
 #ifdef SWIGPERL
   perliter(solv::Dataiterator)
 #endif
-
   %newobject __next__;
   Datamatch *__next__() {
     Dataiterator *ndi;
@@ -1459,6 +1793,7 @@ typedef struct {
     }
     ndi = solv_calloc(1, sizeof(*ndi));
     dataiterator_init_clone(ndi, $self);
+    dataiterator_strdup(ndi);
     return ndi;
   }
 #ifdef SWIGRUBY
@@ -1496,6 +1831,24 @@ typedef struct {
     pool->pos = oldpos;
     return r;
   }
+  unsigned long long lookup_num(Id keyname, unsigned long long notfound = 0) {
+    Pool *pool = $self->repo->pool;
+    Datapos oldpos = pool->pos;
+    unsigned long long r;
+    pool->pos = *$self;
+    r = pool_lookup_num(pool, SOLVID_POS, keyname, notfound);
+    pool->pos = oldpos;
+    return r;
+  }
+  bool lookup_void(Id keyname) {
+    Pool *pool = $self->repo->pool;
+    Datapos oldpos = pool->pos;
+    int r;
+    pool->pos = *$self;
+    r = pool_lookup_void(pool, SOLVID_POS, keyname);
+    pool->pos = oldpos;
+    return r;
+  }
   %newobject lookup_checksum;
   Chksum *lookup_checksum(Id keyname) {
     Pool *pool = $self->repo->pool;
@@ -1507,6 +1860,48 @@ typedef struct {
     pool->pos = oldpos;
     return solv_chksum_create_from_bin(type, b);
   }
+  const char *lookup_deltaseq() {
+    Pool *pool = $self->repo->pool;
+    Datapos oldpos = pool->pos;
+    const char *seq;
+    pool->pos = *$self;
+    seq = pool_lookup_str(pool, SOLVID_POS, DELTA_SEQ_NAME);
+    if (seq) {
+      seq = pool_tmpjoin(pool, seq, "-", pool_lookup_str(pool, SOLVID_POS, DELTA_SEQ_EVR));
+      seq = pool_tmpappend(pool, seq, "-", pool_lookup_str(pool, SOLVID_POS, DELTA_SEQ_NUM));
+    }
+    pool->pos = oldpos;
+    return seq;
+  }
+  const char *lookup_deltalocation(unsigned int *OUTPUT) {
+    Pool *pool = $self->repo->pool;
+    Datapos oldpos = pool->pos;
+    const char *loc;
+    pool->pos = *$self;
+    loc = pool_lookup_deltalocation(pool, SOLVID_POS, OUTPUT);
+    pool->pos = oldpos;
+    return loc;
+  }
+  Queue lookup_idarray(Id keyname) {
+    Pool *pool = $self->repo->pool;
+    Datapos oldpos = pool->pos;
+    Queue r;
+    queue_init(&r);
+    pool->pos = *$self;
+    pool_lookup_idarray(pool, SOLVID_POS, keyname, &r);
+    pool->pos = oldpos;
+    return r;
+  }
+  %newobject Dataiterator;
+  Dataiterator *Dataiterator(Id key, const char *match = 0, int flags = 0) {
+    Pool *pool = $self->repo->pool;
+    Datapos oldpos = pool->pos;
+    Dataiterator *di;
+    pool->pos = *$self;
+    di = new_Dataiterator(pool, 0, SOLVID_POS, key, match, flags);
+    pool->pos = oldpos;
+    return di;
+  }
 }
 
 %extend Datamatch {
@@ -1516,38 +1911,67 @@ typedef struct {
   }
   %newobject solvable;
   XSolvable * const solvable;
+  Id const key_id;
+  const char * const key_idstr;
+  Id const type_id;
+  const char * const type_idstr;
+  Id const id;
+  const char * const idstr;
+  const char * const str;
+  BinaryBlob const binary;
+  unsigned long long const num;
+  unsigned int const num2;
   %{
   SWIGINTERN XSolvable *Datamatch_solvable_get(Dataiterator *di) {
     return new_XSolvable(di->pool, di->solvid);
   }
-  %}
-  Id key_id() {
-    return $self->key->name;
+  SWIGINTERN Id Datamatch_key_id_get(Dataiterator *di) {
+    return di->key->name;
   }
-  const char *key_idstr() {
-    return pool_id2str($self->pool, $self->key->name);
+  SWIGINTERN const char *Datamatch_key_idstr_get(Dataiterator *di) {
+    return pool_id2str(di->pool, di->key->name);
   }
-  Id type_id() {
-    return $self->key->type;
+  SWIGINTERN Id Datamatch_type_id_get(Dataiterator *di) {
+    return di->key->type;
   }
-  const char *type_idstr() {
-    return pool_id2str($self->pool, $self->key->type);
+  SWIGINTERN const char *Datamatch_type_idstr_get(Dataiterator *di) {
+    return pool_id2str(di->pool, di->key->type);
   }
-  Id id() {
-     return $self->kv.id;
+  SWIGINTERN Id Datamatch_id_get(Dataiterator *di) {
+    return di->kv.id;
   }
-  const char *idstr() {
-     return pool_id2str($self->pool, $self->kv.id);
+  SWIGINTERN const char *Datamatch_idstr_get(Dataiterator *di) {
+   if (di->data && (di->key->type == REPOKEY_TYPE_DIR || di->key->type == REPOKEY_TYPE_DIRSTRARRAY || di->key->type == REPOKEY_TYPE_DIRNUMNUMARRAY))
+      return repodata_dir2str(di->data,  di->kv.id, 0);
+    if (di->data && di->data->localpool)
+      return stringpool_id2str(&di->data->spool, di->kv.id);
+    return pool_id2str(di->pool, di->kv.id);
   }
-  const char *str() {
-     return $self->kv.str;
+  SWIGINTERN const char * const Datamatch_str_get(Dataiterator *di) {
+    return di->kv.str;
+  }
+  SWIGINTERN BinaryBlob Datamatch_binary_get(Dataiterator *di) {
+    BinaryBlob bl;
+    bl.data = 0;
+    bl.len = 0;
+    if (di->key->type == REPOKEY_TYPE_BINARY)
+      {
+        bl.data = di->kv.str;
+        bl.len = di->kv.num;
+      }
+    else if ((bl.len = solv_chksum_len(di->key->type)) != 0)
+      bl.data = di->kv.str;
+    return bl;
   }
-  int num() {
-     return $self->kv.num;
+  SWIGINTERN unsigned long long Datamatch_num_get(Dataiterator *di) {
+   if (di->key->type == REPOKEY_TYPE_NUM)
+     return SOLV_KV_NUM64(&di->kv);
+   return di->kv.num;
   }
-  int num2() {
-     return $self->kv.num2;
+  SWIGINTERN unsigned int Datamatch_num2_get(Dataiterator *di) {
+    return di->kv.num2;
   }
+  %}
   %newobject pos;
   Datapos *pos() {
     Pool *pool = $self->pool;
@@ -1568,11 +1992,17 @@ typedef struct {
     pool->pos = oldpos;
     return pos;
   }
-  void setpos() {
-    dataiterator_setpos($self);
+#if defined(SWIGPERL)
+  /* cannot use str here because swig reports a bogus conflict... */
+  %rename("stringify") __str__;
+  %perlcode {
+    *solv::Datamatch::str = *solvc::Datamatch_stringify;
   }
-  void setpos_parent() {
-    dataiterator_setpos_parent($self);
+#endif
+  const char *__str__() {
+    KeyValue kv = $self->kv;
+    const char *str = repodata_stringify($self->pool, $self->data, $self->key, &kv, SEARCH_FILES | SEARCH_CHECKSUMS);
+    return str ? str : "";
   }
 }
 
@@ -1584,14 +2014,12 @@ typedef struct {
     return s;
   }
 #if defined(SWIGPYTHON)
-  %newobject __iter__;
-  Pool_solvable_iterator *__iter__() {
-    Pool_solvable_iterator *s;
-    s = solv_calloc(1, sizeof(*s));
-    *s = *$self;
-    return s;
+  %pythoncode {
+    def __iter__(self): return self
   }
+#ifndef PYTHON3
   %rename("next") __next__();
+#endif
   %exception __next__ {
     $action
     if (!result) {
@@ -1600,7 +2028,6 @@ typedef struct {
     }
   }
 #endif
-
 #ifdef SWIGPERL
   perliter(solv::Pool_solvable_iterator)
 #endif
@@ -1642,14 +2069,12 @@ typedef struct {
     return s;
   }
 #if defined(SWIGPYTHON)
-  %newobject __iter__;
-  Pool_repo_iterator *__iter__() {
-    Pool_repo_iterator *s;
-    s = solv_calloc(1, sizeof(*s));
-    *s = *$self;
-    return s;
+  %pythoncode {
+    def __iter__(self): return self
   }
+#ifndef PYTHON3
   %rename("next") __next__();
+#endif
   %exception __next__ {
     $action
     if (!result) {
@@ -1658,6 +2083,9 @@ typedef struct {
     }
   }
 #endif
+#ifdef SWIGPERL
+  perliter(solv::Pool_repo_iterator)
+#endif
   %newobject __next__;
   Repo *__next__() {
     Pool *pool = $self->pool;
@@ -1697,14 +2125,12 @@ typedef struct {
     return s;
   }
 #if defined(SWIGPYTHON)
-  %newobject __iter__;
-  Repo_solvable_iterator *__iter__() {
-    Repo_solvable_iterator *s;
-    s = solv_calloc(1, sizeof(*s));
-    *s = *$self;
-    return s;
+  %pythoncode {
+    def __iter__(self): return self
   }
+#ifndef PYTHON3
   %rename("next") __next__();
+#endif
   %exception __next__ {
     $action
     if (!result) {
@@ -1713,6 +2139,9 @@ typedef struct {
     }
   }
 #endif
+#ifdef SWIGPERL
+  perliter(solv::Repo_solvable_iterator)
+#endif
   %newobject __next__;
   XSolvable *__next__() {
     Repo *repo = $self->repo;
@@ -1757,6 +2186,40 @@ typedef struct {
     s->id = id;
     return s;
   }
+  %newobject Rel;
+  Dep *Rel(int flags, DepId evrid, bool create=1) {
+    Id id = pool_rel2id($self->pool, $self->id, evrid, flags, create);
+    if (!id)
+      return 0;
+    return new_Dep($self->pool, id);
+  }
+  %newobject Selection_name;
+  Selection *Selection_name(int setflags=0) {
+    Selection *sel = new_Selection($self->pool);
+    if (ISRELDEP($self->id)) {
+      Reldep *rd = GETRELDEP($self->pool, $self->id);
+      if (rd->flags == REL_EQ) {
+        setflags |= $self->pool->disttype == DISTTYPE_DEB || strchr(pool_id2str($self->pool, rd->evr), '-') != 0 ? SOLVER_SETEVR : SOLVER_SETEV;
+        if (ISRELDEP(rd->name))
+          rd = GETRELDEP($self->pool, rd->name);
+      }
+      if (rd->flags == REL_ARCH)
+        setflags |= SOLVER_SETARCH;
+    }
+    queue_push2(&sel->q, SOLVER_SOLVABLE_NAME | setflags, $self->id);
+    return sel;
+  }
+  %newobject Selection_provides;
+  Selection *Selection_provides(int setflags=0) {
+    Selection *sel = new_Selection($self->pool);
+    if (ISRELDEP($self->id)) {
+      Reldep *rd = GETRELDEP($self->pool, $self->id);
+      if (rd->flags == REL_ARCH)
+        setflags |= SOLVER_SETARCH;
+    }
+    queue_push2(&sel->q, SOLVER_SOLVABLE_PROVIDES | setflags, $self->id);
+    return sel;
+  }
   const char *str() {
     return pool_dep2str($self->pool, $self->id);
   }
@@ -1815,14 +2278,6 @@ typedef struct {
     Solvable *s = $self->pool->solvables + $self->id;
     Queue r;
     queue_init(&r);
-    if (marker == -1 || marker == 1) {
-      if (keyname == SOLVABLE_PROVIDES)
-        marker = marker < 0 ? -SOLVABLE_FILEMARKER : SOLVABLE_FILEMARKER;
-      else if (keyname == SOLVABLE_REQUIRES)
-        marker = marker < 0 ? -SOLVABLE_PREREQMARKER : SOLVABLE_PREREQMARKER;
-      else
-        marker = 0;
-    }
     solvable_lookup_deparray(s, keyname, &r, marker);
     return r;
   }
@@ -1832,19 +2287,15 @@ typedef struct {
     Solvable *s = $self->pool->solvables + $self->id;
     Queue r;
     queue_init(&r);
-    if (marker == -1 || marker == 1) {
-      if (keyname == SOLVABLE_PROVIDES)
-        marker = marker < 0 ? -SOLVABLE_FILEMARKER : SOLVABLE_FILEMARKER;
-      else if (keyname == SOLVABLE_REQUIRES)
-        marker = marker < 0 ? -SOLVABLE_PREREQMARKER : SOLVABLE_PREREQMARKER;
-      else
-        marker = 0;
-    }
     solvable_lookup_deparray(s, keyname, &r, marker);
     return r;
   }
   const char *lookup_location(unsigned int *OUTPUT) {
-    return solvable_get_location($self->pool->solvables + $self->id, OUTPUT);
+    return solvable_lookup_location($self->pool->solvables + $self->id, OUTPUT);
+  }
+  %newobject Dataiterator;
+  Dataiterator *Dataiterator(Id key, const char *match = 0, int flags = 0) {
+    return new_Dataiterator($self->pool, 0, $self->id, key, match, flags);
   }
 #ifdef SWIGRUBY
   %rename("installable?") installable;
@@ -1947,77 +2398,67 @@ typedef struct {
     }
   %}
 
-  void add_provides(Dep *dep, Id marker = -1) {
-    Solvable *s = $self->pool->solvables + $self->id;
-    if (marker == -1 || marker == 1)
-      marker = marker < 0 ? -SOLVABLE_FILEMARKER : SOLVABLE_FILEMARKER;
-    s->provides = repo_addid_dep(s->repo, s->provides, dep->id, marker);
-  }
-  void add_providesid(Id id, Id marker = -1) {
+  /* old interface, please use the generic add_deparray instead */
+  void add_provides(DepId id, Id marker = -1) {
     Solvable *s = $self->pool->solvables + $self->id;
-    if (marker == -1 || marker == 1)
-      marker = marker < 0 ? -SOLVABLE_FILEMARKER : SOLVABLE_FILEMARKER;
+    marker = solv_depmarker(SOLVABLE_PROVIDES, marker);
     s->provides = repo_addid_dep(s->repo, s->provides, id, marker);
   }
-  void add_obsoletes(Dep *dep) {
-    Solvable *s = $self->pool->solvables + $self->id;
-    s->obsoletes = repo_addid_dep(s->repo, s->obsoletes, dep->id, 0);
-  }
-  void add_obsoletesid(Id id) {
+  void add_obsoletes(DepId id) {
     Solvable *s = $self->pool->solvables + $self->id;
     s->obsoletes = repo_addid_dep(s->repo, s->obsoletes, id, 0);
   }
-  void add_conflicts(Dep *dep) {
-    Solvable *s = $self->pool->solvables + $self->id;
-    s->conflicts = repo_addid_dep(s->repo, s->conflicts, dep->id, 0);
-  }
-  void add_conflictsid(Id id) {
+  void add_conflicts(DepId id) {
     Solvable *s = $self->pool->solvables + $self->id;
     s->conflicts = repo_addid_dep(s->repo, s->conflicts, id, 0);
   }
-  void add_requires(Dep *dep, Id marker = -1) {
-    Solvable *s = $self->pool->solvables + $self->id;
-    if (marker == -1 || marker == 1)
-      marker = marker < 0 ? -SOLVABLE_PREREQMARKER : SOLVABLE_PREREQMARKER;
-    s->requires = repo_addid_dep(s->repo, s->requires, dep->id, marker);
-  }
-  void add_requiresid(Id id, Id marker = -1) {
+  void add_requires(DepId id, Id marker = -1) {
     Solvable *s = $self->pool->solvables + $self->id;
-    if (marker == -1 || marker == 1)
-      marker = marker < 0 ? -SOLVABLE_PREREQMARKER : SOLVABLE_PREREQMARKER;
+    marker = solv_depmarker(SOLVABLE_REQUIRES, marker);
     s->requires = repo_addid_dep(s->repo, s->requires, id, marker);
   }
-  void add_recommends(Dep *dep) {
-    Solvable *s = $self->pool->solvables + $self->id;
-    s->recommends = repo_addid_dep(s->repo, s->recommends, dep->id, 0);
-  }
-  void add_recommendsid(Id id) {
+  void add_recommends(DepId id) {
     Solvable *s = $self->pool->solvables + $self->id;
     s->recommends = repo_addid_dep(s->repo, s->recommends, id, 0);
   }
-  void add_suggests(Dep *dep) {
-    Solvable *s = $self->pool->solvables + $self->id;
-    s->suggests = repo_addid_dep(s->repo, s->suggests, dep->id, 0);
-  }
-  void add_suggestsid(Id id) {
+  void add_suggests(DepId id) {
     Solvable *s = $self->pool->solvables + $self->id;
     s->suggests = repo_addid_dep(s->repo, s->suggests, id, 0);
   }
-  void add_supplements(Dep *dep) {
+  void add_supplements(DepId id) {
     Solvable *s = $self->pool->solvables + $self->id;
-    s->supplements = repo_addid_dep(s->repo, s->supplements, dep->id, 0);
+    s->supplements = repo_addid_dep(s->repo, s->supplements, id, 0);
   }
-  void add_supplementsid(Id id) {
+  void add_enhances(DepId id) {
     Solvable *s = $self->pool->solvables + $self->id;
-    s->supplements = repo_addid_dep(s->repo, s->supplements, id, 0);
+    s->enhances = repo_addid_dep(s->repo, s->enhances, id, 0);
   }
-  void add_enhances(Dep *dep) {
+
+  void unset(Id keyname) {
     Solvable *s = $self->pool->solvables + $self->id;
-    s->enhances = repo_addid_dep(s->repo, s->enhances, dep->id, 0);
+    repo_unset(s->repo, $self->id, keyname);
   }
-  void add_enhancesid(Id id) {
+
+  void add_deparray(Id keyname, DepId id, Id marker = -1) {
     Solvable *s = $self->pool->solvables + $self->id;
-    s->enhances = repo_addid_dep(s->repo, s->enhances, id, 0);
+    solvable_add_deparray(s, keyname, id, marker);
+  }
+
+  %newobject Selection;
+  Selection *Selection(int setflags=0) {
+    Selection *sel = new_Selection($self->pool);
+    queue_push2(&sel->q, SOLVER_SOLVABLE | setflags, $self->id);
+    return sel;
+  }
+
+#ifdef SWIGRUBY
+  %rename("identical?") identical;
+#endif
+  bool identical(XSolvable *s2) {
+    return solvable_identical($self->pool->solvables + $self->id, s2->pool->solvables + s2->id);
+  }
+  int evrcmp(XSolvable *s2) {
+    return pool_evrcmp($self->pool, $self->pool->solvables[$self->id].evr, s2->pool->solvables[s2->id].evr, EVRCMP_COMPARE);
   }
 
   bool __eq__(XSolvable *s) {
@@ -2081,8 +2522,8 @@ typedef struct {
   int solution_count() {
     return solver_solution_count($self->solv, $self->id);
   }
-  %newobject solutions;
   %typemap(out) Queue solutions Queue2Array(Solution *, 1, new_Solution(arg1, id));
+  %newobject solutions;
   Queue solutions() {
     Queue q;
     int i, cnt;
@@ -2092,6 +2533,12 @@ typedef struct {
       queue_push(&q, i);
     return q;
   }
+#if defined(SWIGPERL)
+  %rename("str") __str__;
+#endif
+  const char *__str__() {
+    return solver_problem2str($self->solv, $self->id);
+  }
 }
 
 %extend Solution {
@@ -2107,8 +2554,8 @@ typedef struct {
     return solver_solutionelement_count($self->solv, $self->problemid, $self->id);
   }
 
-  %newobject elements;
   %typemap(out) Queue elements Queue2Array(Solutionelement *, 4, new_Solutionelement(arg1->solv, arg1->problemid, arg1->id, id, idp[1], idp[2], idp[3]));
+  %newobject elements;
   Queue elements(bool expandreplaces=0) {
     Queue q;
     int i, cnt;
@@ -2140,6 +2587,10 @@ typedef struct {
               queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_VENDORCHANGE);
               queue_push2(&q, p, rp);
             }
+            if ((illegal & POLICY_ILLEGAL_NAMECHANGE) != 0) {
+              queue_push2(&q, i, SOLVER_SOLUTION_REPLACE_NAMECHANGE);
+              queue_push2(&q, p, rp);
+            }
             continue;
           }
         }
@@ -2166,6 +2617,7 @@ typedef struct {
   const char *str() {
     Id p = $self->type;
     Id rp = $self->p;
+    int illegal = 0;
     if (p == SOLVER_SOLUTION_ERASE)
       {
         p = rp;
@@ -2177,15 +2629,19 @@ typedef struct {
         rp = $self->rp;
       }
     else if (p == SOLVER_SOLUTION_REPLACE_DOWNGRADE)
-      return pool_tmpjoin($self->solv->pool, "allow ", policy_illegal2str($self->solv, POLICY_ILLEGAL_DOWNGRADE, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp), 0);
+      illegal = POLICY_ILLEGAL_DOWNGRADE;
     else if (p == SOLVER_SOLUTION_REPLACE_ARCHCHANGE)
-      return pool_tmpjoin($self->solv->pool, "allow ", policy_illegal2str($self->solv, POLICY_ILLEGAL_ARCHCHANGE, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp), 0);
+      illegal = POLICY_ILLEGAL_ARCHCHANGE;
     else if (p == SOLVER_SOLUTION_REPLACE_VENDORCHANGE)
-      return pool_tmpjoin($self->solv->pool, "allow ", policy_illegal2str($self->solv, POLICY_ILLEGAL_VENDORCHANGE, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp), 0);
+      illegal = POLICY_ILLEGAL_VENDORCHANGE;
+    else if (p == SOLVER_SOLUTION_REPLACE_NAMECHANGE)
+      illegal = POLICY_ILLEGAL_NAMECHANGE;
+    if (illegal)
+      return pool_tmpjoin($self->solv->pool, "allow ", policy_illegal2str($self->solv, illegal, $self->solv->pool->solvables + $self->p, $self->solv->pool->solvables + $self->rp), 0);
     return solver_solutionelement2str($self->solv, p, rp);
   }
-  %newobject replaceelements;
   %typemap(out) Queue replaceelements Queue2Array(Solutionelement *, 1, new_Solutionelement(arg1->solv, arg1->problemid, arg1->solutionid, arg1->id, id, arg1->p, arg1->rp));
+  %newobject replaceelements;
   Queue replaceelements() {
     Queue q;
     int illegal;
@@ -2201,6 +2657,8 @@ typedef struct {
       queue_push(&q, SOLVER_SOLUTION_REPLACE_ARCHCHANGE);
     if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0)
       queue_push(&q, SOLVER_SOLUTION_REPLACE_VENDORCHANGE);
+    if ((illegal & POLICY_ILLEGAL_NAMECHANGE) != 0)
+      queue_push(&q, SOLVER_SOLUTION_REPLACE_NAMECHANGE);
     if (!q.count)
       queue_push(&q, $self->type);
     return q;
@@ -2223,7 +2681,7 @@ typedef struct {
       return new_XSolvable(e->solv->pool, e->rp);
     }
     SWIGINTERN int Solutionelement_jobidx_get(Solutionelement *e) {
-      if (e->type != SOLVER_SOLUTION_JOB)
+      if (e->type != SOLVER_SOLUTION_JOB && e->type != SOLVER_SOLUTION_POOLJOB)
         return -1;
       return (e->p - 1) / 2;
     }
@@ -2231,12 +2689,12 @@ typedef struct {
   %newobject Job;
   Job *Job() {
     Id extraflags = solver_solutionelement_extrajobflags($self->solv, $self->problemid, $self->solutionid);
-    if ($self->type == SOLVER_SOLUTION_JOB)
+    if ($self->type == SOLVER_SOLUTION_JOB || SOLVER_SOLUTION_POOLJOB)
       return new_Job($self->solv->pool, SOLVER_NOOP, 0);
-    if ($self->type == SOLVER_SOLUTION_INFARCH || $self->type == SOLVER_SOLUTION_DISTUPGRADE)
-      return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE|extraflags, $self->p);
-    if ($self->type == SOLVER_SOLUTION_REPLACE || $self->type == SOLVER_SOLUTION_REPLACE_DOWNGRADE || $self->type == SOLVER_SOLUTION_REPLACE_ARCHCHANGE || $self->type == SOLVER_SOLUTION_REPLACE_VENDORCHANGE)
-      return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE|extraflags, $self->rp);
+    if ($self->type == SOLVER_SOLUTION_INFARCH || $self->type == SOLVER_SOLUTION_DISTUPGRADE || $self->type == SOLVER_SOLUTION_BEST)
+      return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE|SOLVER_NOTBYUSER|extraflags, $self->p);
+    if ($self->type == SOLVER_SOLUTION_REPLACE || $self->type == SOLVER_SOLUTION_REPLACE_DOWNGRADE || $self->type == SOLVER_SOLUTION_REPLACE_ARCHCHANGE || $self->type == SOLVER_SOLUTION_REPLACE_VENDORCHANGE || $self->type == SOLVER_SOLUTION_REPLACE_NAMECHANGE)
+      return new_Job($self->solv->pool, SOLVER_INSTALL|SOLVER_SOLVABLE|SOLVER_NOTBYUSER|extraflags, $self->rp);
     if ($self->type == SOLVER_SOLUTION_ERASE)
       return new_Job($self->solv->pool, SOLVER_ERASE|SOLVER_SOLVABLE|extraflags, $self->p);
     return 0;
@@ -2259,33 +2717,59 @@ typedef struct {
   static const int SOLVER_RULE_FEATURE = SOLVER_RULE_FEATURE;
   static const int SOLVER_RULE_JOB = SOLVER_RULE_JOB;
   static const int SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP = SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP;
+  static const int SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM = SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM;
+  static const int SOLVER_RULE_JOB_UNKNOWN_PACKAGE = SOLVER_RULE_JOB_UNKNOWN_PACKAGE;
+  static const int SOLVER_RULE_JOB_UNSUPPORTED = SOLVER_RULE_JOB_UNSUPPORTED;
   static const int SOLVER_RULE_DISTUPGRADE = SOLVER_RULE_DISTUPGRADE;
   static const int SOLVER_RULE_INFARCH = SOLVER_RULE_INFARCH;
   static const int SOLVER_RULE_CHOICE = SOLVER_RULE_CHOICE;
   static const int SOLVER_RULE_LEARNT = SOLVER_RULE_LEARNT;
 
   static const int SOLVER_SOLUTION_JOB = SOLVER_SOLUTION_JOB;
+  static const int SOLVER_SOLUTION_POOLJOB = SOLVER_SOLUTION_POOLJOB;
   static const int SOLVER_SOLUTION_INFARCH = SOLVER_SOLUTION_INFARCH;
   static const int SOLVER_SOLUTION_DISTUPGRADE = SOLVER_SOLUTION_DISTUPGRADE;
+  static const int SOLVER_SOLUTION_BEST = SOLVER_SOLUTION_BEST;
   static const int SOLVER_SOLUTION_ERASE = SOLVER_SOLUTION_ERASE;
   static const int SOLVER_SOLUTION_REPLACE = SOLVER_SOLUTION_REPLACE;
   static const int SOLVER_SOLUTION_REPLACE_DOWNGRADE = SOLVER_SOLUTION_REPLACE_DOWNGRADE;
   static const int SOLVER_SOLUTION_REPLACE_ARCHCHANGE = SOLVER_SOLUTION_REPLACE_ARCHCHANGE;
   static const int SOLVER_SOLUTION_REPLACE_VENDORCHANGE = SOLVER_SOLUTION_REPLACE_VENDORCHANGE;
+  static const int SOLVER_SOLUTION_REPLACE_NAMECHANGE = SOLVER_SOLUTION_REPLACE_NAMECHANGE;
 
   static const int POLICY_ILLEGAL_DOWNGRADE = POLICY_ILLEGAL_DOWNGRADE;
   static const int POLICY_ILLEGAL_ARCHCHANGE = POLICY_ILLEGAL_ARCHCHANGE;
   static const int POLICY_ILLEGAL_VENDORCHANGE = POLICY_ILLEGAL_VENDORCHANGE;
+  static const int POLICY_ILLEGAL_NAMECHANGE = POLICY_ILLEGAL_NAMECHANGE;
 
   static const int SOLVER_FLAG_ALLOW_DOWNGRADE = SOLVER_FLAG_ALLOW_DOWNGRADE;
   static const int SOLVER_FLAG_ALLOW_ARCHCHANGE = SOLVER_FLAG_ALLOW_ARCHCHANGE;
   static const int SOLVER_FLAG_ALLOW_VENDORCHANGE = SOLVER_FLAG_ALLOW_VENDORCHANGE;
+  static const int SOLVER_FLAG_ALLOW_NAMECHANGE = SOLVER_FLAG_ALLOW_NAMECHANGE;
   static const int SOLVER_FLAG_ALLOW_UNINSTALL = SOLVER_FLAG_ALLOW_UNINSTALL;
   static const int SOLVER_FLAG_NO_UPDATEPROVIDE = SOLVER_FLAG_NO_UPDATEPROVIDE;
   static const int SOLVER_FLAG_SPLITPROVIDES = SOLVER_FLAG_SPLITPROVIDES;
   static const int SOLVER_FLAG_IGNORE_RECOMMENDED = SOLVER_FLAG_IGNORE_RECOMMENDED;
   static const int SOLVER_FLAG_ADD_ALREADY_RECOMMENDED = SOLVER_FLAG_ADD_ALREADY_RECOMMENDED;
   static const int SOLVER_FLAG_NO_INFARCHCHECK = SOLVER_FLAG_NO_INFARCHCHECK;
+  static const int SOLVER_FLAG_BEST_OBEY_POLICY = SOLVER_FLAG_BEST_OBEY_POLICY;
+  static const int SOLVER_FLAG_NO_AUTOTARGET = SOLVER_FLAG_NO_AUTOTARGET;
+  static const int SOLVER_FLAG_DUP_ALLOW_DOWNGRADE = SOLVER_FLAG_DUP_ALLOW_DOWNGRADE;
+  static const int SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE = SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE;
+  static const int SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE = SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE;
+  static const int SOLVER_FLAG_DUP_ALLOW_NAMECHANGE = SOLVER_FLAG_DUP_ALLOW_NAMECHANGE;
+
+  static const int SOLVER_REASON_UNRELATED = SOLVER_REASON_UNRELATED;
+  static const int SOLVER_REASON_UNIT_RULE = SOLVER_REASON_UNIT_RULE;
+  static const int SOLVER_REASON_KEEP_INSTALLED = SOLVER_REASON_KEEP_INSTALLED;
+  static const int SOLVER_REASON_RESOLVE_JOB = SOLVER_REASON_RESOLVE_JOB;
+  static const int SOLVER_REASON_UPDATE_INSTALLED = SOLVER_REASON_UPDATE_INSTALLED;
+  static const int SOLVER_REASON_CLEANDEPS_ERASE = SOLVER_REASON_CLEANDEPS_ERASE;
+  static const int SOLVER_REASON_RESOLVE = SOLVER_REASON_RESOLVE;
+  static const int SOLVER_REASON_WEAKDEP = SOLVER_REASON_WEAKDEP;
+  static const int SOLVER_REASON_RESOLVE_ORPHAN = SOLVER_REASON_RESOLVE_ORPHAN;
+  static const int SOLVER_REASON_RECOMMENDED = SOLVER_REASON_RECOMMENDED;
+  static const int SOLVER_REASON_SUPPLEMENTED = SOLVER_REASON_SUPPLEMENTED;
 
   ~Solver() {
     solver_free($self);
@@ -2343,6 +2827,13 @@ rb_eval_string(
   Transaction *transaction() {
     return solver_create_transaction($self);
   }
+
+  int describe_decision(XSolvable *s, XRule **OUTPUT) {
+    int ruleid;
+    int reason = solver_describe_decision($self, s->id, &ruleid);
+    *OUTPUT = new_XRule($self, ruleid);
+    return reason;
+  }
 }
 
 %extend Transaction {
@@ -2367,6 +2858,7 @@ rb_eval_string(
   static const int SOLVER_TRANSACTION_SHOW_OBSOLETES = SOLVER_TRANSACTION_SHOW_OBSOLETES;
   static const int SOLVER_TRANSACTION_SHOW_MULTIINSTALL = SOLVER_TRANSACTION_SHOW_MULTIINSTALL;
   static const int SOLVER_TRANSACTION_CHANGE_IS_REINSTALL = SOLVER_TRANSACTION_CHANGE_IS_REINSTALL;
+  static const int SOLVER_TRANSACTION_OBSOLETE_IS_UPGRADE = SOLVER_TRANSACTION_OBSOLETE_IS_UPGRADE;
   static const int SOLVER_TRANSACTION_MERGE_VENDORCHANGES = SOLVER_TRANSACTION_MERGE_VENDORCHANGES;
   static const int SOLVER_TRANSACTION_MERGE_ARCHCHANGES = SOLVER_TRANSACTION_MERGE_ARCHCHANGES;
   static const int SOLVER_TRANSACTION_RPM_ONLY = SOLVER_TRANSACTION_RPM_ONLY;
@@ -2389,8 +2881,8 @@ rb_eval_string(
     return new_XSolvable($self->pool, op);
   }
 
-  %newobject allothersolvables;
   %typemap(out) Queue allothersolvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
+  %newobject allothersolvables;
   Queue allothersolvables(XSolvable *s) {
     Queue q;
     queue_init(&q);
@@ -2407,6 +2899,7 @@ rb_eval_string(
     return q;
   }
 
+  # deprecated, use newsolvables instead
   %typemap(out) Queue newpackages Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
   %newobject newpackages;
   Queue newpackages() {
@@ -2418,6 +2911,7 @@ rb_eval_string(
     return q;
   }
 
+  # deprecated, use keptsolvables instead
   %typemap(out) Queue keptpackages Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
   %newobject keptpackages;
   Queue keptpackages() {
@@ -2430,8 +2924,31 @@ rb_eval_string(
     return q;
   }
 
+  %typemap(out) Queue newsolvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
+  %newobject newsolvables;
+  Queue newsolvables() {
+    Queue q;
+    int cut;
+    queue_init(&q);
+    cut = transaction_installedresult(self, &q);
+    queue_truncate(&q, cut);
+    return q;
+  }
+
+  %typemap(out) Queue keptsolvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
+  %newobject keptsolvables;
+  Queue keptsolvables() {
+    Queue q;
+    int cut;
+    queue_init(&q);
+    cut = transaction_installedresult(self, &q);
+    if (cut)
+      queue_deleten(&q, 0, cut);
+    return q;
+  }
+
   %typemap(out) Queue steps Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id));
-  %newobject steps ;
+  %newobject steps;
   Queue steps() {
     Queue q;
     queue_init_clone(&q, &$self->steps);
@@ -2444,7 +2961,7 @@ rb_eval_string(
   int calc_installsizechange() {
     return transaction_calc_installsizechange($self);
   }
-  void order(int flags) {
+  void order(int flags=0) {
     transaction_order($self, flags);
   }
 }
@@ -2460,14 +2977,24 @@ rb_eval_string(
     cl->toid = toid;
     return cl;
   }
-  %newobject solvables;
   %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->transaction->pool, id));
+  %newobject solvables;
   Queue solvables() {
     Queue q;
     queue_init(&q);
     transaction_classify_pkgs($self->transaction, $self->mode, $self->type, $self->fromid, $self->toid, &q);
     return q;
   }
+  const char * const fromstr;
+  const char * const tostr;
+  %{
+    SWIGINTERN const char *TransactionClass_fromstr_get(TransactionClass *cl) {
+      return pool_id2str(cl->transaction->pool, cl->fromid);
+    }
+    SWIGINTERN const char *TransactionClass_tostr_get(TransactionClass *cl) {
+      return pool_id2str(cl->transaction->pool, cl->toid);
+    }
+  %}
 }
 
 %extend XRule {
@@ -2479,9 +3006,16 @@ rb_eval_string(
     xr->id = id;
     return xr;
   }
+  int const type;
+  %{
+    SWIGINTERN int XRule_type_get(XRule *xr) {
+      return solver_ruleclass(xr->solv, xr->id);
+    }
+  %}
+  %newobject info;
   Ruleinfo *info() {
     Id type, source, target, dep;
-    type =  solver_ruleinfo($self->solv, $self->id, &source, &target, &dep);
+    type = solver_ruleinfo($self->solv, $self->id, &source, &target, &dep);
     return new_Ruleinfo($self, type, source, target, dep);
   }
   %typemap(out) Queue allinfos Queue2Array(Ruleinfo *, 4, new_Ruleinfo(arg1, id, idp[1], idp[2], idp[3]));
@@ -2508,18 +3042,22 @@ rb_eval_string(
 }
 
 %extend Ruleinfo {
-  Ruleinfo(XRule *r, Id type, Id source, Id target, Id dep) {
+  Ruleinfo(XRule *r, Id type, Id source, Id target, Id dep_id) {
     Ruleinfo *ri = solv_calloc(1, sizeof(*ri));
     ri->solv = r->solv;
     ri->rid = r->id;
     ri->type = type;
     ri->source = source;
     ri->target = target;
-    ri->dep = dep;
+    ri->dep_id = dep_id;
     return ri;
   }
+  %newobject solvable;
   XSolvable * const solvable;
+  %newobject othersolvable;
   XSolvable * const othersolvable;
+  %newobject dep;
+  Dep * const dep;
   %{
     SWIGINTERN XSolvable *Ruleinfo_solvable_get(Ruleinfo *ri) {
       return new_XSolvable(ri->solv->pool, ri->source);
@@ -2527,9 +3065,12 @@ rb_eval_string(
     SWIGINTERN XSolvable *Ruleinfo_othersolvable_get(Ruleinfo *ri) {
       return new_XSolvable(ri->solv->pool, ri->target);
     }
+    SWIGINTERN Dep *Ruleinfo_dep_get(Ruleinfo *ri) {
+      return new_Dep(ri->solv->pool, ri->dep_id);
+    }
   %}
   const char *problemstr() {
-    return solver_problemruleinfo2str($self->solv, $self->type, $self->source, $self->target, $self->dep);
+    return solver_problemruleinfo2str($self->solv, $self->type, $self->source, $self->target, $self->dep_id);
   }
 }
 
@@ -2543,7 +3084,7 @@ rb_eval_string(
   Id new_handle() {
     return repodata_new_handle(repo_id2repodata($self->repo, $self->id));
   }
-  void set_id(Id solvid, Id keyname, Id id) {
+  void set_id(Id solvid, Id keyname, DepId id) {
     repodata_set_id(repo_id2repodata($self->repo, $self->id), solvid, keyname, id);
   }
   void set_str(Id solvid, Id keyname, const char *str) {
@@ -2552,7 +3093,7 @@ rb_eval_string(
   void set_poolstr(Id solvid, Id keyname, const char *str) {
     repodata_set_poolstr(repo_id2repodata($self->repo, $self->id), solvid, keyname, str);
   }
-  void add_idarray(Id solvid, Id keyname, Id id) {
+  void add_idarray(Id solvid, Id keyname, DepId id) {
     repodata_add_idarray(repo_id2repodata($self->repo, $self->id), solvid, keyname, id);
   }
   void add_flexarray(Id solvid, Id keyname, Id handle) {
@@ -2582,10 +3123,12 @@ rb_eval_string(
     repodata_internalize(repo_id2repodata($self->repo, $self->id));
   }
   void create_stubs() {
-    repodata_create_stubs(repo_id2repodata($self->repo, $self->id));
+    Repodata *data = repo_id2repodata($self->repo, $self->id);
+    data = repodata_create_stubs(data);
+    $self->id = data->repodataid;
   }
-  void write(FILE *fp) {
-    repodata_write(repo_id2repodata($self->repo, $self->id), fp);
+  bool write(FILE *fp) {
+    return repodata_write(repo_id2repodata($self->repo, $self->id), fp) == 0;
   }
   bool add_solv(FILE *fp, int flags = 0) {
     Repodata *data = repo_id2repodata($self->repo, $self->id);
@@ -2614,3 +3157,24 @@ rb_eval_string(
   }
 }
 
+#ifdef ENABLE_PUBKEY
+%extend Solvsig {
+  Solvsig(FILE *fp) {
+    return solvsig_create(fp);
+  }
+  ~Solvsig() {
+    solvsig_free($self);
+  }
+  %newobject Chksum;
+  Chksum *Chksum() {
+    return $self->htype ? (Chksum *)solv_chksum_create($self->htype) : 0;
+  }
+#ifdef ENABLE_PGPVRFY
+  %newobject verify;
+  XSolvable *verify(Repo *repo, Chksum *chksum) {
+    Id p = solvsig_verify($self, repo, chksum);
+    return new_XSolvable(repo->pool, p);
+  }
+#endif
+}
+#endif