+#define FIND_INVOLVED_DEBUG 0
+void
+solver_find_involved(Solver *solv, Queue *installedq, Solvable *ts, Queue *q)
+{
+ Pool *pool = solv->pool;
+ Map im;
+ Map installedm;
+ Solvable *s;
+ Queue iq;
+ Queue installedq_internal;
+ Id tp, ip, p, pp, req, *reqp, sup, *supp;
+ int i, count;
+
+ tp = ts - pool->solvables;
+ queue_init(&iq);
+ queue_init(&installedq_internal);
+ map_init(&im, pool->nsolvables);
+ map_init(&installedm, pool->nsolvables);
+
+ if (!installedq)
+ {
+ installedq = &installedq_internal;
+ if (solv->installed)
+ {
+ for (ip = solv->installed->start; ip < solv->installed->end; ip++)
+ {
+ s = pool->solvables + ip;
+ if (s->repo != solv->installed)
+ continue;
+ queue_push(installedq, ip);
+ }
+ }
+ }
+ for (i = 0; i < installedq->count; i++)
+ {
+ ip = installedq->elements[i];
+ MAPSET(&installedm, ip);
+ MAPSET(&im, ip);
+ }
+
+ queue_push(&iq, ts - pool->solvables);
+ while (iq.count)
+ {
+ ip = queue_shift(&iq);
+ if (!MAPTST(&im, ip))
+ continue;
+ if (!MAPTST(&installedm, ip))
+ continue;
+ MAPCLR(&im, ip);
+ s = pool->solvables + ip;
+#if FIND_INVOLVED_DEBUG
+ printf("hello %s\n", solvable2str(pool, s));
+#endif
+ if (s->requires)
+ {
+ reqp = s->repo->idarraydata + s->requires;
+ while ((req = *reqp++) != 0)
+ {
+ if (req == SOLVABLE_PREREQMARKER)
+ continue;
+ /* count number of installed packages that match */
+ count = 0;
+ FOR_PROVIDES(p, pp, req)
+ if (MAPTST(&installedm, p))
+ count++;
+ if (count > 1)
+ continue;
+ FOR_PROVIDES(p, pp, req)
+ {
+ if (MAPTST(&im, p))
+ {
+#if FIND_INVOLVED_DEBUG
+ printf("%s requires %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p));
+#endif
+ queue_push(&iq, p);
+ }
+ }
+ }
+ }
+ if (s->recommends)
+ {
+ reqp = s->repo->idarraydata + s->recommends;
+ while ((req = *reqp++) != 0)
+ {
+ count = 0;
+ FOR_PROVIDES(p, pp, req)
+ if (MAPTST(&installedm, p))
+ count++;
+ if (count > 1)
+ continue;
+ FOR_PROVIDES(p, pp, req)
+ {
+ if (MAPTST(&im, p))
+ {
+#if FIND_INVOLVED_DEBUG
+ printf("%s recommends %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p));
+#endif
+ queue_push(&iq, p);
+ }
+ }
+ }
+ }
+ if (!iq.count)
+ {
+ /* supplements pass */
+ for (i = 0; i < installedq->count; i++)
+ {
+ ip = installedq->elements[i];
+ s = pool->solvables + ip;
+ if (!s->supplements)
+ continue;
+ if (!MAPTST(&im, ip))
+ continue;
+ supp = s->repo->idarraydata + s->supplements;
+ while ((sup = *supp++) != 0)
+ if (!dep_possible(solv, sup, &im) && dep_possible(solv, sup, &installedm))
+ break;
+ /* no longer supplemented, also erase */
+ if (sup)
+ {
+#if FIND_INVOLVED_DEBUG
+ printf("%s supplemented\n", solvable2str(pool, pool->solvables + ip));
+#endif
+ queue_push(&iq, ip);
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < installedq->count; i++)
+ {
+ ip = installedq->elements[i];
+ if (MAPTST(&im, ip))
+ queue_push(&iq, ip);
+ }
+
+ while (iq.count)
+ {
+ ip = queue_shift(&iq);
+ if (!MAPTST(&installedm, ip))
+ continue;
+ s = pool->solvables + ip;
+#if FIND_INVOLVED_DEBUG
+ printf("bye %s\n", solvable2str(pool, s));
+#endif
+ if (s->requires)
+ {
+ reqp = s->repo->idarraydata + s->requires;
+ while ((req = *reqp++) != 0)
+ {
+ FOR_PROVIDES(p, pp, req)
+ {
+ if (!MAPTST(&im, p))
+ {
+ if (p == tp)
+ continue;
+#if FIND_INVOLVED_DEBUG
+ printf("%s requires %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p));
+#endif
+ MAPSET(&im, p);
+ queue_push(&iq, p);
+ }
+ }
+ }
+ }
+ if (s->recommends)
+ {
+ reqp = s->repo->idarraydata + s->recommends;
+ while ((req = *reqp++) != 0)
+ {
+ FOR_PROVIDES(p, pp, req)
+ {
+ if (!MAPTST(&im, p))
+ {
+ if (p == tp)
+ continue;
+#if FIND_INVOLVED_DEBUG
+ printf("%s recommends %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p));
+#endif
+ MAPSET(&im, p);
+ queue_push(&iq, p);
+ }
+ }
+ }
+ }
+ if (!iq.count)
+ {
+ /* supplements pass */
+ for (i = 0; i < installedq->count; i++)
+ {
+ ip = installedq->elements[i];
+ if (ip == tp)
+ continue;
+ s = pool->solvables + ip;
+ if (!s->supplements)
+ continue;
+ if (MAPTST(&im, ip))
+ continue;
+ supp = s->repo->idarraydata + s->supplements;
+ while ((sup = *supp++) != 0)
+ if (dep_possible(solv, sup, &im))
+ break;
+ if (sup)
+ {
+#if FIND_INVOLVED_DEBUG
+ printf("%s supplemented\n", solvable2str(pool, pool->solvables + ip));
+#endif
+ MAPSET(&im, ip);
+ queue_push(&iq, ip);
+ }
+ }
+ }
+ }
+
+ queue_free(&iq);
+
+ /* convert map into result */
+ for (i = 0; i < installedq->count; i++)
+ {
+ ip = installedq->elements[i];
+ if (MAPTST(&im, ip))
+ continue;
+ if (ip == ts - pool->solvables)
+ continue;
+ queue_push(q, ip);
+ }
+ map_free(&im);
+ map_free(&installedm);
+ queue_free(&installedq_internal);
+}
+