+}
+
+/* Tests if two solvables have identical content. Currently
+ * both solvables need to come from the same pool
+ */
+
+int
+solvable_identical(Solvable *s1, Solvable *s2)
+{
+ unsigned int bt1, bt2;
+ Id rq1, rq2;
+ Id *reqp;
+ if (s1->name != s2->name)
+ return 0;
+ if (s1->arch != s2->arch)
+ return 0;
+ if (s1->evr != s2->evr)
+ return 0;
+
+ /* check vendor, map missing vendor to empty string */
+ if ((s1->vendor ? s1->vendor : 1) != (s2->vendor ? s2->vendor : 1))
+ {
+ /* workaround for bug 881493 */
+ if (s1->repo && !strncmp(pool_id2str(s1->repo->pool, s1->name), "product:", 8))
+ return 1;
+ return 0;
+ }
+
+ /* looking good, try some fancier stuff */
+ /* might also look up the package checksum here */
+ bt1 = solvable_lookup_num(s1, SOLVABLE_BUILDTIME, 0);
+ bt2 = solvable_lookup_num(s2, SOLVABLE_BUILDTIME, 0);
+ if (bt1 && bt2)
+ {
+ if (bt1 != bt2)
+ return 0;
+ }
+ else
+ {
+ /* workaround for bug 881493 */
+ if (s1->repo && !strncmp(pool_id2str(s1->repo->pool, s1->name), "product:", 8))
+ return 1;
+ /* look at requires in a last attempt to find recompiled packages */
+ rq1 = rq2 = 0;
+ if (s1->requires)
+ for (reqp = s1->repo->idarraydata + s1->requires; *reqp; reqp++)
+ rq1 ^= *reqp;
+ if (s2->requires)
+ for (reqp = s2->repo->idarraydata + s2->requires; *reqp; reqp++)
+ rq2 ^= *reqp;
+ if (rq1 != rq2)
+ return 0;
+ }
+ return 1;
+}
+
+/* return the self provide dependency of a solvable */
+Id
+solvable_selfprovidedep(Solvable *s)
+{
+ Pool *pool;
+ Reldep *rd;
+ Id prov, *provp;
+
+ if (!s->repo)
+ return s->name;
+ pool = s->repo->pool;
+ if (s->provides)
+ {
+ provp = s->repo->idarraydata + s->provides;
+ while ((prov = *provp++) != 0)
+ {
+ if (!ISRELDEP(prov))
+ continue;
+ rd = GETRELDEP(pool, prov);
+ if (rd->name == s->name && rd->evr == s->evr && rd->flags == REL_EQ)
+ return prov;
+ }
+ }
+ return pool_rel2id(pool, s->name, s->evr, REL_EQ, 1);
+}
+
+/* setter functions, simply call the repo variants */
+void
+solvable_set_id(Solvable *s, Id keyname, Id id)
+{
+ repo_set_id(s->repo, s - s->repo->pool->solvables, keyname, id);
+}
+
+void
+solvable_set_num(Solvable *s, Id keyname, unsigned long long num)
+{
+ repo_set_num(s->repo, s - s->repo->pool->solvables, keyname, num);
+}
+
+void
+solvable_set_str(Solvable *s, Id keyname, const char *str)
+{
+ repo_set_str(s->repo, s - s->repo->pool->solvables, keyname, str);
+}
+
+void
+solvable_set_poolstr(Solvable *s, Id keyname, const char *str)
+{
+ repo_set_poolstr(s->repo, s - s->repo->pool->solvables, keyname, str);
+}
+
+void
+solvable_add_poolstr_array(Solvable *s, Id keyname, const char *str)
+{
+ repo_add_poolstr_array(s->repo, s - s->repo->pool->solvables, keyname, str);
+}
+
+void
+solvable_add_idarray(Solvable *s, Id keyname, Id id)
+{
+ repo_add_idarray(s->repo, s - s->repo->pool->solvables, keyname, id);
+}
+
+void
+solvable_add_deparray(Solvable *s, Id keyname, Id dep, Id marker)
+{
+ repo_add_deparray(s->repo, s - s->repo->pool->solvables, keyname, dep, marker);
+}
+
+void
+solvable_set_idarray(Solvable *s, Id keyname, Queue *q)
+{
+ repo_set_idarray(s->repo, s - s->repo->pool->solvables, keyname, q);
+}
+
+void
+solvable_set_deparray(Solvable *s, Id keyname, Queue *q, Id marker)
+{
+ repo_set_deparray(s->repo, s - s->repo->pool->solvables, keyname, q, marker);
+}
+
+void
+solvable_unset(Solvable *s, Id keyname)
+{
+ repo_unset(s->repo, s - s->repo->pool->solvables, keyname);
+}
+
+/* return true if a dependency intersects dep in the keyname array */
+int
+solvable_matchesdep(Solvable *s, Id keyname, Id dep, int marker)
+{
+ int i;
+ Pool *pool = s->repo->pool;
+ Queue q;
+ queue_init(&q);
+ solvable_lookup_deparray(s, keyname, &q, marker);
+ for (i = 0; i < q.count; i++)
+ if (pool_match_dep(pool, q.elements[i], dep))
+ break;
+ i = i == q.count ? 0 : 1;
+ queue_free(&q);
+ return i;