[svn] r6529 - in trunk/rpms: . aptitude fail2ban html2text htmldoc icmptx po4a pychecker synaptic wine

packagers at lists.rpmforge.net packagers at lists.rpmforge.net
Fri Oct 31 01:09:10 CET 2008


Author: dag
Date: 2008-10-31 00:09:09 +0000 (Fri, 31 Oct 2008)
New Revision: 6529

Added:
   trunk/rpms/aptitude/
   trunk/rpms/aptitude/aptitude-0.4.4-alt1.patch
   trunk/rpms/aptitude/aptitude-0.4.4-xsl-stylesheets.patch
   trunk/rpms/aptitude/aptitude.spec
   trunk/rpms/html2text/
   trunk/rpms/html2text/html2text-1.3.2.spec
   trunk/rpms/html2text/html2text.spec
   trunk/rpms/po4a/
   trunk/rpms/po4a/po4a.spec
   trunk/rpms/pychecker/pychecker-0.8.17-root.patch
   trunk/rpms/pychecker/pychecker-0.8.17-spe.patch
Modified:
   trunk/rpms/fail2ban/fail2ban.spec
   trunk/rpms/htmldoc/htmldoc.spec
   trunk/rpms/icmptx/icmptx.spec
   trunk/rpms/pychecker/pychecker.spec
   trunk/rpms/synaptic/synaptic.spec
   trunk/rpms/wine/wine.spec
Log:
Updates

Added: trunk/rpms/aptitude/aptitude-0.4.4-alt1.patch
===================================================================
--- trunk/rpms/aptitude/aptitude-0.4.4-alt1.patch	                        (rev 0)
+++ trunk/rpms/aptitude/aptitude-0.4.4-alt1.patch	2008-10-31 00:09:09 UTC (rev 6529)
@@ -0,0 +1,24368 @@
+ INSTALL                                       |  236 -
+ Makefile.in                                   |  688 --
+ aclocal.m4                                    | 1029 ---
+ config.guess                                  | 1500 ----
+ config.h.in                                   |  145 -
+ config.sub                                    | 1616 ----
+ configure                                     |11070 -------------------------
+ configure.ac                                  |   28 +-
+ depcomp                                       |  530 --
+ doc/aptitude-html.xsl                         |    2 +-
+ doc/aptitude-man.xsl                          |    2 +-
+ doc/aptitude-txt.xsl                          |    2 +-
+ doc/cs/Makefile.am                            |    4 +-
+ doc/de/Makefile.am                            |    4 +-
+ doc/en/Makefile.am                            |    4 +-
+ doc/fi/Makefile.am                            |    4 +-
+ doc/fr/Makefile.am                            |    4 +-
+ help-cs.txt                                   |    3 +-
+ help-de.txt                                   |    1 -
+ help-it.txt                                   |    1 -
+ help-ru.txt                                   |    1 -
+ help.txt                                      |    1 -
+ install-sh                                    |  323 -
+ missing                                       |  360 -
+ mkinstalldirs                                 |  158 -
+ po/POTFILES.in                                |   47 -
+ po/aptitude.pot                               |    6 +-
+ po/ar.po                                      |   14 +-
+ po/bs.po                                      |    6 +-
+ po/ca.po                                      |   16 +-
+ po/cs.po                                      |   13 +-
+ po/da.po                                      |   12 +-
+ po/de.po                                      |   14 +-
+ po/el.po                                      |   15 +-
+ po/es.po                                      |   15 +-
+ po/eu.po                                      |   12 +-
+ po/fi.po                                      |   12 +-
+ po/fr.po                                      |   14 +-
+ po/gl.po                                      |   13 +-
+ po/hu.po                                      |   15 +-
+ po/it.po                                      |   13 +-
+ po/ja.po                                      |   15 +-
+ po/lt.po                                      |   13 +-
+ po/nb.po                                      |   13 +-
+ po/nl.po                                      |   13 +-
+ po/nn.po                                      |   14 +-
+ po/pl.po                                      |   12 +-
+ po/pt.po                                      |   15 +-
+ po/pt_BR.po                                   |   15 +-
+ po/ro.po                                      |   13 +-
+ po/ru.po                                      |   13 +-
+ po/sk.po                                      |   15 +-
+ po/stamp-po                                   |    1 -
+ po/sv.po                                      |   15 +-
+ po/tl.po                                      |   13 +-
+ po/tr.po                                      |   13 +-
+ po/vi.po                                      |   15 +-
+ po/zh_CN.po                                   |   12 +-
+ po/zh_TW.po                                   |   14 +-
+ src/Makefile.am                               |   16 -
+ src/Makefile.in                               |  718 --
+ src/apt_options.cc                            |    3 -
+ src/broken_indicator.cc                       |  391 -
+ src/broken_indicator.h                        |   32 -
+ src/changelog_parse.cc                        |  164 -
+ src/changelog_parse.h                         |   39 -
+ src/cmdline/Makefile.am                       |    6 -
+ src/cmdline/Makefile.in                       |   24 +-
+ src/cmdline/cmdline_action.cc                 |   53 +-
+ src/cmdline/cmdline_action.h                  |    6 +-
+ src/cmdline/cmdline_changelog.cc              |  373 -
+ src/cmdline/cmdline_changelog.h               |   20 -
+ src/cmdline/cmdline_common.h                  |    2 +-
+ src/cmdline/cmdline_do_action.cc              |   16 +-
+ src/cmdline/cmdline_dump_resolver.cc          |   51 -
+ src/cmdline/cmdline_dump_resolver.h           |   26 -
+ src/cmdline/cmdline_prompt.cc                 |   82 +-
+ src/cmdline/cmdline_prompt.h                  |    2 -
+ src/cmdline/cmdline_resolver.cc               |  679 --
+ src/cmdline/cmdline_resolver.h                |   55 -
+ src/cmdline/cmdline_show.cc                   |    7 -
+ src/cmdline/cmdline_simulate.cc               |    3 +-
+ src/cmdline/cmdline_simulate.h                |    2 -
+ src/cmdline/cmdline_upgrade.cc                |    6 +-
+ src/cmdline/cmdline_util.cc                   |   13 -
+ src/cmdline/cmdline_util.h                    |    5 -
+ src/defaults.cc                               |    8 -
+ src/dep_item.cc                               |    3 +-
+ src/desc_parse.cc                             |   45 +-
+ src/desc_parse.h                              |    5 -
+ src/download_item.cc                          |    6 +
+ src/edit_pkg_hier.cc                          |  372 -
+ src/edit_pkg_hier.h                           |   83 -
+ src/generic/Makefile.am                       |    2 +-
+ src/generic/Makefile.in                       |  482 --
+ src/generic/apt/Makefile.am                   |   20 +-
+ src/generic/apt/Makefile.in                   |  521 --
+ src/generic/apt/apt.cc                        |   64 +-
+ src/generic/apt/apt.h                         |   16 -
+ src/generic/apt/aptcache.cc                   |  147 +-
+ src/generic/apt/aptcache.h                    |   29 -
+ src/generic/apt/aptitude_resolver.cc          |  172 -
+ src/generic/apt/aptitude_resolver.h           |  107 -
+ src/generic/apt/aptitude_resolver_universe.cc |  589 --
+ src/generic/apt/aptitude_resolver_universe.h  | 1148 ---
+ src/generic/apt/download_install_manager.cc   |   15 +-
+ src/generic/apt/download_manager.cc           |    2 +-
+ src/generic/apt/matchers.cc                   |  166 +-
+ src/generic/apt/matchers.h                    |    1 +
+ src/generic/apt/pkg_acqfile.cc                |   51 +-
+ src/generic/apt/pkg_acqfile.h                 |   43 +-
+ src/generic/apt/pkg_changelog.cc              |  212 -
+ src/generic/apt/pkg_changelog.h               |   59 -
+ src/generic/apt/pkg_hier.cc                   |  307 -
+ src/generic/apt/pkg_hier.h                    |  217 -
+ src/generic/apt/pkg_hier_dump.cc              |  209 -
+ src/generic/apt/resolver_manager.cc           |  928 ---
+ src/generic/apt/resolver_manager.h            |  520 --
+ src/generic/apt/tags.cc                       |  310 -
+ src/generic/apt/tags.h                        |  207 -
+ src/generic/apt/tasks.cc                      |  344 -
+ src/generic/apt/tasks.h                       |   47 -
+ src/generic/problemresolver/Makefile.am       |   11 -
+ src/generic/problemresolver/Makefile.in       |  428 -
+ src/generic/problemresolver/dummy_universe.cc |  358 -
+ src/generic/problemresolver/dummy_universe.h  |  776 --
+ src/generic/problemresolver/dump_universe.h   |   62 -
+ src/generic/problemresolver/exceptions.h      |   82 -
+ src/generic/problemresolver/model.tex         | 1358 ---
+ src/generic/problemresolver/problemresolver.h | 2825 -------
+ src/generic/problemresolver/resolver_undo.h   |   56 -
+ src/generic/problemresolver/solution.h        |  746 --
+ src/generic/problemresolver/test.cc           |  394 -
+ src/generic/problemresolver/test1.txt         |   25 -
+ src/generic/problemresolver/test3.txt         |   25 -
+ src/generic/problemresolver/test4.txt         |   23 -
+ src/generic/util/Makefile.in                  |  454 -
+ src/load_grouppolicy.cc                       |   48 -
+ src/main.cc                                   |   16 -
+ src/menu_redirect.cc                          |   55 -
+ src/menu_redirect.h                           |   28 -
+ src/menu_tree.cc                              |   48 -
+ src/menu_tree.h                               |   34 -
+ src/mine/Makefile.in                          |  467 --
+ src/pkg_columnizer.cc                         |    9 +-
+ src/pkg_grouppolicy.cc                        |  641 +--
+ src/pkg_grouppolicy.h                         |   78 -
+ src/pkg_info_screen.cc                        |    6 +-
+ src/pkg_item.cc                               |   85 -
+ src/pkg_item.h                                |    4 -
+ src/pkg_node.cc                               |    7 -
+ src/pkg_node.h                                |    2 -
+ src/pkg_subtree.cc                            |   10 -
+ src/pkg_subtree.h                             |    1 -
+ src/pkg_ver_item.cc                           |   29 +-
+ src/pkg_ver_item.h                            |    9 +-
+ src/pkg_view.cc                               |   45 +-
+ src/solution_dialog.cc                        |  208 -
+ src/solution_dialog.h                         |   31 -
+ src/solution_fragment.cc                      |  303 -
+ src/solution_fragment.h                       |   64 -
+ src/solution_item.cc                          |  615 --
+ src/solution_item.h                           |  214 -
+ src/solution_screen.cc                        |  603 --
+ src/solution_screen.h                         |   37 -
+ src/ui.cc                                     |  739 +--
+ src/ui.h                                      |   28 -
+ src/view_changelog.cc                         |  228 -
+ src/view_changelog.h                          |   15 -
+ src/vscreen/Makefile.in                       |  679 --
+ src/vscreen/config/Makefile.in                |  441 -
+ src/vscreen/config/style.h                    |    2 +-
+ src/vscreen/curses++.cc                       |    6 +-
+ src/vscreen/curses++.h                        |    2 +-
+ tests/Makefile.am                             |    4 +-
+ tests/Makefile.in                             |  547 --
+ tests/test_resolver.cc                        |  361 -
+ tests/test_tags.cc                            |  237 -
+ 178 files changed, 446 insertions(+), 42601 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 12fc5e2..8090059 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -30,6 +30,15 @@ AC_CHECK_LIB(pthread, main,
+ 	HAVE_LIBPTHREAD=1
+ 	, [AC_MSG_ERROR([Can't find the POSIX thread libraries])])
+ 
++dnl popt checking
++AC_CHECK_LIB(popt, main,
++      HAVE_POPT=1,
++              AC_MSG_ERROR([Can't find the popt library -- please install popt-devel package]))
++dnl rpm checking
++AC_CHECK_LIB(rpm, main,
++      HAVE_RPM=1,
++              AC_MSG_ERROR([Can't find the rpm library -- please install librpm-devel package]))
++
+ ALL_LINGUAS="ar bs ca cs da de el es eu fi fr gl hu it ja km ku lt nb nl nn pl pt pt_BR ro ru sk sv tl tr vi zh_CN zh_TW"
+ AM_GNU_GETTEXT([external])
+ 
+@@ -160,6 +169,24 @@ then
+ 	[AC_MSG_ERROR([POSIX thread header not installed])])
+ fi
+ 
++if test x$HAVE_RPM = x1
++then
++  AC_CHECK_HEADER(rpm/rpmio.h,
++              CXXFLAGS="$CXXFLAGS -I/usr/include/rpm"
++              LIBS="$LIBS -lrpm"
++              [AC_DEFINE(HAVE_RPM,  , [Define if rpm is available])],
++              [AC_MSG_ERROR([RPM headers not found. Please verify your build system.])])
++fi
++
++if test x$HAVE_POPT = x1
++then
++      AC_CHECK_HEADER(popt.h,
++              CXXFLAGS="$CXXFLAGS"
++              LIBS="$LIBS -lpopt"
++              [AC_DEFINE(HAVE_POPT,  , [Define if popt is available])],
++              [AC_MSG_ERROR([POPT headers not found. Please verify your build system.])])
++fi
++
+ WERROR="-Werror"
+ 
+ AC_ARG_ENABLE(dynamic-backtrace,
+@@ -277,7 +304,6 @@ AC_CONFIG_FILES([
+ 	src/cmdline/Makefile
+ 	src/generic/Makefile
+ 	src/generic/apt/Makefile
+-	src/generic/problemresolver/Makefile
+ 	src/generic/util/Makefile
+ 	src/mine/Makefile
+ 	src/vscreen/Makefile
+diff --git a/doc/aptitude-html.xsl b/doc/aptitude-html.xsl
+index e837df8..e5ba7ee 100644
+--- a/doc/aptitude-html.xsl
++++ b/doc/aptitude-html.xsl
+@@ -5,7 +5,7 @@
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+                 version="1.0">
+ 
+-<xsl:import href="/usr/share/xml/docbook/stylesheet/nwalsh/html/chunk.xsl"/>
++<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl"/>
+ 
+ <xsl:import href="aptitude-common.xsl"/>
+ 
+diff --git a/doc/aptitude-man.xsl b/doc/aptitude-man.xsl
+index 7d0ccc1..229062f 100644
+--- a/doc/aptitude-man.xsl
++++ b/doc/aptitude-man.xsl
+@@ -5,7 +5,7 @@
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+                 version="1.0">
+ 
+-<xsl:import href="/usr/share/xml/docbook/stylesheet/nwalsh/manpages/docbook.xsl"/>
++<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl"/>
+ 
+ <xsl:param name="chunker.output.method" select="'text'"/>
+ <xsl:param name="chunker.output.encoding" select="'UTF-8'"/>
+diff --git a/doc/aptitude-txt.xsl b/doc/aptitude-txt.xsl
+index 0a0c5c0..950eab4 100644
+--- a/doc/aptitude-txt.xsl
++++ b/doc/aptitude-txt.xsl
+@@ -5,7 +5,7 @@
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+                 version="1.0">
+ 
+-<xsl:import href="/usr/share/xml/docbook/stylesheet/nwalsh/html/docbook.xsl"/>
++<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
+ 
+ <xsl:import href="aptitude-common.xsl"/>
+ 
+diff --git a/doc/cs/Makefile.am b/doc/cs/Makefile.am
+index 0ce4e01..29b788a 100644
+--- a/doc/cs/Makefile.am
++++ b/doc/cs/Makefile.am
+@@ -59,7 +59,7 @@ doc-html-stamp: aptitude.xml ../aptitude-html.xsl ../aptitude-common.xsl $(IMAGE
+ 
+ 	mkdir output-html/images/
+ 	ln -f $(srcdir)/images/*.png output-html/images/
+-	for x in caution important note tip warning; do ln -s /usr/share/xml/docbook/stylesheet/nwalsh/images/$$x.png output-html/images/; done
+-	for x in home next prev up; do ln -s /usr/share/xml/docbook/stylesheet/nwalsh/images/$$x.gif output-html/images/; done
++	for x in caution important note tip warning; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
++	for x in home next prev up; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
+ 
+ 	touch doc-html-stamp
+diff --git a/doc/de/Makefile.am b/doc/de/Makefile.am
+index e1fc821..2153de7 100644
+--- a/doc/de/Makefile.am
++++ b/doc/de/Makefile.am
+@@ -61,8 +61,8 @@ doc-html-stamp: $(XMLSOURCES) $(srcdir)/../aptitude-html.xsl $(IMAGES)
+ 
+ 	mkdir output-html/images/
+ 	ln -f $(srcdir)/images/*.png output-html/images/
+-	for x in caution important note tip warning; do ln -s /usr/share/xml/docbook/stylesheet/nwalsh/images/$$x.png output-html/images/; done
+-	for x in home next prev up; do ln -s /usr/share/xml/docbook/stylesheet/nwalsh/images/$$x.gif output-html/images/; done
++	for x in caution important note tip warning; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
++	for x in home next prev up; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
+ 
+ 	touch doc-html-stamp
+ 
+diff --git a/doc/en/Makefile.am b/doc/en/Makefile.am
+index a004be2..aac7951 100644
+--- a/doc/en/Makefile.am
++++ b/doc/en/Makefile.am
+@@ -67,7 +67,7 @@ doc-html-stamp: aptitude.xml manpage.xml $(srcdir)/../aptitude-html.xsl $(srcdir
+ 
+ 	mkdir output-html/images/
+ 	ln -f $(srcdir)/images/*.png output-html/images/
+-	for x in caution important note tip warning; do ln -s /usr/share/xml/docbook/stylesheet/nwalsh/images/$$x.png output-html/images/; done
+-	for x in home next prev up; do ln -s /usr/share/xml/docbook/stylesheet/nwalsh/images/$$x.gif output-html/images/; done
++	for x in caution important note tip warning; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
++	for x in home next prev up; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
+ 
+ 	touch doc-html-stamp
+diff --git a/doc/fi/Makefile.am b/doc/fi/Makefile.am
+index 55f0e03..f95d055 100644
+--- a/doc/fi/Makefile.am
++++ b/doc/fi/Makefile.am
+@@ -58,7 +58,7 @@ doc-html-stamp: aptitude.xml manpage.xml $(srcdir)/../aptitude-html.xsl $(srcdir
+ 
+ 	mkdir output-html/images/
+ 	ln -f $(srcdir)/images/*.png output-html/images/
+-	for x in caution important note tip warning; do ln -s /usr/share/xml/docbook/stylesheet/nwalsh/images/$$x.png output-html/images/; done
+-	for x in home next prev up; do ln -s /usr/share/xml/docbook/stylesheet/nwalsh/images/$$x.gif output-html/images/; done
++	for x in caution important note tip warning; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
++	for x in home next prev up; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
+ 
+ 	touch doc-html-stamp
+diff --git a/doc/fr/Makefile.am b/doc/fr/Makefile.am
+index 7f45271..314fee3 100644
+--- a/doc/fr/Makefile.am
++++ b/doc/fr/Makefile.am
+@@ -68,7 +68,7 @@ doc-html-stamp: aptitude.xml manpage.xml $(srcdir)/../aptitude-html.xsl $(srcdir
+ 
+ 	mkdir output-html/images/
+ 	ln -f $(srcdir)/images/*.png output-html/images/
+-	for x in caution important note tip warning; do ln -s /usr/share/xml/docbook/stylesheet/nwalsh/images/$$x.png output-html/images/; done
+-	for x in home next prev up; do ln -s /usr/share/xml/docbook/stylesheet/nwalsh/images/$$x.gif output-html/images/; done
++	for x in caution important note tip warning; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
++	for x in home next prev up; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
+ 
+ 	touch doc-html-stamp
+diff --git a/help-cs.txt b/help-cs.txt
+index bcb44bd..a9c8409 100644
+--- a/help-cs.txt
++++ b/help-cs.txt
+@@ -19,7 +19,6 @@ všech kláves naleznete v souboru README.
+   "]":          Sbalí skupinu balíků a všechny její podskupiny.
+ 
+   Enter:        Zobrazí informace o balíku.
+-  "C":          Zobrazí seznam změn balíku (changelog).
+   "+":          Instaluje nebo aktualizuje balík, také zruší podržení.
+   "-":          Odstraní balík.
+   "=":          Podrží balík v aktuální verzi (zabrání aktualizaci).
+@@ -75,4 +74,4 @@ všech kláves naleznete v souboru README.
+    i - instalovat
+    r - reinstalovat
+    u - aktualizovat
+-   F - možná aktualizace byla zakázána klávesou "F"
+\ No newline at end of file
++   F - možná aktualizace byla zakázána klávesou "F"
+diff --git a/help-de.txt b/help-de.txt
+index fb5bbf1..fc4fc14 100644
+--- a/help-de.txt
++++ b/help-de.txt
+@@ -22,7 +22,6 @@ anleitung" im Aptitude-Hilfemenü.)
+    ]            Eine Gruppe von Paketen und alle Untergruppen einklappen.
+ 
+    Enter        Informationen über ein Paket anzeigen.
+-   C            Das Änderungsprotokoll (Changelog) eines Pakets anzeigen.
+    +            Ein Paket installieren oder aktualisieren bzw. nicht mehr
+                 zurückhalten.
+    -            Ein Paket entfernen.
+diff --git a/help-it.txt b/help-it.txt
+index eb6f790..0e19ba6 100644
+--- a/help-it.txt
++++ b/help-it.txt
+@@ -20,7 +20,6 @@ README.
+   "]":          Comprime un gruppo di pacchetti e tutti i suoi sottogruppi.
+ 
+   Invio:        Mostra le informazioni sul pacchetto selezionato.
+-  "C":          Visualizza il changelog di un pacchetto.
+   "+":          Installa o aggiorna un pacchetto; sblocca il pacchetto se
+                 era bloccato.
+   "-":          Rimuove un pacchetto.
+diff --git a/help-ru.txt b/help-ru.txt
+index c08c25a..dbaaded 100644
+--- a/help-ru.txt
++++ b/help-ru.txt
+@@ -19,7 +19,6 @@
+   "]":          Свернуть группу пакетов и все её подгруппы.
+ 
+   Enter:        Показать информацию о пакете.
+-  "C":          Показать файл changelog пакета.
+   "+":          Установить или обновить пакет, или удалить с него фиксацию.
+   "-":          Удалить пакет.
+   "=":          Фиксировать пакет на его текущей версии, т.е. запретить
+diff --git a/help.txt b/help.txt
+index 6e36510..a1d05f0 100644
+--- a/help.txt
++++ b/help.txt
+@@ -19,7 +19,6 @@ screens.  Other keys are available; consult the README for a list of these.
+   "]":          Collapse a group of packages and all its subgroups.
+ 
+   Enter:        View information about a package.
+-  "C":          View a package's changelog.
+   "+":          Install or upgrade a package, or remove its held state.
+   "-":          Remove a package.
+   "=":          Hold a package in its current version to prevent upgrades.
+diff --git a/po/POTFILES.in b/po/POTFILES.in
+index f0bc228..bf9a0c1 100644
+--- a/po/POTFILES.in
++++ b/po/POTFILES.in
+@@ -7,14 +7,8 @@ src/apt_options.cc
+ src/apt_options.h
+ src/apt_undo_tree.cc
+ src/apt_undo_tree.h
+-src/broken_indicator.cc
+-src/broken_indicator.h
+-src/changelog_parse.cc
+-src/changelog_parse.h
+ src/cmdline/cmdline_action.cc
+ src/cmdline/cmdline_action.h
+-src/cmdline/cmdline_changelog.cc
+-src/cmdline/cmdline_changelog.h
+ src/cmdline/cmdline_clean.cc
+ src/cmdline/cmdline_clean.h
+ src/cmdline/cmdline_common.h
+@@ -22,8 +16,6 @@ src/cmdline/cmdline_do_action.cc
+ src/cmdline/cmdline_do_action.h
+ src/cmdline/cmdline_download.cc
+ src/cmdline/cmdline_download.h
+-src/cmdline/cmdline_dump_resolver.cc
+-src/cmdline/cmdline_dump_resolver.h
+ src/cmdline/cmdline_forget_new.cc
+ src/cmdline/cmdline_forget_new.h
+ src/cmdline/cmdline_moo.cc
+@@ -32,8 +24,6 @@ src/cmdline/cmdline_progress.cc
+ src/cmdline/cmdline_progress.h
+ src/cmdline/cmdline_prompt.cc
+ src/cmdline/cmdline_prompt.h
+-src/cmdline/cmdline_resolver.cc
+-src/cmdline/cmdline_resolver.h
+ src/cmdline/cmdline_search.cc
+ src/cmdline/cmdline_search.h
+ src/cmdline/cmdline_show_broken.cc
+@@ -50,8 +40,6 @@ src/cmdline/cmdline_upgrade.cc
+ src/cmdline/cmdline_upgrade.h
+ src/cmdline/cmdline_util.cc
+ src/cmdline/cmdline_util.h
+-src/cmdline_parse.cc
+-src/cmdline_parse.h
+ src/defaults.cc
+ src/defaults.h
+ src/dep_item.cc
+@@ -68,8 +56,6 @@ src/download_screen.cc
+ src/download_screen.h
+ src/download_thread.cc
+ src/download_thread.h
+-src/edit_pkg_hier.cc
+-src/edit_pkg_hier.h
+ src/generic/apt/acqprogress.cc
+ src/generic/apt/acqprogress.h
+ src/generic/apt/aptcache.cc
+@@ -78,10 +64,6 @@ src/generic/apt/apt.cc
+ src/generic/apt/apt.h
+ src/generic/apt/aptitudepolicy.cc
+ src/generic/apt/aptitudepolicy.h
+-src/generic/apt/aptitude_resolver.cc
+-src/generic/apt/aptitude_resolver.h
+-src/generic/apt/aptitude_resolver_universe.cc
+-src/generic/apt/aptitude_resolver_universe.h
+ src/generic/apt/apt_undo_group.cc
+ src/generic/apt/apt_undo_group.h
+ src/generic/apt/config_signal.cc
+@@ -102,26 +84,7 @@ src/generic/apt/matchers.cc
+ src/generic/apt/matchers.h
+ src/generic/apt/pkg_acqfile.cc
+ src/generic/apt/pkg_acqfile.h
+-src/generic/apt/pkg_changelog.cc
+-src/generic/apt/pkg_changelog.h
+-src/generic/apt/pkg_hier.cc
+-src/generic/apt/pkg_hier_dump.cc
+-src/generic/apt/pkg_hier.h
+-src/generic/apt/resolver_manager.cc
+-src/generic/apt/resolver_manager.h
+ src/generic/apt/rev_dep_iterator.h
+-src/generic/apt/tags.cc
+-src/generic/apt/tags.h
+-src/generic/apt/tasks.cc
+-src/generic/apt/tasks.h
+-src/generic/problemresolver/dummy_universe.cc
+-src/generic/problemresolver/dummy_universe.h
+-src/generic/problemresolver/dump_universe.h
+-src/generic/problemresolver/exceptions.h
+-src/generic/problemresolver/problemresolver.h
+-src/generic/problemresolver/resolver_undo.h
+-src/generic/problemresolver/solution.h
+-src/generic/problemresolver/test.cc
+ src/generic/util/bool_accumulate.h
+ src/generic/util/dense_setset.h
+ src/generic/util/eassert.cc
+@@ -184,22 +147,12 @@ src/pkg_view.cc
+ src/pkg_view.h
+ src/reason_fragment.cc
+ src/reason_fragment.h
+-src/solution_dialog.cc
+-src/solution_dialog.h
+-src/solution_fragment.cc
+-src/solution_fragment.h
+-src/solution_item.cc
+-src/solution_item.h
+-src/solution_screen.cc
+-src/solution_screen.h
+ src/trust.cc
+ src/trust.h
+ src/ui.cc
+ src/ui_download_manager.cc
+ src/ui_download_manager.h
+ src/ui.h
+-src/view_changelog.cc
+-src/view_changelog.h
+ src/vscreen/columnify.cc
+ src/vscreen/columnify.h
+ src/vscreen/config/colors.cc
+diff --git a/po/aptitude.pot b/po/aptitude.pot
+index daa392f..bd15913 100644
+--- a/po/aptitude.pot
++++ b/po/aptitude.pot
+@@ -3224,7 +3224,7 @@ msgstr ""
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ 
+ #: src/pkg_grouppolicy.cc:330
+@@ -4197,7 +4197,7 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+@@ -4242,7 +4242,7 @@ msgstr ""
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+diff --git a/po/ar.po b/po/ar.po
+index b3ef9d9..3d80ae9 100644
+--- a/po/ar.po
++++ b/po/ar.po
+@@ -3480,10 +3480,10 @@ msgstr "رئيسي"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "ترقيات الأمن\n"
+-" تتوفر ترقيات أمنية لهذه الحزم من security.debian.org."
++" تتوفر ترقيات أمنية لهذه الحزم."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4536,10 +4536,9 @@ msgstr "نفذ الوقت أثناء محاولة حل المعتمدات (اضØ
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+-"تثبيت/إزالة الحزم بتطلب صلاحيات إداريّة، والتي لا تملكها حاليّاً.  هل تود "
+-"التغيّر إلى حساب root؟"
++"تثبيت/إزالة الحزم بتطلب صلاحيات إداريّة، والتي لا تملكها حاليّاً."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4585,10 +4584,9 @@ msgstr "تحديث القائمة"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+-"تحديث لوائح الحزم يتطلب صلاحيات إداريّة، والتي لا تملكها حاليّاً.  هل تود "
+-"التغيّر إلى حساب المستخدم root؟"
++"تحديث لوائح الحزم يتطلب صلاحيات إداريّة، والتي لا تملكها حاليّاً."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/bs.po b/po/bs.po
+index 8002d6b..bad5e73 100644
+--- a/po/bs.po
++++ b/po/bs.po
+@@ -3237,7 +3237,7 @@ msgstr ""
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ 
+ #: src/pkg_grouppolicy.cc:330
+@@ -4227,7 +4227,7 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+@@ -4272,7 +4272,7 @@ msgstr ""
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+diff --git a/po/ca.po b/po/ca.po
+index 93f8a94..702bd77 100644
+--- a/po/ca.po
++++ b/po/ca.po
+@@ -8,7 +8,7 @@ msgstr ""
+ "Project-Id-Version: aptitude_0.2.13-2\n"
+ "Report-Msgid-Bugs-To: aptitude at packages.debian.org\n"
+ "POT-Creation-Date: 2006-10-26 21:31-0700\n"
+-"PO-Revision-Date: 2006-04-20 08:19+0200\n"
++"PO-Revision-Date: 2006-12-13 23:35+0300\n"
+ "Last-Translator: Aleix Badia i Bosch <a.badia at callusdigital.org>\n"
+ "Language-Team: Catalan <debian-l10n-catalan at lists.debian.org>\n"
+ "MIME-Version: 1.0\n"
+@@ -3623,11 +3623,10 @@ msgstr "principal"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Actualitzacions de seguretat\n"
+-" Les actualitzacions de seguretat dels paquets estan disponibles a security."
+-"debian.org."
++" Les actualitzacions de seguretat dels paquets estan disponibles."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4741,11 +4740,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "El procés de suprimir/instal·lar paquets precisa de privilegis "
+-"d'administrador,els quals actualment no teniu. Voleu canviar al compte de "
+-"superusuari?"
++"d'administrador,els quals actualment no teniu."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4792,10 +4790,10 @@ msgstr "Actualitza la llista"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "El procés d'actualitzar paquets precisa de privilegis d'administrador,els "
+-"quals actualment no teniu. Voleu canviar al compte de superusuari?"
++"quals actualment no teniu."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/cs.po b/po/cs.po
+index 489b037..ee1615a 100644
+--- a/po/cs.po
++++ b/po/cs.po
+@@ -3504,11 +3504,10 @@ msgstr "hlavní"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Bezpečnostní aktualizace\n"
+-" Bezpečnostní aktualizace těchto balíků jsou k dispozici na security.debian."
+-"org."
++" Bezpečnostní aktualizace těchto balíků jsou k dispozici."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4588,10 +4587,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Instalace/odebrání balíků vyžaduje administrátorská práva, která momentálně "
+-"nemáte. Chcete se přepnout na účet root?"
++"nemáte."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4638,10 +4637,10 @@ msgstr "Aktualizace seznamu"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Aktualizace seznamu balíků vyžaduje administrátorská práva, která momentálně "
+-"nemáte. Chcete se přepnout na účet root?"
++"nemáte."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/da.po b/po/da.po
+index d89bfb0..d791274 100644
+--- a/po/da.po
++++ b/po/da.po
+@@ -3542,10 +3542,10 @@ msgstr "main"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Sikkerhedsopdateringer\n"
+-" Sikkerhedsopdateringer for disse pakker kan hentes fra security.debian.org."
++" Sikkerhedsopdateringer for disse pakker kan hentes."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4641,10 +4641,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Installering/afinstallering af pakker kræver administrative rettigheder som "
+-"du ikke har lige nu. Vil du ændre bruger til root?"
++"du ikke har lige nu."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4691,10 +4691,10 @@ msgstr "Opdatering af pakkeliste"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Opdatering af pakkelisterne kræver administrative rettigheder som du ikke "
+-"har lige nu. Vil du ændre bruger til root?"
++"har lige nu."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/de.po b/po/de.po
+index d45ddd6..0df195a 100644
+--- a/po/de.po
++++ b/po/de.po
+@@ -10,7 +10,7 @@ msgstr ""
+ "Project-Id-Version: aptitude 0.2.15.5\n"
+ "Report-Msgid-Bugs-To: aptitude at packages.debian.org\n"
+ "POT-Creation-Date: 2006-10-26 21:31-0700\n"
+-"PO-Revision-Date: 2006-10-05 23:21+0200\n"
++"PO-Revision-Date: 2006-12-13 23:35+0300\n"
+ "Last-Translator: Jens Seidel <jensseidel at users.sf.net>\n"
+ "Language-Team: Debian German <debian-l10n-german at lists.debian.org>\n"
+ "MIME-Version: 1.0\n"
+@@ -3625,10 +3625,10 @@ msgstr "main"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Sicherheitsupgrades\n"
+-" Sicherheitsupgrades für diese Paket sind auf security.debian.org abrufbar."
++" Sicherheitsupgrades für diese Paket sind abrufbar."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4750,10 +4750,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Zum Installieren/Entfernen von Paketen sind Administrationsrechte nötig, die "
+-"Sie derzeit nicht haben. Wollen Sie zum root-Account wechseln?"
++"Sie derzeit nicht haben."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4802,10 +4802,10 @@ msgstr "Listenaktualisierung"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Zum Aktualisieren der Paketlisten sind Administrationsrechte nötig, die Sie "
+-"derzeit nicht haben. Wollen Sie zum root-Account wechseln?"
++"derzeit nicht haben."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/el.po b/po/el.po
+index b46d5ad..c0b663f 100644
+--- a/po/el.po
++++ b/po/el.po
+@@ -20,7 +20,7 @@ msgstr ""
+ "Project-Id-Version: aptitude_po_el\n"
+ "Report-Msgid-Bugs-To: aptitude at packages.debian.org\n"
+ "POT-Creation-Date: 2006-10-26 21:31-0700\n"
+-"PO-Revision-Date: 2006-09-03 09:46-0700\n"
++"PO-Revision-Date: 2006-12-13 23:36+0300\n"
+ "Last-Translator: Konstantinos Margaritis <markos at debian.org>\n"
+ "Language-Team: Greek <debian-l10n-greek at lists.debian.org>\n"
+ "MIME-Version: 1.0\n"
+@@ -3645,11 +3645,10 @@ msgstr "κύριο"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Αναβαθμίσεις Ασφαλείας\n"
+-" Υπάρχουν διαθέσιμες αναβαθμίσεις ασφαλείας για αυτά τα πακέτα από το "
+-"security.debian.org."
++" Υπάρχουν διαθέσιμες αναβαθμίσεις ασφαλείας για αυτά τα πακέτα από."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4757,10 +4756,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Η εγκατάσταση/αφαίρεση πακέτων απαιτεί προνόμια διαχειριστή, που δεν έχετε "
+-"αυτή τη στιγμή. Θα θέλατε να περάσετε στο λογαριασμό χρήστη root;"
++"αυτή τη στιγμή."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4807,10 +4806,10 @@ msgstr "Αναβάθμιση λίστας"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Η ενημέρωση των καταλόγων των πακέτων απαιτεί προνόμια διαχειριστή, που δεν "
+-"έχετε αυτή τη στιγμή. Θα θέλατε να αλλάξετε στον λογαριασμό του χρήστη root;"
++"έχετε αυτή τη στιγμή."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/es.po b/po/es.po
+index aa531a2..4c85697 100644
+--- a/po/es.po
++++ b/po/es.po
+@@ -3635,11 +3635,10 @@ msgstr "principal"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Actualizaciones de seguridad\n"
+-" Hay disponibles actualizaciones de seguridad de estos paquetes disponibles "
+-"desde security.debian.org."
++" Hay disponibles actualizaciones de seguridad de estos paquetes disponibles."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4751,11 +4750,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "La instalación/eliminación de paquetes requiere privilegios de "
+-"administración, que actualmente no tiene. ¿Desearía cambiar a la cuenta de "
+-"administrador?"
++"administración, que actualmente no tiene."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4805,11 +4803,10 @@ msgstr "Actualizando listas"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "La actualización de la lista de paquetes disponibles requiere privilegios de "
+-"administración, que actualmente no tiene. ¿Desearía cambiar a la cuenta de "
+-"administrador?"
++"administración, que actualmente no tiene."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/eu.po b/po/eu.po
+index 3d70a77..20b59b0 100644
+--- a/po/eu.po
++++ b/po/eu.po
+@@ -3586,10 +3586,10 @@ msgstr "nagusia"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Segurtasun Eguneratzeak\n"
+-" Pakete hauen segurtasun-eguneratzeak security.debian.org gunean aurkituko "
++" Pakete hauen segurtasun-eguneratzeak aurkituko "
+ "dituzu."
+ 
+ #: src/pkg_grouppolicy.cc:330
+@@ -4689,10 +4689,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Paketeak instalatu/kendu ahal izateko, administratzaile-pribilegioak behar "
+-"dira, eta zuk ez daukazu horrelakorik. Root kontura aldatu nahi duzu?"
++"dira, eta zuk ez daukazu horrelakorik."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4740,10 +4740,10 @@ msgstr "Zerrendaren eguneraketa"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Pakete-zerrendak eguneratzeko, administratzaile-pribilegioak behar dira, eta "
+-"zuk ez daukazu horrelakorik. Root kontura aldatu nahi duzu?"
++"zuk ez daukazu horrelakorik."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/fi.po b/po/fi.po
+index 523d379..4d3f3da 100644
+--- a/po/fi.po
++++ b/po/fi.po
+@@ -3529,10 +3529,10 @@ msgstr "main"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Tietoturvapäivitykset\n"
+-" Palvelimella security.debian.org on tietoturvapäivityksiä näille paketeille."
++" Palvelimella tietoturvapäivityksiä näille paketeille."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4631,10 +4631,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Pakettien asentaminen ja poisto vaativat ylläpitäjän oikeudet, joita sinulla "
+-"ei ole.  Haluatko vaihtaa root-tunnukselle?"
++"ei ole."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4680,10 +4680,10 @@ msgstr "Luettelopäivitys"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Pakettiluettelon päivitys vaatii ylläpitäjän oikeudet, joita sinulla ei "
+-"ole.  Haluatko vaihtaa root-tunnukselle?"
++"ole."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/fr.po b/po/fr.po
+index a8f4690..a1aa276 100644
+--- a/po/fr.po
++++ b/po/fr.po
+@@ -3674,11 +3674,10 @@ msgstr "main"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Mise à jour de sécurité\n"
+-" Les mises à jour de sécurité pour ces paquets sont disponibles depuis "
+-"security.debian.org."
++" Les mises à jour de sécurité pour ces paquets sont disponibles."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4798,11 +4797,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "L'installation et la suppression de paquets demandent des droits "
+-"d'administration que vous n'avez pas pour le moment. Voulez-vous devenir "
+-"administrateur ?"
++"d'administration que vous n'avez pas pour le moment."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4851,10 +4849,10 @@ msgstr "Mise à jour de la liste"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "La mise à jour des listes de paquets exige des privilèges d'administration "
+-"que vous n'avez pas pour le moment. Voulez-vous devenir administrateur ?"
++"que vous n'avez pas pour le moment."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/gl.po b/po/gl.po
+index 4671a69..9cecc2c 100644
+--- a/po/gl.po
++++ b/po/gl.po
+@@ -3583,11 +3583,10 @@ msgstr "main"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Actualizacións de seguridade\n"
+-" As actualizacións de seguridade destes paquetes están dispoñibles en "
+-"security.debian.org"
++" As actualizacións de seguridade destes paquetes están dispoñibles"
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4693,10 +4692,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "A instalación/eliminación de paquetes precisa de privilexios "
+-"administrativos, que agora non ten. ¿Quere pasar á conta de administrador?"
++"administrativos, que agora non ten."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4744,10 +4743,10 @@ msgstr "Actualización das listas"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Actualizar as listas de paquetes precisa de privilexios administrativos, que "
+-"agora non ten. ¿Quere pasar á conta de administrador?"
++"agora non ten."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/hu.po b/po/hu.po
+index 1b5884d..d600003 100644
+--- a/po/hu.po
++++ b/po/hu.po
+@@ -7,7 +7,7 @@ msgstr ""
+ "Project-Id-Version: aptitude_po_hu\n"
+ "Report-Msgid-Bugs-To: aptitude at packages.debian.org\n"
+ "POT-Creation-Date: 2006-10-26 21:31-0700\n"
+-"PO-Revision-Date: 2006-10-12 20:44+0100\n"
++"PO-Revision-Date: 2006-12-13 23:56+0300\n"
+ "Last-Translator: SZERVÁC Attila <sas at 321.hu>\n"
+ "Language-Team: Hungarian <debian-l10n-hungarian at lists.debian.org>\n"
+ "MIME-Version: 1.0\n"
+@@ -3558,10 +3558,10 @@ msgstr "fő"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Biztonsági frissítések\n"
+-" E csomagok Biztonsági frissítéseinek elérhetősége: security.debian.org"
++" E csomagok Biztonsági frissítéseinek elérhetősége"
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4664,10 +4664,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "A csomagok telepítéséhez/törléséhez rendszergazdai jogosultságok kellenek, "
+-"amikkel jelenleg nem rendelkezel.  Szeretnél rendszergazdaként bejelentkezni?"
++"amikkel jelenleg nem rendelkezel."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4714,10 +4714,9 @@ msgstr "Lista frissítés"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+-"A csomaglista frissítés root jogot igényel, mellyel most nem rendelkezel. "
+-"Akarsz erre szert tenni?"
++"A csomaglista frissítés root jogot igényel, mellyel most nem rendelkezel."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/it.po b/po/it.po
+index 0b440b9..a7c01b9 100644
+--- a/po/it.po
++++ b/po/it.po
+@@ -3647,11 +3647,10 @@ msgstr "main"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Aggiornamenti di sicurezza\n"
+-" Aggiornamenti di sicurezza per questi pacchetti sono disponibili presso "
+-"security.debian.org."
++" Aggiornamenti di sicurezza per questi pacchetti sono disponibili."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4765,10 +4764,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Per installare e rimuovere pacchetti servono i privilegi di amministratore, "
+-"dei quali al momento si è privi. Passare all'account di root?"
++"dei quali al momento si è privi."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4816,10 +4815,10 @@ msgstr "Aggiornamento elenco"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Per aggiornare l'elenco dei pacchetti servono i privilegi di amministratore, "
+-"dei quali attualmente si è privi. Passare all'account di root?"
++"dei quali attualmente si è privi."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/ja.po b/po/ja.po
+index ccae3ab..77c8b4a 100644
+--- a/po/ja.po
++++ b/po/ja.po
+@@ -162,7 +162,7 @@ msgstr ""
+ "Project-Id-Version: aptitude 0.4.1\n"
+ "Report-Msgid-Bugs-To: aptitude at packages.debian.org\n"
+ "POT-Creation-Date: 2006-10-26 21:31-0700\n"
+-"PO-Revision-Date: 2006-09-26 21:48+0900\n"
++"PO-Revision-Date: 2006-12-13 23:38+0300\n"
+ "Last-Translator: Noritada Kobayashi <nori1 at dolphin.c.u-tokyo.ac.jp>\n"
+ "Language-Team: Japanese\n"
+ "MIME-Version: 1.0\n"
+@@ -3827,10 +3827,10 @@ msgstr "メイン"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "セキュリティアップデート\n"
+-" これらのパッケージのセキュリティアップデートが security.debian.org から入手"
++" これらのパッケージのセキュリティアップデートがから入手"
+ "可能です。"
+ 
+ #: src/pkg_grouppolicy.cc:330
+@@ -4945,10 +4945,9 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+-"パッケージのインストールや削除に必要な管理者権限が現在ありません。root になり"
+-"ますか?"
++"パッケージのインストールや削除に必要な管理者権限が現在ありません。"
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4998,9 +4997,9 @@ msgstr "一覧の更新"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+-"パッケージ一覧の更新に必要な管理者権限が現在ありません。root になりますか?"
++"パッケージ一覧の更新に必要な管理者権限が現在ありません。"
+ 
+ # * Description of an item.
+ #: src/ui.cc:1446 src/ui.cc:1967
+diff --git a/po/lt.po b/po/lt.po
+index f85a82f..83ec296 100644
+--- a/po/lt.po
++++ b/po/lt.po
+@@ -3554,11 +3554,10 @@ msgstr "pagrindiniai"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Saugumo pataisos\n"
+-" Šiuose paketuose rasta saugumo spragų, juos galima atnaujinti iš security."
+-"debian.org."
++" Šiuose paketuose rasta saugumo spragų, juos galima atnaujinti."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4643,10 +4642,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Norėdami įdiegti/pašalinti paketus turite turėti administratoriaus (root) "
+-"privilegijas, kurių jūs neturite.  Ar norite pereiti į „root“ paskyrą?"
++"privilegijas, kurių jūs neturite."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4693,10 +4692,10 @@ msgstr "Atnaujinimų sąrašas"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Norint atnaujinti paketų sąrašą reikalingos administratoriaus privilegijos, "
+-"kurių jūs šiuo metu neturite. Ar norite pereiti į root paskyrą?"
++"kurių jūs šiuo metu neturite."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/nb.po b/po/nb.po
+index 52e392d..c450e8c 100644
+--- a/po/nb.po
++++ b/po/nb.po
+@@ -3543,11 +3543,10 @@ msgstr "hoved"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Sikkerhetsoppdateringer\n"
+-"Sikkerhetsoppdateringer for disse pakkene er tilgjengelige fra security."
+-"debian.org."
++"Sikkerhetsoppdateringer for disse pakkene er tilgjengelige."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4647,10 +4646,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Ã… installere eller fjerne pakker krever at du er logget inn som root, noe du "
+-"ikke er. Vil du logge deg inn som root nå?"
++"ikke er."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4698,10 +4697,10 @@ msgstr "Listeoppdatering"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Ã… oppdatere pakkelistene krever at du er logget inn som root, noe du ikke "
+-"er. Vil du logge deg inn som root nå?"
++"er."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/nl.po b/po/nl.po
+index 6c50276..08c57a1 100644
+--- a/po/nl.po
++++ b/po/nl.po
+@@ -3597,11 +3597,10 @@ msgstr "hoofd"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Veiligheidsupdates\n"
+-" Veiligheidsupdates voor deze pakketten zijn beschikbaar van security.debian."
+-"org."
++" Veiligheidsupdates voor deze pakketten zijn beschikbaar."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4706,10 +4705,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Installeren/verwijderen van pakketten vereist administratieve privileges, "
+-"die u momenteel niet heeft. Wenst u te wijzigen naar de root-account?"
++"die u momenteel niet heeft."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4760,10 +4759,10 @@ msgstr "Lijst Bijwerken"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Bijwerken van pakketlijsten vereist administratieve privileges, die u "
+-"momenteel niet heeft. Wenst u te wijzigen naar de root-account?"
++"momenteel niet heeft."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/nn.po b/po/nn.po
+index c2bd10f..47ca335 100644
+--- a/po/nn.po
++++ b/po/nn.po
+@@ -3577,11 +3577,10 @@ msgstr "hovud"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Tryggingsoppdateringer\n"
+-"Tryggingsoppdateringer for desse pakkane er tilgjengeleg frå security.debian."
+-"org."
++"Tryggingsoppdateringer for desse pakkane er tilgjengeleg."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4672,10 +4671,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Ã… installera/fjerna pakkar krev at du har administrative rettar, noko du "
+-"ikkje har no. Vil du byte til root-kontoen?"
++"ikkje har no."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4722,10 +4721,9 @@ msgstr "Listeoppdatering"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+-"Oppdatering av pakkelister krev administrative rettar, noko du ikkje har no. "
+-"Vil du byte til root-kontoen?"
++"Oppdatering av pakkelister krev administrative rettar, noko du ikkje har no."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/pl.po b/po/pl.po
+index b263fa9..d2f3757 100644
+--- a/po/pl.po
++++ b/po/pl.po
+@@ -3547,10 +3547,10 @@ msgstr "main"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Poprawki bezpieczeñstwa\n"
+-" Na serwerze security.debian.org dostêpne s± poprawki bezpieczeñstwa tych "
++" Dostêpne s± poprawki bezpieczeñstwa tych "
+ "programów."
+ 
+ #: src/pkg_grouppolicy.cc:330
+@@ -4651,10 +4651,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Instalowanie/usuwanie pakietów wymaga uprawnieñ administratora, których nie "
+-"posiadasz. Czy chcesz siê prze³±czyæ na konto administratora?"
++"posiadasz."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4703,10 +4703,10 @@ msgstr "Uaktualnianie list"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Uaktualnianie listy pakietów wymaga uprawnieñ administratora, których nie "
+-"posiadasz. Czy chcesz siê prze³±czyæ na konto administratora?"
++"posiadasz."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/pt.po b/po/pt.po
+index 2d89654..db0eea8 100644
+--- a/po/pt.po
++++ b/po/pt.po
+@@ -7,7 +7,7 @@ msgstr ""
+ "Project-Id-Version: aptitude\n"
+ "Report-Msgid-Bugs-To: aptitude at packages.debian.org\n"
+ "POT-Creation-Date: 2006-10-26 21:31-0700\n"
+-"PO-Revision-Date: 2006-10-11 20:47+0000\n"
++"PO-Revision-Date: 2006-12-13 23:38+0300\n"
+ "Last-Translator: Miguel Figueiredo <elmig at debianPT.org>\n"
+ "Language-Team: Portuguese <traduz at debianpt.org>\n"
+ "MIME-Version: 1.0\n"
+@@ -3617,11 +3617,10 @@ msgstr "principal"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Actualizações de Segurança\n"
+-" Actualizações de segurança para esses pacotes estão disponíveis a partir de "
+-"security.debian.org."
++" Actualizações de segurança para esses pacotes estão disponíveis."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4725,10 +4724,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Instalar/remover pacotes requer privilégios administrativos, que você "
+-"actualmente não possui.  Deseja mudar para a conta de root?"
++"actualmente não possui."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4778,10 +4777,10 @@ msgstr "Lista de Actualizações"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Actualizar a lista de pacotes requer privilégios administrativos, que você "
+-"actualmente não possui. Deseja mudar para a conta de root ?"
++"actualmente não possui."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/pt_BR.po b/po/pt_BR.po
+index 62298b1..c2531e1 100644
+--- a/po/pt_BR.po
++++ b/po/pt_BR.po
+@@ -5,7 +5,7 @@ msgstr ""
+ "Project-Id-Version: aptitude\n"
+ "Report-Msgid-Bugs-To: aptitude at packages.debian.org\n"
+ "POT-Creation-Date: 2006-10-26 21:31-0700\n"
+-"PO-Revision-Date: 2006-09-07 16:00-0300\n"
++"PO-Revision-Date: 2006-12-13 23:38+0300\n"
+ "Last-Translator: André Luís Lopes <andrelop at debian.org>\n"
+ "Language-Team: l10n portuguese <debian-l10n-portuguese at lists.debian.org>\n"
+ "MIME-Version: 1.0\n"
+@@ -3605,11 +3605,10 @@ msgstr "principal"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Atualizações de Segurança\n"
+-" Atualizações de segurança para estes pacotes estão disponíveis em security."
+-"debian.org."
++" Atualizações de segurança para estes pacotes estão disponíveis."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4709,10 +4708,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Instalar/remover pacotes requer privilégios administrativos, os quais você "
+-"atualmente não possui. Você gostaria de mudar para a conta de root?"
++"atualmente não possui."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4760,10 +4759,10 @@ msgstr "Atualização da Lista"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Atualizar a lista de pacotes requer privilégios administrativos, os quais "
+-"você atualmente não possui. Você gostaria de mudar para a conta de root ?"
++"você atualmente não possui."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/ro.po b/po/ro.po
+index 2f123f7..9703222 100644
+--- a/po/ro.po
++++ b/po/ro.po
+@@ -3598,11 +3598,10 @@ msgstr "principal"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Actualizări de securitate\n"
+-" Actualizările de securitate pentru aceste pachete sunt disponibile din "
+-"security.debian.org"
++" Actualizările de securitate pentru aceste pachete sunt disponibile"
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4701,10 +4700,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Instalarea/ştergerea pachetelor necesită privilegii administrative, care "
+-"acum nu le aveţi.  Vreţi să schimb către contul de root?"
++"acum nu le aveţi."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4752,10 +4751,10 @@ msgstr "Actualizare Listă"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Actualizarea listelor de pachete necesită privilegii administrative, ceea ce "
+-"n-aveţi acum.  Vreţi să schimb către contul de root?"
++"n-aveţi acum."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/ru.po b/po/ru.po
+index db7077d..1f5272a 100644
+--- a/po/ru.po
++++ b/po/ru.po
+@@ -3568,11 +3568,10 @@ msgstr "main"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Обновления, связанные с безопасностью\n"
+-" Обновления, связанные с безопасностью данных пакетов доступны на security."
+-"debian.org."
++" Обновления, связанные с безопасностью данных пакетов доступны."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4655,10 +4654,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Для установки/удаления пакетов требуются административные права, которыми вы "
+-"в данный момент не обладаете. Получить права суперпользователя? "
++"в данный момент не обладаете."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4705,10 +4704,10 @@ msgstr "Обновление списка"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Для обновления списка пакетов требуются административные права, которыми вы "
+-"в данный момент не обладаете. Получить права суперпользователя? "
++"в данный момент не обладаете."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/sk.po b/po/sk.po
+index 00afc26..037d1c2 100644
+--- a/po/sk.po
++++ b/po/sk.po
+@@ -10,7 +10,7 @@ msgstr ""
+ "Project-Id-Version: aptitude\n"
+ "Report-Msgid-Bugs-To: aptitude at packages.debian.org\n"
+ "POT-Creation-Date: 2006-10-26 21:31-0700\n"
+-"PO-Revision-Date: 2006-10-22 18:32+0200\n"
++"PO-Revision-Date: 2006-12-13 23:39+0300\n"
+ "Last-Translator: Peter Mann <Peter.Mann at tuke.sk>\n"
+ "Language-Team: Slovak <sk-i18n at lists.linux.sk>\n"
+ "MIME-Version: 1.0\n"
+@@ -3532,11 +3532,10 @@ msgstr "hlavný"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Bezpečnostné aktualizácie\n"
+-" Bezpečnostné aktualizácie týchto balíkov sú k dispozícií na security.debian."
+-"org."
++" Bezpečnostné aktualizácie týchto balíkov sú k dispozícií."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4617,10 +4616,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Inštalácia/odobranie balíkov vyžaduje administrátorské práva, ktoré "
+-"momentálne nemáte. Chcete sa prepnúť na účet root?"
++"momentálne nemáte."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4668,10 +4667,10 @@ msgstr "Aktualizovať Zoznam"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Aktualizácia zoznamu balíkov vyžaduje administrátorské práva, ktoré "
+-"momentálne nemáte. Chcete sa prepnúť na účet root?"
++"momentálne nemáte."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/sv.po b/po/sv.po
+index 2f63e5c..f856b4f 100644
+--- a/po/sv.po
++++ b/po/sv.po
+@@ -8,7 +8,7 @@ msgstr ""
+ "Project-Id-Version: aptitude\n"
+ "Report-Msgid-Bugs-To: aptitude at packages.debian.org\n"
+ "POT-Creation-Date: 2006-10-26 21:31-0700\n"
+-"PO-Revision-Date: 2006-10-06 23:48-0700\n"
++"PO-Revision-Date: 2006-12-13 23:39+0300\n"
+ "Last-Translator: Daniel Nylander <po at danielnylander.se>\n"
+ "Language-Team: Swedish <tp-sv at listor.tp-sv.se>\n"
+ "MIME-Version: 1.0\n"
+@@ -3544,11 +3544,10 @@ msgstr "main"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Säkerhetsuppdateringar\n"
+-" Säkerhetsuppdateringar för dessa paket finns tillgängliga från security."
+-"debian.org."
++" Säkerhetsuppdateringar för dessa paket finns tillgängliga."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4649,10 +4648,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Installation/borttagning av paket kräver administrativa rättigheter som du "
+-"för närvarande inte har.  Vill du byta till root-kontot?"
++"för närvarande inte har."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4701,10 +4700,10 @@ msgstr "Listuppdatering"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Uppdatering av paketlistan kräver att du har administrativa rättigheter "
+-"vilket du inte har för tillfället. Vill du byta till root-kontot?"
++"vilket du inte har för tillfället."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/tl.po b/po/tl.po
+index 4f44ee2..9a5d069 100644
+--- a/po/tl.po
++++ b/po/tl.po
+@@ -3636,11 +3636,10 @@ msgstr "main"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Update sa seguridad\n"
+-" Update sa seguridad para sa paketeng ito ay available mula sa security."
+-"debian.org."
++" Update sa seguridad para sa paketeng ito ay available."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4767,11 +4766,11 @@ msgstr "Magsayang ng oras sa pag-hahanap ng mga mina"
+ #, fuzzy
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Installing/removing ng mga pakete ay kailangan ng administrative na "
+ "pribilhiyo, na\n"
+-"sa iyo kasalukuyan ay wala.  Gusto mo bang magbago sa root account?\n"
++"sa iyo kasalukuyan ay wala.\n"
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4822,11 +4821,11 @@ msgstr ""
+ #, fuzzy
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Updating ng mga pakete list ay kailangan ng administrative na pribilhiyo, "
+ "na\n"
+-"sa iyo kasalukuyan ay wala.  Gusto mo bang magbago sa root account?\n"
++"sa iyo kasalukuyan ay wala.\n"
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/tr.po b/po/tr.po
+index 187dd81..70ef2fe 100644
+--- a/po/tr.po
++++ b/po/tr.po
+@@ -3528,10 +3528,10 @@ msgstr "main"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Güvenlik Güncellemeleri\n"
+-"Bu paketler için güvenlik güncellemeleri security.debian.org adresindedir."
++"Bu paketler için güvenlik güncellemeleri."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4623,10 +4623,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Paket kurma/kaldırma işlemi şu anda sahip olmadığınız yönetici yetkilerini "
+-"gerektirir.  Root kullanıcı hesabına geçmek ister misiniz?"
++"gerektirir."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4673,11 +4673,10 @@ msgstr "Liste Güncelleme"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Paket listesi güncelleme işlemi şu anda sahip olmadığınız "
+-"yöneticiyetkilerini gerektirir.  Root kullanıcı hesabına geçmek ister "
+-"misiniz?"
++"yöneticiyetkilerini gerektirir."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/vi.po b/po/vi.po
+index 6f4dc9e..abbf3dc 100644
+--- a/po/vi.po
++++ b/po/vi.po
+@@ -8,7 +8,7 @@ msgstr ""
+ "Project-Id-Version: aptitude 0.4.x\n"
+ "Report-Msgid-Bugs-To: aptitude at packages.debian.org\n"
+ "POT-Creation-Date: 2006-10-26 21:31-0700\n"
+-"PO-Revision-Date: 2006-10-14 14:55+0930\n"
++"PO-Revision-Date: 2006-12-13 23:40+0300\n"
+ "Last-Translator: Clytie Siddall <clytie at riverland.net.au>\n"
+ "Language-Team: Vietnamese <vi-VN at googlegroups.com>\n"
+ "MIME-Version: 1.0\n"
+@@ -3570,11 +3570,10 @@ msgstr "chính"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "Bản cập nhật bảo mật\n"
+-" Bản cập nhật bảo mật cho những gói này sẵn sàng ở nơi Mạng « security."
+-"debian.org »."
++" Bản cập nhật bảo mật cho những gói này sẵn sàng ở nơi Mạng."
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4670,10 +4669,10 @@ msgstr ""
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Việc cài đặt/gỡ bỏ gói cần thiết quyền truy cập quản trị mà bạn hiện thời "
+-"không có. Bạn có muốn chuyển đổi sang tài khoản ngươi chủ (root) phải không?"
++"không có."
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4720,10 +4719,10 @@ msgstr "Cập nhật danh sách"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+ "Việc cập nhật danh sách gói cần thiết quyền truy cập quản trị, mà bạn hiện "
+-"thời không có. Bạn có muốn chuyển đổi sang tài khoản người chủ phải không?"
++"thời không có."
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/zh_CN.po b/po/zh_CN.po
+index e5d5391..774363a 100644
+--- a/po/zh_CN.po
++++ b/po/zh_CN.po
+@@ -3426,10 +3426,10 @@ msgstr "主要"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "安全更新\n"
+-" 这些软件包的安全更新可在 security.debian.org 得到。"
++" 这些软件包的安全更新可在得到。"
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4474,9 +4474,9 @@ msgstr "试图搜寻解决方案时用时已尽 (按“%s”加把劲儿再试è¯
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+-"安装/删除软件包需要管理员权限,而您现在没有这种权限。您想要进入 root 帐号吗?"
++"安装/删除软件包需要管理员权限,而您现在没有这种权限。"
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4522,9 +4522,9 @@ msgstr "列表更新"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+-"更新软件包列表需要管理员权限,而您现在没有这种权限。您想要进入 root 帐号吗?"
++"更新软件包列表需要管理员权限,而您现在没有这种权限。"
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/po/zh_TW.po b/po/zh_TW.po
+index e1bd36a..6b5b44e 100644
+--- a/po/zh_TW.po
++++ b/po/zh_TW.po
+@@ -8,7 +8,7 @@ msgstr ""
+ "Project-Id-Version: aptitude\n"
+ "Report-Msgid-Bugs-To: aptitude at packages.debian.org\n"
+ "POT-Creation-Date: 2006-10-26 21:31-0700\n"
+-"PO-Revision-Date: 2006-10-21 22:43+0800\n"
++"PO-Revision-Date: 2006-12-13 23:40+0300\n"
+ "Last-Translator: Asho Yeh <asho at debian.org.tw>\n"
+ "Language-Team: Chinese/Traditional <zh-l10n at linux.org.tw>\n"
+ "MIME-Version: 1.0\n"
+@@ -3425,10 +3425,10 @@ msgstr "主要"
+ #: src/pkg_grouppolicy.cc:329
+ msgid ""
+ "Security Updates\n"
+-" Security updates for these packages are available from security.debian.org."
++" Security updates for these packages are available."
+ msgstr ""
+ "資安更新\n"
+-" 資安更新代表 security.debian.org 所提供的更新套件。"
++" 資安更新代表所提供的更新套件。"
+ 
+ #: src/pkg_grouppolicy.cc:330
+ msgid ""
+@@ -4467,9 +4467,9 @@ msgstr "試圖搜尋解決方案時用時已盡 (按“%s”加把勁兒再試è©
+ #: src/ui.cc:1302
+ msgid ""
+ "Installing/removing packages requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+-"安裝/刪除套件需要管理員權限,而您現在沒有這種權限。您想要進入 root 帳號嗎?"
++"安裝/刪除套件需要管理員權限,而您現在沒有這種權限。"
+ 
+ #: src/ui.cc:1305 src/ui.cc:1434
+ msgid "Become root"
+@@ -4515,9 +4515,9 @@ msgstr "列表更新"
+ #: src/ui.cc:1431
+ msgid ""
+ "Updating the package lists requires administrative privileges, which you "
+-"currently do not have.  Would you like to change to the root account?"
++"currently do not have."
+ msgstr ""
+-"更新套件列表需要管理員權限,而您現在沒有這種權限。您想要進入 root 帳號嗎?"
++"更新套件列表需要管理員權限,而您現在沒有這種權限。"
+ 
+ #: src/ui.cc:1446 src/ui.cc:1967
+ msgid "Waste time trying to find mines"
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 9ccd2d8..703eba2 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -25,10 +25,6 @@ aptitude_SOURCES= 	\
+ 	apt_options.h	\
+ 	apt_undo_tree.cc \
+ 	apt_undo_tree.h \
+-	broken_indicator.cc\
+-	broken_indicator.h\
+-	changelog_parse.cc \
+-	changelog_parse.h  \
+ 	defaults.cc	\
+ 	defaults.h	\
+ 	dep_item.cc	\
+@@ -43,8 +39,6 @@ aptitude_SOURCES= 	\
+ 	download_screen.cc\
+ 	download_thread.h\
+ 	download_thread.cc\
+-	edit_pkg_hier.h	\
+-	edit_pkg_hier.cc\
+ 	load_config.cc	\
+ 	load_config.h	\
+ 	load_grouppolicy.cc\
+@@ -82,21 +76,11 @@ aptitude_SOURCES= 	\
+ 	pkg_view.h	\
+ 	reason_fragment.cc\
+ 	reason_fragment.h\
+-	solution_dialog.cc\
+-	solution_dialog.h\
+-	solution_fragment.cc\
+-	solution_fragment.h\
+-	solution_item.cc\
+-	solution_item.h\
+-	solution_screen.cc\
+-	solution_screen.h\
+ 	trust.h		\
+ 	trust.cc	\
+ 	ui.cc		\
+ 	ui.h		\
+ 	ui_download_manager.cc \
+ 	ui_download_manager.h  \
+-	view_changelog.cc \
+-	view_changelog.h \
+ 	vs_progress.cc  \
+ 	vs_progress.h
+diff --git a/src/apt_options.cc b/src/apt_options.cc
+index 10facad..fda5c09 100644
+--- a/src/apt_options.cc
++++ b/src/apt_options.cc
+@@ -156,9 +156,6 @@ option_item misc_options[]={
+ 	      PACKAGE "::Auto-Upgrade", false),
+   option_item(N_("Remove obsolete package files after downloading new package lists"),
+ 	      PACKAGE "::AutoClean-After-Update", false),
+-  option_item(N_("URL to use to download changelogs"),
+-	      PACKAGE "::Changelog-URL-Template",
+-	      "http://cgi.debian.org/cgi-bin/get-changelog?package=%s"),
+   option_item(N_("Display a preview of what will be done before doing it"),
+ 	      PACKAGE "::Display-Planned-Action",
+ 	      true),
+diff --git a/src/broken_indicator.cc b/src/broken_indicator.cc
+deleted file mode 100644
+index 9e3ee93..0000000
+--- a/src/broken_indicator.cc
++++ /dev/null
+@@ -1,391 +0,0 @@
+-// broken_indicator.cc
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#include "broken_indicator.h"
+-
+-#include <aptitude.h>
+-
+-#include <generic/apt/apt.h>
+-#include <generic/apt/aptcache.h>
+-#include <generic/apt/aptitude_resolver_universe.h>
+-#include <generic/apt/config_signal.h>
+-#include <generic/apt/resolver_manager.h>
+-
+-#include <generic/problemresolver/exceptions.h>
+-#include <generic/problemresolver/solution.h>
+-
+-#include <generic/util/util.h>
+-
+-#include <vscreen/config/colors.h>
+-#include <vscreen/config/keybindings.h>
+-#include <vscreen/fragment.h>
+-#include <vscreen/vs_text_layout.h>
+-#include <vscreen/vscreen.h>
+-
+-#include <apt-pkg/pkgsystem.h>
+-
+-#include <string>
+-#include <vector>
+-
+-using namespace std;
+-
+-typedef generic_solution<aptitude_universe> aptitude_solution;
+-
+-/** A simple indicator, usually placed at the bottom of the screen,
+- *  that describes the current state of the problem resolver.  Hidden
+- *  if no problem resolver is active.
+- *
+- *  \todo write a simple table fragment class and use that to
+- *  right-justify the text that obviously should be
+- */
+-class broken_indicator:public vs_text_layout
+-{
+-  aptitude_solution last_sol;
+-
+-  /** Records whether we had generated all solutions at the time of
+-   *  the last update.
+-   */
+-  bool last_complete : 1;
+-
+-  /** Records whether the background thread was active at the time of
+-   *  the last update.
+-   */
+-  bool last_background_active : 1;
+-
+-  /** Tracks the phase of the visual "spinner". */
+-  int spin_count;
+-
+-  void handle_cache_reload()
+-  {
+-    if(resman != NULL)
+-      resman->state_changed.connect(sigc::mem_fun(*this, &broken_indicator::post_update));
+-
+-    update();
+-  }
+-
+-protected:
+-  broken_indicator()
+-    :spin_count(0)
+-  {
+-    if(resman != NULL)
+-      resman->state_changed.connect(sigc::mem_fun(*this, &broken_indicator::post_update));
+-
+-    cache_closed.connect(sigc::mem_fun(*this, &broken_indicator::update));
+-    cache_reloaded.connect(sigc::mem_fun(*this, &broken_indicator::handle_cache_reload));
+-
+-    set_bg_style(get_style("Error"));
+-
+-    update();
+-
+-    vscreen_addtimeout(new slot_event(sigc::mem_fun(this, &broken_indicator::tick_timeout)),
+-		       aptcfg->FindI(PACKAGE "::Spin-Interval", 500));
+-  }
+-
+-private:
+-  static fragment *key_hint_fragment(const resolver_manager::state &state)
+-  {
+-    wstring next=global_bindings.readable_keyname("NextSolution");
+-    wstring prev=global_bindings.readable_keyname("PrevSolution");
+-    wstring examine=global_bindings.readable_keyname("ExamineSolution");
+-    wstring apply=global_bindings.readable_keyname("ApplySolution");
+-
+-
+-
+-    style st_normal;
+-    style st_disabled;
+-    st_disabled.attrs_off(A_BOLD);
+-    st_disabled.attrs_on(A_DIM);
+-    st_disabled.set_fg(COLOR_BLACK);
+-
+-    vector<fragment *> key_hints;
+-
+-    key_hints.push_back(fragf(_("%s: Examine"),
+-			      examine.c_str()));
+-
+-
+-    bool can_apply = (state.selected_solution < state.generated_solutions);
+-    bool can_next = (state.selected_solution < state.generated_solutions &&
+-		     !(state.selected_solution + 1 == state.generated_solutions && state.solutions_exhausted));
+-
+-    key_hints.push_back(style_fragment(fragf(_("%s: Apply"),
+-					     apply.c_str()),
+-				       can_apply ? st_normal : st_disabled));
+-    key_hints.push_back(style_fragment(fragf(_("%s: Next"),
+-					     next.c_str()),
+-				       can_next ? st_normal : st_disabled));
+-
+-    bool can_prev = (state.selected_solution > 0);
+-    key_hints.push_back(style_fragment(fragf(_("%s: Previous"),
+-					     prev.c_str()),
+-				       can_prev ? st_normal : st_disabled));
+-
+-    return join_fragments(key_hints, L"  ");
+-  }
+-
+-  void tick_timeout()
+-  {
+-    vs_widget_ref tmpref(this);
+-
+-    if(resman != NULL && resman->background_thread_active())
+-      {
+- 	++spin_count;
+-	update();
+-	vscreen_update();
+-      }
+-
+-    vscreen_addtimeout(new slot_event(sigc::mem_fun(this, &broken_indicator::tick_timeout)),
+-		       aptcfg->FindI(PACKAGE "::Spin-Interval", 500));
+-  }
+-
+-  std::string spin_string(const resolver_manager::state &state) const
+-  {
+-    if(!state.background_thread_active)
+-      return " ";
+-
+-    switch(spin_count % 4)
+-      {
+-      case 0:
+-	return ".";
+-      case 1:
+-	return "o";
+-      case 2:
+-	return "O";
+-      case 3:
+-	return "o";
+-      default:
+-	return "?";
+-      }
+-  }
+-
+-  struct update_event : public vscreen_event
+-  {
+-    broken_indicator *b;
+-  public:
+-    update_event(broken_indicator *_b)
+-      : b(_b)
+-    {
+-    }
+-
+-    void dispatch()
+-    {
+-      b->update();
+-    }
+-  };
+-
+-  /** Post an update to run in the main thread; needed since the
+-   *  selected_signal_changed signal might theoretically run from a
+-   *  background thread.  (at the moment it shouldn't, but this will
+-   *  help avoid nasty surprises)
+-   */
+-  void post_update()
+-  {
+-    vscreen_post_event(new update_event(this));
+-  }
+-public:
+-  static ref_ptr<broken_indicator> create()
+-  {
+-    ref_ptr<broken_indicator> rval(new broken_indicator);
+-    rval->decref();
+-    return rval;
+-  }
+-
+-  // TODO: split this monster up.
+-  void update()
+-  {
+-    vs_widget_ref tmpref(this);
+-
+-    if(resman == NULL || !resman->resolver_exists())
+-      {
+-	set_fragment(fragf(""));
+-	last_sol.nullify();
+-	hide();
+-	return;
+-      }
+-
+-    // Take a snapshot of the state.
+-    resolver_manager::state state = resman->state_snapshot();
+-
+-    if(state.solutions_exhausted && state.generated_solutions == 0)
+-      {
+-	set_fragment(fragf(_("Unable to resolve dependencies.")));
+-	last_sol.nullify();
+-	show();
+-	return;
+-      }
+-
+-    // Handle the case where the resolver is churning away.
+-    if(state.selected_solution >= state.generated_solutions)
+-      {
+-	// TODO: add a column-generating fragment that can
+-	//       left/right justify stuff.
+-
+-	vector<fragment_column_entry> columns;
+-
+-	columns.push_back(fragment_column_entry(true, 1, fragment_column_entry::top, flowbox(text_fragment(ssprintf(_("[%d(%d)/...] Resolving dependencies"),
+-														    state.selected_solution + 1,
+-														    state.generated_solutions)))));
+-
+-	columns.push_back(fragment_column_entry(false, 1, fragment_column_entry::top, NULL));
+-
+-	columns.push_back(fragment_column_entry(false, 1, fragment_column_entry::top, text_fragment(spin_string(state))));
+-
+-	set_fragment(sequence_fragment(fragment_columns(columns),
+-				       key_hint_fragment(state),
+-				       NULL));
+-	last_sol.nullify();
+-	show();
+-	return;
+-      }
+-
+-    aptitude_solution sol = resman->get_solution(state.selected_solution, 0);
+-
+-    // This test always fails the first time update() is called, since
+-    // sol is never NULL and last_sol is initialized to NULL.
+-    if(sol == last_sol && state.solutions_exhausted == last_complete &&
+-       // If there's an active thread we need to redraw the widget to
+-       // include the spinner.
+-       !last_background_active &&
+-       state.background_thread_active == last_background_active)
+-      return;
+-
+-    last_sol = sol;
+-    last_complete = state.solutions_exhausted;
+-    last_background_active = state.background_thread_active;
+-
+-    if(sol.get_actions().empty())
+-      {
+-	set_fragment(fragf("%s", _("Internal error: unexpected null solution.")));
+-	show();
+-	return;
+-      }
+-
+-    int install_count=0, remove_count=0, keep_count=0, upgrade_count=0, downgrade_count=0;
+-
+-    for(imm::map<aptitude_universe::package, aptitude_solution::action>::const_iterator
+-	  i = sol.get_actions().begin();
+-	i != sol.get_actions().end(); ++i)
+-      {
+-	pkgCache::PkgIterator pkg=i->first.get_pkg();
+-	pkgCache::VerIterator curver=pkg.CurrentVer();
+-	pkgCache::VerIterator instver=(*apt_cache_file)[pkg].InstVerIter(*apt_cache_file);
+-	pkgCache::VerIterator newver=i->second.ver.get_ver();
+-
+-	// If not, we have a problem.
+-	eassert(instver!=newver);
+-
+-	if(newver == curver)
+-	  ++keep_count;
+-	else if(curver.end())
+-	  ++install_count;
+-	else if(newver.end())
+-	  ++remove_count;
+-	else
+-	  {
+-	    int cmp=_system->VS->CmpVersion(curver.VerStr(),
+-					    newver.VerStr());
+-
+-	    // The versions shouldn't be equal -- otherwise
+-	    // something is majorly wrong.
+-	    // eassert(cmp!=0);
+-	    //
+-	    // The above is not true: consider, eg, the case of a
+-	    // locally compiled package and a standard package.
+-
+-	    /** \todo indicate "sidegrades" separately? */
+-	    if(cmp<=0)
+-	      ++upgrade_count;
+-	    else if(cmp>0)
+-	      ++downgrade_count;
+-	  }
+-      }
+-
+-    vector<fragment *> fragments;
+-
+-    string countstr
+-      = ssprintf(state.solutions_exhausted?"[%d/%d]":"[%d(%d)/...]",
+-		 state.selected_solution + 1,
+-		 state.generated_solutions);
+-    fragments.push_back(fragf("%s ", countstr.c_str()));
+-
+-
+-    vector<fragment *> suggestions;
+-
+-    if(install_count>0)
+-      suggestions.push_back(text_fragment(ssprintf(ngettext("%d install",
+-							    "%d installs",
+-							    install_count),
+-						   install_count)));
+-
+-    if(remove_count>0)
+-      suggestions.push_back(text_fragment(ssprintf(ngettext("%d removal",
+-							    "%d removals",
+-							    remove_count),
+-						   remove_count)));
+-
+-    if(keep_count>0)
+-      suggestions.push_back(text_fragment(ssprintf(ngettext("%d keep",
+-							    "%d keeps",
+-							    keep_count),
+-						   keep_count)));
+-
+-    if(upgrade_count>0)
+-      suggestions.push_back(text_fragment(ssprintf(ngettext("%d upgrade",
+-							    "%d upgrades",
+-							    upgrade_count),
+-						   upgrade_count)));
+-
+-    if(downgrade_count>0)
+-      suggestions.push_back(text_fragment(ssprintf(ngettext("%d downgrade",
+-							    "%d downgrades",
+-							    downgrade_count),
+-						   downgrade_count)));
+-
+-    /* ForTranslators: %F is replaced with a comma separated list such as
+-       "n1 installs, n2 removals", ...
+-     */
+-    fragments.push_back(fragf(_("Suggest %F"), join_fragments(suggestions, L", ")));
+-
+-    if(state.background_thread_active)
+-      {
+-	vector<fragment_column_entry> columns;
+-	columns.push_back(fragment_column_entry(true, 1, fragment_column_entry::top, hardwrapbox(sequence_fragment(fragments))));
+-
+-	columns.push_back(fragment_column_entry(false, 1, fragment_column_entry::top, NULL));
+-
+-	columns.push_back(fragment_column_entry(false, 1, fragment_column_entry::top, text_fragment(spin_string(state))));
+-
+-
+-	fragments.clear();
+-	fragments.push_back(fragment_columns(columns));
+-      }
+-    else
+-      fragments.push_back(newline_fragment());
+-    fragments.push_back(hardwrapbox(key_hint_fragment(state)));
+-
+-    fragment *f=sequence_fragment(fragments);
+-    set_fragment(f);
+-
+-    show();
+-  }
+-};
+-
+-ref_ptr<vscreen_widget> make_broken_indicator()
+-{
+-  return broken_indicator::create();
+-}
+diff --git a/src/broken_indicator.h b/src/broken_indicator.h
+deleted file mode 100644
+index 80ee3aa..0000000
+--- a/src/broken_indicator.h
++++ /dev/null
+@@ -1,32 +0,0 @@
+-// broken_indicator.h                        -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-//
+-// Generates a (hopefully) unobtrusive hint about how to use the
+-// problem resolver.
+-
+-#ifndef BROKEN_INDICATOR_H
+-#define BROKEN_INDICATOR_H
+-
+-class vscreen_widget;
+-template<class T> class ref_ptr;
+-
+-/** \return a newly generated "broken indicator". */
+-ref_ptr<vscreen_widget> make_broken_indicator();
+-
+-#endif // BROKEN_INDICATOR_H
+diff --git a/src/changelog_parse.cc b/src/changelog_parse.cc
+deleted file mode 100644
+index 463b02f..0000000
+--- a/src/changelog_parse.cc
++++ /dev/null
+@@ -1,164 +0,0 @@
+-// changelog_parse.cc
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-//
+-// At the moment this code uses parsechangelog to convert changelogs
+-// into something easier to read.
+-
+-#include "changelog_parse.h"
+-
+-#include "desc_parse.h"
+-
+-#include <apt-pkg/fileutl.h>
+-#include <apt-pkg/pkgsystem.h>
+-#include <apt-pkg/tagfile.h>
+-#include <apt-pkg/version.h>
+-
+-#include <generic/util/temp.h>
+-#include <generic/util/util.h>
+-
+-#include <vscreen/fragment.h>
+-#include <vscreen/transcode.h>
+-
+-static
+-fragment *change_text_fragment(const std::string &s)
+-{
+-  std::vector<fragment *> lines;
+-
+-  std::string::size_type start = 0;
+-  std::string::size_type next_nl;
+-
+-  do
+-    {
+-      next_nl = s.find('\n', start);
+-
+-      if(s[start] == ' ')
+-	++start;
+-
+-      if(next_nl == start + 1 && s[start] == '.')
+-	{
+-	  lines.push_back(newline_fragment());
+-	  start = next_nl + 1;
+-	  continue;
+-	}
+-
+-      std::string this_line;
+-      if(next_nl != std::string::npos)
+-	this_line.assign(s, start, next_nl - start);
+-      else
+-	this_line.assign(s, start, std::string::npos);
+-
+-      size_t first_nonspace = 0;
+-      while(first_nonspace < this_line.size() && isspace(this_line[first_nonspace]))
+-	++first_nonspace;
+-
+-      bool has_bullet = false;
+-      if(first_nonspace < this_line.size())
+-	switch(this_line[first_nonspace])
+-	  {
+-	  case '*':
+-	  case '+':
+-	  case '-':
+-	    has_bullet = true;
+-	    break;
+-	  }
+-
+-      if(has_bullet)
+-	lines.push_back(hardwrapbox(fragf("%s%F%s%n",
+-					  std::string(this_line, 0, first_nonspace).c_str(),
+-					  text_fragment(std::string(this_line, first_nonspace, 1).c_str(),
+-							get_style("Bullet")),
+-					  std::string(this_line, first_nonspace + 1).c_str())));
+-      else
+-	lines.push_back(hardwrapbox(fragf("%s%n", this_line.c_str())));
+-
+-      start = next_nl + 1;
+-    } while(next_nl != std::string::npos);
+-
+-  return sequence_fragment(lines);
+-}
+-
+-static
+-fragment *parse_predigested_changelog(const temp::name &digest,
+-				      const std::string &curver)
+-{
+-  FileFd digestfd(digest.get_name(), FileFd::ReadOnly);
+-
+-  if(!digestfd.IsOpen())
+-    return NULL;
+-  else
+-    {
+-      pkgTagFile tagfile(&digestfd);
+-
+-      pkgTagSection sec;
+-
+-      std::vector<fragment *> fragments;
+-
+-      bool first = true;
+-
+-      while(tagfile.Step(sec))
+-	{
+-	  std::string version(sec.FindS("Version"));
+-	  std::string changes(sec.FindS("Changes"));
+-	  std::string maintainer(sec.FindS("Maintainer"));
+-	  std::string date(sec.FindS("Date"));
+-
+-	  fragment *f = fragf(first ? "%F%F" : "%n%F%F",
+-			      change_text_fragment(changes),
+-			      hardwrapbox(fragf("%n -- %s  %s",
+-						maintainer.c_str(),
+-						date.c_str())));
+-
+-	  first = false;
+-
+-	  if(!curver.empty() && _system->VS->CmpVersion(version, curver) > 0)
+-	    {
+-	      style s = get_style("ChangelogNewerVersion");
+-	      fragments.push_back(style_fragment(f, s));
+-	    }
+-	  else
+-	    fragments.push_back(f);
+-	}
+-
+-      return sequence_fragment(fragments);
+-    }
+-}
+-
+-static
+-temp::name digest_changelog(const temp::name &changelog)
+-{
+-  temp::name rval(changelog.get_parent(), "parsedchangelog");
+-
+-  if(system(ssprintf("parsechangelog --all --format rfc822 -l %s > %s 2> /dev/null",
+-		     changelog.get_name().c_str(),
+-		     rval.get_name().c_str()).c_str()) == 0)
+-    return rval;
+-  else
+-    return temp::name();
+-}
+-
+-fragment *make_changelog_fragment(const temp::name &file,
+-				  const std::string &curver)
+-{
+-  temp::name digested = digest_changelog(file);
+-
+-  if(!digested.valid())
+-    return NULL;
+-  else
+-    return parse_predigested_changelog(digested, curver);
+-}
+diff --git a/src/changelog_parse.h b/src/changelog_parse.h
+deleted file mode 100644
+index be60f83..0000000
+--- a/src/changelog_parse.h
++++ /dev/null
+@@ -1,39 +0,0 @@
+-// changelog_parse.h                        -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#ifndef CHANGELOG_PARSE_H
+-#define CHANGELOG_PARSE_H
+-
+-#include <apt-pkg/pkgcache.h>
+-
+-class fragment;
+-namespace temp {class name;}
+-
+-/** Parse the contents of the given file as a Debian changelog.  If
+- *  for some reason the file cannot be parsed, returns \b NULL.
+- *
+- *  \param file a temporary file object containing the changelog.
+- *  \param verstr the name of the currently installed version of
+- *                this package (empty if there is no installed
+- *                version)
+- */
+-fragment *make_changelog_fragment(const temp::name &file,
+-				  const std::string &curver);
+-
+-#endif
+diff --git a/src/cmdline/Makefile.am b/src/cmdline/Makefile.am
+index 7cde4bd..c0c4ee9 100644
+--- a/src/cmdline/Makefile.am
++++ b/src/cmdline/Makefile.am
+@@ -5,8 +5,6 @@ noinst_LIBRARIES=libcmdline.a
+ libcmdline_a_SOURCES=\
+ 	cmdline_action.cc \
+ 	cmdline_action.h \
+-	cmdline_changelog.cc \
+-	cmdline_changelog.h \
+ 	cmdline_clean.cc \
+ 	cmdline_clean.h \
+ 	cmdline_common.h \
+@@ -14,8 +12,6 @@ libcmdline_a_SOURCES=\
+ 	cmdline_do_action.h \
+ 	cmdline_download.cc \
+ 	cmdline_download.h \
+-	cmdline_dump_resolver.cc \
+-	cmdline_dump_resolver.h \
+ 	cmdline_forget_new.cc \
+ 	cmdline_forget_new.h \
+ 	cmdline_moo.cc \
+@@ -24,8 +20,6 @@ libcmdline_a_SOURCES=\
+ 	cmdline_progress.h \
+ 	cmdline_prompt.cc \
+ 	cmdline_prompt.h \
+-	cmdline_resolver.cc \
+-	cmdline_resolver.h \
+ 	cmdline_search.cc \
+ 	cmdline_search.h \
+ 	cmdline_show.cc \
+diff --git a/src/cmdline/cmdline_action.cc b/src/cmdline/cmdline_action.cc
+index bfc2c5b..b03087f 100644
+--- a/src/cmdline/cmdline_action.cc
++++ b/src/cmdline/cmdline_action.cc
+@@ -10,7 +10,6 @@
+ #include <generic/apt/apt.h>
+ #include <generic/apt/config_signal.h>
+ #include <generic/apt/matchers.h>
+-#include <generic/apt/tasks.h>
+ 
+ #include <apt-pkg/algorithms.h>
+ #include <apt-pkg/error.h>
+@@ -19,7 +18,7 @@
+ bool cmdline_applyaction(cmdline_pkgaction_type action,
+ 			 pkgCache::PkgIterator pkg,
+ 			 pkgset &to_install, pkgset &to_hold,
+-			 pkgset &to_remove, pkgset &to_purge,
++			 pkgset &to_remove,
+ 			 int verbose,
+ 			 cmdline_version_source source,
+ 			 const string &sourcestr,
+@@ -107,19 +106,12 @@ bool cmdline_applyaction(cmdline_pkgaction_type action,
+       else if((*apt_cache_file)[pkg].Keep() && verbose>0)
+ 	printf(_("Package %s is not installed, so it will not be removed\n"), pkg.Name());
+       break;
+-    case cmdline_purge:
+-      if(!pkg.CurrentVer().end() || pkg->CurrentState!=pkgCache::State::ConfigFiles)
+-	to_purge.insert(pkg);
+-      else if((*apt_cache_file)[pkg].Keep() && verbose>0)
+-	printf(_("Package %s is not installed, so it will not be removed\n"), pkg.Name());
+-      break;
+     case cmdline_hold:
+       to_hold.insert(pkg);
+       break;
+     case cmdline_keep:
+       to_install.erase(pkg);
+       to_remove.erase(pkg);
+-      to_purge.erase(pkg);
+       to_hold.erase(pkg);
+       break;
+     case cmdline_unhold:
+@@ -154,9 +146,6 @@ bool cmdline_applyaction(cmdline_pkgaction_type action,
+     case cmdline_remove:
+       (*apt_cache_file)->mark_delete(pkg, false, false, NULL);
+       break;
+-    case cmdline_purge:
+-      (*apt_cache_file)->mark_delete(pkg, true, false, NULL);
+-      break;
+     case cmdline_hold:
+       (*apt_cache_file)->mark_keep(pkg, false, true, NULL);
+       break;
+@@ -194,7 +183,7 @@ bool cmdline_applyaction(cmdline_pkgaction_type action,
+ bool cmdline_applyaction(string s,
+ 			 cmdline_pkgaction_type action,
+ 			 pkgset &to_install, pkgset &to_hold,
+-			 pkgset &to_remove, pkgset &to_purge,
++			 pkgset &to_remove,
+ 			 int verbose,
+ 			 bool allow_auto)
+ {
+@@ -204,32 +193,6 @@ bool cmdline_applyaction(string s,
+ 
+   string sourcestr, package;
+ 
+-  // Handle task installation.  Won't work if tasksel isn't installed.
+-  if(task_list->find(s)!=task_list->end())
+-    {
+-      task t=(*task_list)[s];
+-
+-      printf(_("Note: selecting the task \"%s: %s\" for installation\n"),
+-	     s.c_str(), t.shortdesc.c_str());
+-
+-      for(pkgCache::PkgIterator pkg=(*apt_cache_file)->PkgBegin();
+-	  !pkg.end(); ++pkg)
+-	{
+-	  std::list<std::string> *tasks=get_tasks(pkg);
+-
+-	  for(std::list<std::string>::iterator i=tasks->begin();
+-	      i!=tasks->end(); ++i)
+-	    if(*i==s)
+-	      rval=cmdline_applyaction(action, pkg,
+-				       to_install, to_hold, to_remove, to_purge,
+-				       verbose, source,
+-				       sourcestr, allow_auto) && rval;
+-	}
+-
+-      // break out.
+-      return rval;
+-    }
+-
+   if(!cmdline_parse_source(s, source, package, sourcestr))
+     return false;
+ 
+@@ -322,7 +285,7 @@ bool cmdline_applyaction(string s,
+ 	}
+ 
+       rval=cmdline_applyaction(action, pkg,
+-			       to_install, to_hold, to_remove, to_purge,
++			       to_install, to_hold, to_remove,
+ 			       verbose, source,
+ 			       sourcestr, allow_auto);
+     }
+@@ -342,7 +305,7 @@ bool cmdline_applyaction(string s,
+ 
+ 	  if(m->matches(pkg))
+ 	    rval=cmdline_applyaction(action, pkg,
+-				     to_install, to_hold, to_remove, to_purge,
++				     to_install, to_hold, to_remove,
+ 				     verbose, source,
+ 				     sourcestr, allow_auto) && rval;
+ 	}
+@@ -364,10 +327,6 @@ static bool parse_action_str(const string &s,
+     {
+       switch(s[loc])
+ 	{
+-	case '_':
+-	  action=cmdline_purge;
+-	  ++loc;
+-	  break;
+ 	case '-':
+ 	  action=cmdline_remove;
+ 	  ++loc;
+@@ -417,7 +376,7 @@ static bool parse_action_str(const string &s,
+ 
+ void cmdline_parse_action(string s,
+ 			  pkgset &to_install, pkgset &to_hold,
+-			  pkgset &to_remove, pkgset &to_purge,
++			  pkgset &to_remove,
+ 			  int verbose,
+ 			  bool allow_auto)
+ {
+@@ -452,7 +411,7 @@ void cmdline_parse_action(string s,
+ 
+ 	      if(!cmdline_applyaction(pkgname, action,
+ 				      to_install, to_hold,
+-				      to_remove, to_purge,
++				      to_remove,
+ 				      verbose, allow_auto))
+ 		return;
+ 	    }
+diff --git a/src/cmdline/cmdline_action.h b/src/cmdline/cmdline_action.h
+index 88b99c3..189151a 100644
+--- a/src/cmdline/cmdline_action.h
++++ b/src/cmdline/cmdline_action.h
+@@ -51,7 +51,7 @@
+ bool cmdline_applyaction(cmdline_pkgaction_type action,
+ 			 pkgCache::PkgIterator pkg,
+ 			 pkgset &to_install, pkgset &to_hold,
+-			 pkgset &to_remove, pkgset &to_purge,
++			 pkgset &to_remove,
+ 			 int verbose,
+ 			 cmdline_version_source source,
+ 			 const string &sourcestr,
+@@ -89,7 +89,7 @@ bool cmdline_applyaction(cmdline_pkgaction_type action,
+ bool cmdline_applyaction(string s,
+ 			 cmdline_pkgaction_type action,
+ 			 pkgset &to_install, pkgset &to_hold,
+-			 pkgset &to_remove, pkgset &to_purge,
++			 pkgset &to_remove,
+ 			 int verbose, bool allow_auto);
+ 
+ /** \brief Parses a list of actions and executes them.
+@@ -123,7 +123,7 @@ bool cmdline_applyaction(string s,
+  */
+ void cmdline_parse_action(string s,
+ 			  pkgset &to_install, pkgset &to_hold,
+-			  pkgset &to_remove, pkgset &to_purge,
++			  pkgset &to_remove,
+ 			  int verbose, bool allow_auto);
+ 
+ #endif // CMDLINE_ACTION_H
+diff --git a/src/cmdline/cmdline_changelog.cc b/src/cmdline/cmdline_changelog.cc
+deleted file mode 100644
+index fa5df4f..0000000
+--- a/src/cmdline/cmdline_changelog.cc
++++ /dev/null
+@@ -1,373 +0,0 @@
+-// cmdline_changelog.cc
+-//
+-//  Copyright 2004 Daniel Burrows
+-
+-#include "cmdline_changelog.h"
+-
+-#include "cmdline_common.h"
+-#include "cmdline_progress.h"
+-#include "cmdline_util.h"
+-
+-#include <aptitude.h>
+-
+-#include <generic/apt/apt.h>
+-#include <generic/apt/config_signal.h>
+-#include <generic/apt/pkg_changelog.h>
+-
+-#include <apt-pkg/error.h>
+-#include <apt-pkg/metaindex.h>
+-#include <apt-pkg/progress.h>
+-#include <apt-pkg/sourcelist.h>
+-#include <apt-pkg/srcrecords.h>
+-
+-#include <sigc++/adaptors/bind.h>
+-
+-using namespace std;
+-
+-/** Represents the information needed to retrieve a changelog. */
+-struct changelog_entity
+-{
+-  /** The name of the source package. */
+-  std::string pkg;
+-
+-  /** The name of the source version. */
+-  std::string ver;
+-
+-  /** The section of the package. */
+-  std::string section;
+-
+-  /** Initializes the empty entity: all the members are 0-length
+-   *  strings.
+-   */
+-  changelog_entity():pkg(), ver(), section()
+-  {
+-  }
+-
+-  changelog_entity(const std::string &_pkg,
+-		   const std::string &_ver,
+-		   const std::string &_section)
+-    :pkg(_pkg), ver(_ver), section(_section)
+-  {
+-  }
+-
+-  changelog_entity &operator=(const changelog_entity &other)
+-  {
+-    pkg = other.pkg;
+-    ver = other.ver;
+-    section = other.section;
+-  }
+-};
+-
+-/** Find a source record in the given set of source records
+- *  corresponding to the package pkg, version ver.
+- *
+- *  \param records the source records object
+- *  \param pkg the package name to match on
+- *  \param ver the version string to match on
+- *
+- *  \return a matching changelog entity, or the empty entity if no
+- *  such entity exists.
+- */
+-changelog_entity find_src_ver(pkgSourceList &list,
+-			      const std::string &pkg,
+-			      const std::string &ver)
+-{
+-  pkgSrcRecords records(list);
+-  records.Restart();
+-
+-  pkgSrcRecords :: Parser *parser = records.Find(pkg.c_str());
+-
+-  while(parser != NULL && parser->Version() != ver)
+-    parser = records.Find(pkg.c_str());
+-
+-  if(parser == NULL)
+-    return changelog_entity();
+-  else
+-    return changelog_entity(pkg, ver, parser->Section());
+-}
+-
+-static void set_name(temp::name n, temp::name *target)
+-{
+-  *target = n;
+-}
+-
+-/** Try to find a particular package version without knowing the
+- *  section that it occurs in.  The resulting name will be invalid if
+- *  no changelog could be found.
+- */
+-temp::name changelog_by_version(const std::string &pkg,
+-				const std::string &ver)
+-{
+-  // Try forcing the particular version that was
+-  // selected, using various sections.  FIXME: relies
+-  // on specialized knowledge about how get_changelog
+-  // works; in particular, that it only cares whether
+-  // "section" has a first component.
+-
+-  temp::name rval;
+-  download_manager::result res = download_manager::failure;
+-
+-  download_manager *m = get_changelog_from_source(pkg, ver, "", pkg,
+-						  sigc::bind(sigc::ptr_fun(set_name),
+-							     &rval));
+-  if(m != NULL)
+-    {
+-      res = cmdline_do_download(m);
+-      delete m;
+-    }
+-
+-  if(res != download_manager::success || !rval.valid())
+-    {
+-      m = get_changelog_from_source(pkg, ver, "contrib/foo", pkg,
+-				    sigc::bind(sigc::ptr_fun(set_name), &rval));
+-      if(m != NULL)
+-	{
+-	  res = cmdline_do_download(m);
+-	  delete m;
+-	}
+-    }
+-
+-  if(res != download_manager::success || !rval.valid())
+-    {
+-      m = get_changelog_from_source(pkg, ver, "non-free/foo", pkg,
+-				    sigc::bind(sigc::ptr_fun(set_name), &rval));
+-      if(m != NULL)
+-	{
+-	  res = cmdline_do_download(m);
+-	  delete m;
+-	}
+-    }
+-
+-  if(res != download_manager::success)
+-    return temp::name();
+-  else
+-    return rval;
+-}
+-
+-/** Find a source record in the given set of source records
+- *  corresponding to the given package and archive.
+- *
+- *  IMPORTANT: You should dump errors before starting this routine; it
+- *  assumes that there are no pending errors.
+- *
+- *  \param records the source records object
+- *  \param pkg the package name to match on
+- *  \param ver the version string to match on
+- *
+- *  \return a matching changelog entity, or the empty entity
+- *  ("","","") if no such entity exists.
+- */
+-
+-// Based heavily on pkgSrcRecords.
+-changelog_entity find_src_archive(pkgSourceList &list,
+-				  const std::string &pkg,
+-				  const std::string &archive)
+-{
+-  for(pkgSourceList::const_iterator i = list.begin(); i!=list.end(); ++i)
+-    {
+-      if((*i)->GetDist() != archive)
+-	continue;
+-
+-      vector<pkgIndexFile *> *indexes = (*i)->GetIndexFiles();
+-
+-      for(vector<pkgIndexFile *> :: const_iterator j = indexes->begin();
+-	  j != indexes->end(); ++j)
+-	{
+-	  auto_ptr<pkgSrcRecords :: Parser> p((*j)->CreateSrcParser());
+-
+-	  if(_error->PendingError())
+-	    return changelog_entity();
+-	  if(p.get() != 0)
+-	    {
+-	      // Step through the file until we reach the end or find
+-	      // the package:
+-	      while(p.get()->Step() == true)
+-		{
+-		  if(_error->PendingError() == true)
+-		    return changelog_entity();
+-
+-		  if(p.get()->Package() == pkg)
+-		    return changelog_entity(pkg,
+-					    p.get()->Version(),
+-					    p.get()->Section());
+-		}
+-	    }
+-	}
+-    }
+-
+-  return changelog_entity();
+-}
+-
+-bool do_cmdline_changelog(const vector<string> &packages)
+-{
+-  const char *pager="/usr/bin/sensible-pager";
+-
+-  if(access("/usr/bin/sensible-pager", X_OK)!=0)
+-    {
+-      _error->Warning(_("Can't execute sensible-pager, is this a working Debian system?"));
+-
+-      pager=getenv("PAGER");
+-
+-      if(pager==NULL)
+-	pager="more";
+-    }
+-
+-  string default_release = aptcfg->Find("APT::Default-Release");
+-
+-  for(vector<string>::const_iterator i=packages.begin(); i!=packages.end(); ++i)
+-    {
+-      // We need to do this because some code (see above) checks
+-      // PendingError to see whether everything is OK.  In addition,
+-      // dumping errors means we get sensible error message output
+-      // (this will be true even if the PendingError check is removed
+-      // ... which it arguably should be).
+-      _error->DumpErrors();
+-      string input=*i;
+-
+-      cmdline_version_source source;
+-      string package, sourcestr;
+-
+-      if(!cmdline_parse_source(input, source, package, sourcestr))
+-	continue;
+-
+-      if(source == cmdline_version_cand && !default_release.empty())
+-	{
+-	  source    = cmdline_version_archive;
+-	  sourcestr = default_release;
+-	}
+-
+-      pkgCache::PkgIterator pkg=(*apt_cache_file)->FindPkg(package);
+-
+-      temp::name filename;
+-
+-      // For real packages/versions, we can do a sanity check.
+-      if(!pkg.end())
+-	{
+-	  pkgCache::VerIterator ver=cmdline_find_ver(pkg,
+-						     source, sourcestr);
+-
+-	  if(!ver.end())
+-	    {
+-	      // Move this to a central location and just display an
+-	      // apt error?
+-	      bool in_debian=false;
+-
+-	      for(pkgCache::VerFileIterator vf=ver.FileList();
+-		  !vf.end() && !in_debian; ++vf)
+-		if(!vf.File().end() && vf.File().Origin()!=NULL &&
+-		   strcmp(vf.File().Origin(), "Debian")==0)
+-		  in_debian=true;
+-
+-	      if(!in_debian)
+-		{
+-		  _error->Error(_("%s is not an official Debian package, cannot display its changelog."), input.c_str());
+-		  continue;
+-		}
+-	    }
+-
+-	  if(ver.end() && source == cmdline_version_version)
+-	    filename = changelog_by_version(package, sourcestr);
+-	  else
+-	    {
+-	      download_manager *m = get_changelog(ver,
+-						  sigc::bind(sigc::ptr_fun(&set_name), &filename));
+-	      if(m != NULL)
+-		{
+-		  cmdline_do_download(m);
+-		  delete m;
+-		}
+-	    }
+-	}
+-      else
+-	{
+-	  changelog_entity ent;
+-
+-	  switch(source)
+-	    {
+-	    case cmdline_version_cand:
+-	      // In this case, pull the first one we see (not very
+-	      // elegant, but finding the actual candidate is a bit
+-	      // hard)
+-	      {
+-		pkgSrcRecords r(*apt_source_list);
+-
+-		pkgSrcRecords :: Parser *p(r.Find(package.c_str()));
+-		while(p != NULL && p->Package() != package)
+-		  p = r.Find(package.c_str());
+-
+-		if(p != NULL)
+-		  ent = changelog_entity(package, p->Version(),
+-					 p->Section());
+-	      }
+-
+-	      break;
+-
+-	    case cmdline_version_archive:
+-	      _error->DumpErrors();
+-	      ent = find_src_archive(*apt_source_list,
+-				     package, sourcestr);
+-
+-	      break;
+-
+-	    case cmdline_version_version:
+-	      ent = find_src_ver(*apt_source_list, package, sourcestr);
+-
+-	      if(ent.pkg.empty())
+-		filename = changelog_by_version(package, sourcestr);
+-
+-	      break;
+-	    }
+-
+-
+-	  if(!filename.valid() && !ent.pkg.empty())
+-	    {
+-	      download_manager *m
+-		= get_changelog_from_source(ent.pkg,
+-					    ent.ver,
+-					    ent.section,
+-					    ent.pkg,
+-					    sigc::bind(sigc::ptr_fun(&set_name), &filename));
+-
+-	      if(m != NULL)
+-		{
+-		  cmdline_do_download(m);
+-
+-		  delete m;
+-		}
+-	    }
+-	}
+-
+-      if(!filename.valid())
+-	_error->Error(_("Couldn't find a changelog for %s"), input.c_str());
+-      else
+-	// Run the user's pager.
+-	system((string(pager) + " " + filename.get_name()).c_str());
+-    }
+-
+-  _error->DumpErrors();
+-}
+-
+-// TODO: fetch them all in one go.
+-int cmdline_changelog(int argc, char *argv[])
+-{
+-  _error->DumpErrors();
+-
+-  OpProgress progress;
+-  apt_init(&progress, false);
+-
+-  if(_error->PendingError())
+-    {
+-      _error->DumpErrors();
+-      return -1;
+-    }
+-
+-  vector<string> packages;
+-  for(int i=1; i<argc; ++i)
+-    packages.push_back(argv[i]);
+-
+-  do_cmdline_changelog(packages);
+-
+-  _error->DumpErrors();
+-
+-  return 0;
+-}
+diff --git a/src/cmdline/cmdline_changelog.h b/src/cmdline/cmdline_changelog.h
+deleted file mode 100644
+index a180a2a..0000000
+--- a/src/cmdline/cmdline_changelog.h
++++ /dev/null
+@@ -1,20 +0,0 @@
+-// cmdline_changelog.h                        -*-c++-*-
+-//
+-//   Copyright 2004 Daniel Burrows
+-
+-#ifndef CMDLINE_CHANGELOG_H
+-#define CMDLINE_CHANGELOG_H
+-
+-#include <string>
+-#include <vector>
+-
+-/** \brief Display the changelog of each of the given package specifiers.
+- *
+- *  The specifiers are literal package names, with optional version/archive
+- *  descriptors.  DumpErrors() is called after each changelog is displayed.
+- */
+-bool do_cmdline_changelog(const std::vector<std::string> &packages);
+-
+-int cmdline_changelog(int argc, char *argv[]);
+-
+-#endif // CMDLINE_CHANGELOG_H
+diff --git a/src/cmdline/cmdline_common.h b/src/cmdline/cmdline_common.h
+index 17c3681..1764772 100644
+--- a/src/cmdline/cmdline_common.h
++++ b/src/cmdline/cmdline_common.h
+@@ -23,7 +23,7 @@ typedef std::vector<string> strvector;
+ 
+ enum cmdline_pkgaction_type
+   {cmdline_install, cmdline_installauto, cmdline_remove,
+-   cmdline_purge, cmdline_hold, cmdline_unhold, cmdline_markauto,
++   cmdline_hold, cmdline_unhold, cmdline_markauto,
+    cmdline_unmarkauto, cmdline_forbid_version, cmdline_reinstall,
+    cmdline_keep};
+ 
+diff --git a/src/cmdline/cmdline_do_action.cc b/src/cmdline/cmdline_do_action.cc
+index e7e8976..7912f31 100644
+--- a/src/cmdline/cmdline_do_action.cc
++++ b/src/cmdline/cmdline_do_action.cc
+@@ -7,7 +7,6 @@
+ #include "cmdline_action.h"
+ #include "cmdline_common.h"
+ #include "cmdline_prompt.h"
+-#include "cmdline_resolver.h"
+ #include "cmdline_show_broken.h"
+ #include "cmdline_simulate.h"
+ #include "cmdline_util.h"
+@@ -53,8 +52,6 @@ int cmdline_do_action(int argc, char *argv[],
+     }
+   else if(!strcasecmp(argv[0], "remove"))
+     default_action=cmdline_remove;
+-  else if(!strcasecmp(argv[0], "purge"))
+-    default_action=cmdline_purge;
+   else if(!strcasecmp(argv[0], "hold"))
+     default_action=cmdline_hold;
+   else if(!strcasecmp(argv[0], "keep") || !strcasecmp(argv[0], "keep-all"))
+@@ -105,7 +102,7 @@ int cmdline_do_action(int argc, char *argv[],
+       return -1;
+     }
+ 
+-  pkgset to_upgrade, to_install, to_hold, to_remove, to_purge;
++  pkgset to_upgrade, to_install, to_hold, to_remove;
+ 
+   if(dist_upgrade)
+     {
+@@ -173,11 +170,6 @@ int cmdline_do_action(int argc, char *argv[],
+ 	      action=cmdline_install;
+ 	      argv[i][tmp]=0;
+ 	      break;
+-	    case '_':
+-	      action=cmdline_purge;
+-	      argv[i][tmp]=0;
+-
+-	      break;
+ 	    case ':':
+ 	      action=cmdline_keep;
+ 	      argv[i][tmp]=0;
+@@ -200,7 +192,7 @@ int cmdline_do_action(int argc, char *argv[],
+ 	    }
+ 
+ 	cmdline_applyaction(argv[i], action,
+-			    to_install, to_hold, to_remove, to_purge,
++			    to_install, to_hold, to_remove,
+ 			    verbose, false);
+       }
+   if(aptcfg->FindB(PACKAGE "::Auto-Install", true))
+@@ -216,7 +208,7 @@ int cmdline_do_action(int argc, char *argv[],
+       return 0;
+     }
+   else if(simulate)
+-    return cmdline_simulate(dist_upgrade, to_install, to_hold, to_remove, to_purge,
++    return cmdline_simulate(dist_upgrade, to_install, to_hold, to_remove,
+ 			    showvers, showdeps, showsize,
+ 			    always_prompt, verbose, assume_yes,
+ 			    !fix_broken);
+@@ -233,7 +225,7 @@ int cmdline_do_action(int argc, char *argv[],
+   else
+     {
+       if(!cmdline_do_prompt(dist_upgrade,
+-			    to_install, to_hold, to_remove, to_purge,
++			    to_install, to_hold, to_remove,
+ 			    showvers, showdeps, showsize,
+ 			    always_prompt, verbose, assume_yes,
+ 			    !fix_broken))
+diff --git a/src/cmdline/cmdline_dump_resolver.cc b/src/cmdline/cmdline_dump_resolver.cc
+deleted file mode 100644
+index 44f0e2b..0000000
+--- a/src/cmdline/cmdline_dump_resolver.cc
++++ /dev/null
+@@ -1,51 +0,0 @@
+-// cmdline_dump_resolver.cc
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-//
+-// Just print out the current resolver state (debugging tool)
+-
+-#include "cmdline_dump_resolver.h"
+-
+-#include <generic/apt/aptitude_resolver_universe.h>
+-#include <generic/problemresolver/dump_universe.h>
+-
+-#include <apt-pkg/error.h>
+-
+-using namespace std;
+-
+-int cmdline_dump_resolver(int argc, char *argv[],
+-			  const char *status_fname)
+-{
+-  _error->DumpErrors();
+-
+-  OpProgress progress;
+-
+-  apt_init(&progress, true, status_fname);
+-
+-  if(_error->PendingError())
+-    {
+-      _error->DumpErrors();
+-      return -1;
+-    }
+-
+-  aptitude_universe u(*apt_cache_file);
+-
+-  dump_universe(u, cout);
+-
+-  return 0;
+-}
+diff --git a/src/cmdline/cmdline_dump_resolver.h b/src/cmdline/cmdline_dump_resolver.h
+deleted file mode 100644
+index c8b0ec1..0000000
+--- a/src/cmdline/cmdline_dump_resolver.h
++++ /dev/null
+@@ -1,26 +0,0 @@
+-// cmdline_dump_resolver.h                     -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#ifndef CMDLINE_DUMP_RESOLVER
+-#define CMDLINE_DUMP_RESOLVER
+-
+-int cmdline_dump_resolver(int argc, char *argv[], const char *status_fname);
+-
+-#endif
+-
+diff --git a/src/cmdline/cmdline_prompt.cc b/src/cmdline/cmdline_prompt.cc
+index 5c6f3b2..447fc57 100644
+--- a/src/cmdline/cmdline_prompt.cc
++++ b/src/cmdline/cmdline_prompt.cc
+@@ -5,8 +5,6 @@
+ #include "cmdline_prompt.h"
+ 
+ #include "cmdline_action.h"
+-#include "cmdline_changelog.h"
+-#include "cmdline_resolver.h"
+ #include "cmdline_show.h"
+ #include "cmdline_util.h"
+ 
+@@ -22,10 +20,10 @@
+ #include <vscreen/transcode.h>
+ 
+ #include <apt-pkg/algorithms.h>
+-#include <apt-pkg/dpkgpm.h>
+ #include <apt-pkg/error.h>
+ #include <apt-pkg/sourcelist.h>
+ #include <apt-pkg/strutl.h>
++#include <apt-pkg/pkgsystem.h>
+ 
+ using namespace std;
+ 
+@@ -52,7 +50,7 @@ static bool get_fetchinfo(fetchinfo &f)
+   if(!l.ReadMainList())
+     return _error->Error(_("Couldn't read list of sources"));
+ 
+-  pkgDPkgPM pm(*apt_cache_file);
++  pkgPackageManager &pm = *_system->CreatePM(*apt_cache_file);
+   pm.GetArchives(&fetcher, &l, apt_package_records);
+ 
+   f.FetchBytes=fetcher.FetchNeeded();
+@@ -108,8 +106,7 @@ static string reason_string_list(set<reason> &reasons)
+ static void cmdline_show_instinfo(pkgvector &items,
+ 				  bool showvers,
+ 				  bool showdeps,
+-				  bool showsize,
+-				  bool showpurge)
++				  bool showsize)
+ {
+   sort(items.begin(), items.end(), pkg_byname_compare);
+   strvector output;
+@@ -122,12 +119,6 @@ static void cmdline_show_instinfo(pkgvector &items,
+       //aptitudeDepCache::aptitude_state &extstate=(*apt_cache_file)->get_ext_state(*i);
+       pkgCache::VerIterator instver=state.InstVerIter(*apt_cache_file);
+ 
+-      if(showpurge)
+-	{
+-	  if(state.Delete() && state.iFlags&pkgDepCache::Purge)
+-	    s += "{p}";
+-	}
+-
+       // Display version numbers.
+       if(showvers)
+ 	{
+@@ -521,26 +512,23 @@ static bool cmdline_show_preview(bool as_upgrade, pkgset &to_install,
+ 	  if(i==pkg_auto_install || i==pkg_auto_remove || i==pkg_unused_remove ||
+ 	     i==pkg_auto_hold || i==pkg_broken)
+ 	    cmdline_show_instinfo(lists[i],
+-				  showvers, showdeps, showsize,
+-				  (i == pkg_auto_remove ||
+-				   i == pkg_unused_remove));
++				  showvers, showdeps, showsize);
+ 	  else
+ 	    cmdline_show_instinfo(lists[i],
+-				  showvers, false, showsize,
+-				  i == pkg_remove);
++				  showvers, false, showsize);
+ 	}
+     }
+ 
+   if(!recommended.empty())
+     {
+       printf(_("The following packages are RECOMMENDED but will NOT be installed:\n"));
+-      cmdline_show_instinfo(recommended, showvers, showdeps, showsize, false);
++      cmdline_show_instinfo(recommended, showvers, showdeps, showsize);
+     }
+ 
+   if(verbose>0 && !suggested.empty())
+     {
+       printf(_("The following packages are SUGGESTED but will NOT be installed:\n"));
+-      cmdline_show_instinfo(suggested, showvers, showdeps, showsize, false);
++      cmdline_show_instinfo(suggested, showvers, showdeps, showsize);
+     }
+ 
+   if(all_empty)
+@@ -617,36 +605,6 @@ static void cmdline_parse_show(string response,
+   prompt_string(_("Press Return to continue."));
+ }
+ 
+-// Erm.  Merge w/ above?
+-static void cmdline_parse_changelog(string response)
+-{
+-  // assume response[0]=='i'
+-  string::size_type i=1;
+-
+-  vector<string> packages;
+-
+-  while(i<response.size())
+-    {
+-      while(i<response.size() && isspace(response[i]))
+-	++i;
+-
+-      string pkgname;
+-      // Could support quoting, etc?
+-      while(i<response.size() && !isspace(response[i]))
+-	pkgname+=response[i++];
+-
+-      if(!pkgname.empty())
+-	packages.push_back(pkgname);
+-    }
+-
+-  if(packages.empty())
+-    printf(_("No packages found -- enter the package names on the line after 'c'.\n"));
+-  else
+-    do_cmdline_changelog(packages);
+-
+-  prompt_string(_("Press Return to continue"));
+-}
+-
+ static inline fragment *flowindentbox(int i1, int irest, fragment *f)
+ {
+   return indentbox(i1, irest, flowbox(f));
+@@ -658,7 +616,6 @@ static void prompt_help(ostream &out)
+ 			fragf(_("y: %F"
+ 				"n: %F"
+ 				"i: %F"
+-				"c: %F"
+ 				"d: %F"
+ 				"s: %F"
+ 				"v: %F"
+@@ -672,7 +629,6 @@ static void prompt_help(ostream &out)
+ 				"%F"
+ 				"%F"
+ 				"%F"
+-				"%F"
+ 				"%F"),
+ 			      flowindentbox(0, 3,
+ 					    fragf(_("continue with the installation"))),
+@@ -681,8 +637,6 @@ static void prompt_help(ostream &out)
+ 			      flowindentbox(0, 3,
+ 					    fragf(_("show information about one or more packages; the package names should follow the 'i'"))),
+ 			      flowindentbox(0, 3,
+-					    fragf(_("show the Debian changelogs of one or more packages; the package names should follow the 'c'"))),
+-			      flowindentbox(0, 3,
+ 					    fragf(_("toggle the display of dependency information"))),
+ 			      flowindentbox(0, 3,
+ 					    fragf(_("toggle the display of changes in package sizes"))),
+@@ -701,8 +655,6 @@ static void prompt_help(ostream &out)
+ 			      flowindentbox(0, 4,
+ 					    fragf(_("'-' to remove packages"))),
+ 			      flowindentbox(0, 4,
+-					    fragf(_("'_' to purge packages"))),
+-			      flowindentbox(0, 4,
+ 					    fragf(_("'=' to place packages on hold"))),
+ 			      flowindentbox(0, 4,
+ 					    fragf(_("':' to keep packages in their current state without placing them on hold"))),
+@@ -720,7 +672,6 @@ bool cmdline_do_prompt(bool as_upgrade,
+ 		       pkgset &to_install,
+ 		       pkgset &to_hold,
+ 		       pkgset &to_remove,
+-		       pkgset &to_purge,
+ 		       bool showvers,
+ 		       bool showdeps,
+ 		       bool showsize,
+@@ -743,17 +694,8 @@ bool cmdline_do_prompt(bool as_upgrade,
+ 	cont=true;
+       else if((*apt_cache_file)->BrokenCount() > 0)
+ 	{
+-	  if(!cmdline_resolve_deps(to_install,
+-				   to_hold,
+-				   to_remove,
+-				   to_purge,
+-				   assume_yes,
+-				   force_no_change,
+-				   verbose))
+-	    {
+-	      cont=true;
+-	      rval=false;
+-	    }
++	  cont=true;
++	  rval=false;
+ 	}
+       else if(assume_yes)
+ 	cont=true;
+@@ -813,16 +755,12 @@ bool cmdline_do_prompt(bool as_upgrade,
+ 		case 'I':
+ 		  cmdline_parse_show(response, verbose);
+ 		  break;
+-		case 'C':
+-		  cmdline_parse_changelog(response);
+-		  break;
+ 		case '+':
+ 		case '-':
+ 		case '=':
+-		case '_':
+ 		case ':':
+ 		  cmdline_parse_action(response, to_install, to_hold,
+-				       to_remove, to_purge, verbose, true);
++				       to_remove, verbose, true);
+ 		  break;
+ 		case 'E':
+ 		  ui_preview();
+diff --git a/src/cmdline/cmdline_prompt.h b/src/cmdline/cmdline_prompt.h
+index ce5d68e..037bacf 100644
+--- a/src/cmdline/cmdline_prompt.h
++++ b/src/cmdline/cmdline_prompt.h
+@@ -30,7 +30,6 @@ public:
+  *  \param to_install a set of packages to install.
+  *  \param to_hold a set of packages to hold.
+  *  \param to_remove a set of packages to remove.
+- *  \param to_purge a set of packages to purge.
+  *  \param showvers \b true to show version information in the preview.
+  *  \param showdeps \b true to show dependency information in the preview.
+  *  \param showsize \b true to show size information in the preview.
+@@ -47,7 +46,6 @@ bool cmdline_do_prompt(bool as_upgrade,
+ 		       pkgset &to_install,
+ 		       pkgset &to_hold,
+ 		       pkgset &to_remove,
+-		       pkgset &to_purge,
+ 		       bool showvers,
+ 		       bool showdeps,
+ 		       bool showsize,
+diff --git a/src/cmdline/cmdline_resolver.cc b/src/cmdline/cmdline_resolver.cc
+deleted file mode 100644
+index a0914df..0000000
+--- a/src/cmdline/cmdline_resolver.cc
++++ /dev/null
+@@ -1,679 +0,0 @@
+-// cmdline_resolver.cc
+-//
+-//   Copyright (C) 2005-2006 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#include "cmdline_resolver.h"
+-
+-#include "cmdline_action.h"
+-#include "cmdline_common.h"
+-#include "cmdline_prompt.h"
+-#include "cmdline_show.h"
+-#include "cmdline_show_broken.h"
+-#include "cmdline_spinner.h"
+-#include "cmdline_util.h"
+-
+-#include <aptitude.h>
+-#include <solution_fragment.h>
+-
+-#include <generic/apt/aptcache.h>
+-#include <generic/apt/aptitude_resolver_universe.h>
+-#include <generic/apt/config_signal.h>
+-#include <generic/apt/resolver_manager.h>
+-
+-#include <generic/problemresolver/exceptions.h>
+-#include <generic/problemresolver/solution.h>
+-
+-#include <generic/util/util.h>
+-
+-#include <vscreen/fragment.h>
+-
+-#include <apt-pkg/error.h>
+-#include <apt-pkg/strutl.h>
+-
+-#include <iostream>
+-#include <fstream>
+-#include <sstream>
+-
+-using namespace std;
+-
+-typedef generic_solution<aptitude_universe> aptitude_solution;
+-
+-/** Generate a fragment describing a solution as an ordered sequence
+- *  of actions.
+- */
+-static fragment *solution_story(const aptitude_solution &s)
+-{
+-  std::vector<aptitude_solution::action> actions;
+-  for(imm::map<aptitude_universe::package, aptitude_solution::action>::const_iterator
+-	i = s.get_actions().begin(); i != s.get_actions().end(); ++i)
+-    actions.push_back(i->second);
+-  sort(actions.begin(), actions.end(), aptitude_solution::action_id_compare());
+-
+-
+-  vector<fragment *> fragments;
+-
+-  for(vector<aptitude_solution::action>::const_iterator i = actions.begin();
+-      i != actions.end(); ++i)
+-    fragments.push_back(fragf("%ls%n -> %F%n",
+-			      dep_text(i->d.get_dep()).c_str(),
+-			      indentbox(0, 4, action_fragment(*i))));
+-
+-  return sequence_fragment(fragments);
+-}
+-
+-static void setup_resolver(pkgset &to_install,
+-			   pkgset &to_hold,
+-			   pkgset &to_remove,
+-			   pkgset &to_purge,
+-			   bool force_no_change)
+-{
+-  resman->set_debug(aptcfg->FindB(PACKAGE "::CmdLine::Resolver-Debug", false));
+-
+-  // For all packages that the user listed on the command-line (i.e.,
+-  // all in to_install, to_hold, to_remove, and to_purge), tell the
+-  // resolver to try *really really hard* to avoid altering their
+-  // state.
+-  if(force_no_change && resman->resolver_exists())
+-    {
+-      pkgset *sets[4]={&to_install, &to_hold, &to_remove, &to_purge};
+-      int tweak_amt=aptcfg->FindI(PACKAGE "::CmdLine::Request-Strictness", 10000);
+-
+-      for(int i=0; i<4; ++i)
+-	{
+-	  pkgset &S=*sets[i];
+-
+-	  for(pkgset::const_iterator p=S.begin();
+-	      p!=S.end(); ++p)
+-	    {
+-	      pkgDepCache::StateCache &state=(*apt_cache_file)[*p];
+-	      pkgCache::VerIterator instver=state.InstVerIter(*apt_cache_file);
+-
+-	      for(pkgCache::VerIterator v=p->VersionList();
+-		  !v.end(); ++v)
+-		if(instver == v)
+-		  resman->tweak_score(*p, v,
+-				     tweak_amt);
+-
+-	      if(instver.end())
+-		resman->tweak_score(*p, pkgCache::VerIterator(*apt_cache_file),
+-				   tweak_amt);
+-	    }
+-	}
+-    }
+-
+-  string dumpfile = aptcfg->Find(PACKAGE "::CmdLine::Resolver-Dump", "");
+-  if(!dumpfile.empty())
+-    {
+-      ofstream f(dumpfile.c_str());
+-      if(!f)
+-	_error->Errno("dump_resolver", _("Unable to open %s for writing"), dumpfile.c_str());
+-      else
+-	{
+-	  resman->dump(f);
+-
+-	  if(!f)
+-	    _error->Errno("dump_resolver", _("Error writing resolver state to %s"), dumpfile.c_str());
+-	  else
+-	    cout << _("Resolver state successfully written!");
+-	}
+-    }
+-}
+-
+-static inline fragment *flowindentbox(int i1, int irest, fragment *f)
+-{
+-  return indentbox(i1, irest, flowbox(f));
+-}
+-
+-static void resolver_help(ostream &out)
+-{
+-  fragment *f=indentbox(2, 2,
+-			fragf(_("y: %F"
+-				"n: %F"
+-				"q: %F"
+-				",: %F"
+-				".: %F"
+-				"o: %F"
+-				"e: %F"
+-				"r pkg ver ...: %F%n"
+-				"a pkg ver ...: %F%n"
+-				"<ACTION> pkg... : %F%n"
+-				"%F"
+-				"%F"
+-				"%F"
+-				"%F"
+-				"%F"
+-				"%F"
+-				"%F"
+-				"%F"),
+-			      flowindentbox(0, 3,
+-					    fragf(_("accept the proposed changes"))),
+-			      flowindentbox(0, 3,
+-					    fragf(_("reject the proposed changes and search for another solution"))),
+-			      flowindentbox(0, 3,
+-					    fragf(_("give up and quit the program"))),
+-			      flowindentbox(0, 3,
+-					    fragf(_("move to the next solution"))),
+-			      flowindentbox(0, 3,
+-					    fragf(_("move to the previous solution"))),
+-			      flowindentbox(0, 3,
+-					    fragf(_("view an explanation of the changes in the solution"))),
+-			      flowindentbox(0, 3,
+-					    fragf(_("examine the solution in the visual user interface"))),
+-			      flowindentbox(0, 3,
+-					    fragf(_("reject the given package versions; don't display any solutions in which they occur."))),
+-			      flowindentbox(0, 3,
+-					    fragf(_("accept the given package versions; display only solutions in which they occur."))),
+-			      flowindentbox(0, 3,
+-					    fragf(_("adjust the state of the listed packages, where ACTION is one of:"))),
+-			      flowindentbox(0, 4,
+-					    fragf(_("'+' to install packages"))),
+-			      flowindentbox(0, 5,
+-					    fragf(_("'+M' to install packages and immediately flag them as automatically installed"))),
+-			      flowindentbox(0, 4,
+-					    fragf(_("'-' to remove packages"))),
+-			      flowindentbox(0, 4,
+-					    fragf(_("'_' to purge packages"))),
+-			      flowindentbox(0, 4,
+-					    fragf(_("'=' to place packages on hold"))),
+-			      flowindentbox(0, 4,
+-					    fragf(_("':' to keep packages in their current state without placing them on hold"))),
+-			      flowindentbox(0, 4,
+-					    fragf(_("'&M' to mark packages as automatically installed"))),
+-			      flowindentbox(0, 4,
+-					    fragf(_("'&m' to mark packages as manually installed"))),
+-			      flowindentbox(0, 3,
+-					    fragf(_("Adjustments will cause the current solution to be discarded and recalculated as necessary.")))));
+-
+-  out << f->layout(screen_width, screen_width, style());
+-  delete f;
+-}
+-
+-// Given several versions with the same VerStr, choose one to output.
+-static pkgCache::VerIterator choose_version(const vector<pkgCache::VerIterator> &choices)
+-{
+-  eassert(!choices.empty());
+-
+-  if(choices.size() == 1)
+-    return choices.front();
+-
+-  cout << ssprintf(_("The version %s is available in the following archives:"), choices.front().VerStr()) << endl;
+-
+-  for(vector<pkgCache::VerIterator>::size_type i = 0;
+-      i < choices.size(); ++i)
+-    cout << ssprintf(" (%d) %s", i+1, archives_text(choices[i]).c_str()) << endl;
+-
+-  while(1)
+-    {
+-      string response = prompt_string(ssprintf(_("Select the version of %s that should be used: "), choices.front().ParentPkg().Name()));
+-
+-      int i;
+-      istringstream in(response);
+-      in >> ws >> i >> ws;
+-
+-      if(!in || !in.eof() || i < 1 || i > choices.size())
+-	cerr << ssprintf(_("Invalid response.  Please enter an integer between 1 and %d."), choices.size()) << endl;
+-      else
+-	return choices[i];
+-    }
+-}
+-
+-static void reject_or_mandate_version(const string &s,
+-				      bool is_reject)
+-{
+-  istringstream in(s);
+-
+-  in >> ws;
+-
+-  if(in.eof())
+-    {
+-      cerr << ssprintf(_("Expected at least one package/version pair following '%c'"),
+-			 is_reject ? 'R' : 'A') << endl;
+-      return;
+-    }
+-
+-  string pkgname;
+-  string vername;
+-
+-  while(!in.eof())
+-    {
+-      in >> pkgname >> ws;
+-
+-      if(in.eof())
+-	{
+-	  cerr << ssprintf(_("Expected a version after \"%s\""), pkgname.c_str()) << endl;
+-	  return;
+-	}
+-
+-      in >> vername >> ws;
+-
+-      pkgCache::PkgIterator pkg((*apt_cache_file)->FindPkg(pkgname));
+-
+-      if(pkg.end())
+-	{
+-	  cerr << ssprintf(_("No such package \"%s\""), pkgname.c_str()) << endl;
+-	  continue;
+-	}
+-
+-      aptitude_universe::version ver(pkg,
+-				     pkgCache::VerIterator(*apt_cache_file),
+-				     *apt_cache_file);
+-      if(stringcasecmp(vername, "UNINST") != 0)
+-	{
+-	  vector<pkgCache::VerIterator> found;
+-	  for(pkgCache::VerIterator vi = pkg.VersionList(); !vi.end(); ++vi)
+-	    if(vi.VerStr() == vername)
+-	      found.push_back(vi);
+-
+-	  if(found.empty())
+-	    {
+-	      cerr << ssprintf(_("%s has no version named \"%s\""),
+-			       pkgname.c_str(), vername.c_str()) << endl;
+-	      continue;
+-	    }
+-
+-	  ver = aptitude_universe::version(pkg, choose_version(found),
+-					   *apt_cache_file);
+-
+-	  eassert(!ver.get_ver().end());
+-	  eassert(ver.get_pkg() == ver.get_ver().ParentPkg());
+-	}
+-
+-      if(is_reject)
+-	{
+-	  if(resman->is_rejected(ver))
+-	    {
+-	      if(ver.get_ver().end())
+-		cout << ssprintf(_("Allowing the removal of %s"),
+-				 pkgname.c_str()) << endl;
+-	      else
+-		cout << ssprintf(_("Allowing the installation of %s version %s (%s)"),
+-				 pkg.Name(),
+-				 ver.get_ver().VerStr(),
+-				 archives_text(ver.get_ver()).c_str()) << endl;
+-
+-	      resman->unreject_version(ver);
+-	    }
+-	  else
+-	    {
+-	      if(ver.get_ver().end())
+-		cout << ssprintf(_("Rejecting the removal of %s"),
+-				 pkgname.c_str()) << endl;
+-	      else
+-		cout << ssprintf(_("Rejecting the installation of %s version %s (%s)"),
+-				 pkg.Name(),
+-				 ver.get_ver().VerStr(),
+-				 archives_text(ver.get_ver()).c_str()) << endl;
+-
+-	      resman->reject_version(ver);
+-	    }
+-	}
+-      else
+-	{
+-	  if(resman->is_mandatory(ver))
+-	    {
+-	      if(ver.get_ver().end())
+-		cout << ssprintf(_("No longer requiring the removal of %s"),
+-				 pkgname.c_str()) << endl;
+-	      else
+-		cout << ssprintf(_("No longer requiring the installation of %s version %s (%s)"),
+-				 pkg.Name(), ver.get_ver().VerStr(),
+-				 archives_text(ver.get_ver()).c_str()) << endl;
+-
+-	      resman->unmandate_version(ver);
+-	    }
+-	  else
+-	    {
+-	      if(ver.get_ver().end())
+-		cout << ssprintf(_("Requiring the removal of %s"),
+-				 pkgname.c_str()) << endl;
+-	      else
+-		cout << ssprintf(_("Requiring the installation of %s version %s (%s)"),
+-				 pkg.Name(), ver.get_ver().VerStr(),
+-				 archives_text(ver.get_ver()).c_str()) << endl;
+-
+-	      resman->mandate_version(ver);
+-	    }
+-	}
+-    }
+-}
+-
+-// TODO: make this generic?
+-class cmdline_resolver_continuation : public resolver_manager::background_continuation
+-{
+-public:
+-  struct resolver_result
+-  {
+-    /** If \b true, then NoMoreSolutions was thrown. */
+-    bool out_of_solutions;
+-
+-    /** If \b true, then NoMoreTime was thrown. */
+-    bool out_of_time;
+-
+-    /** If out_of_solutions and out_of_time are false, this is
+-     *  the result returned by the resolver.
+-     */
+-    aptitude_solution sol;
+-
+-    resolver_result()
+-      : out_of_solutions(false), out_of_time(false)
+-    {
+-    }
+-
+-    resolver_result(bool _out_of_solutions, bool _out_of_time)
+-      : out_of_solutions(_out_of_solutions),
+-	out_of_time(_out_of_time)
+-    {
+-    }
+-
+-    resolver_result(const aptitude_solution &_sol)
+-      : out_of_solutions(false), out_of_time(false), sol(_sol)
+-    {
+-    }
+-  };
+-
+-private:
+-  threads::box<resolver_result> &retbox;
+-
+-public:
+-  cmdline_resolver_continuation(threads::box<resolver_result> &_retbox)
+-    : retbox(_retbox)
+-  {
+-  }
+-
+-  void success(const aptitude_solution &sol)
+-  {
+-    retbox.put(resolver_result(sol));
+-  }
+-
+-  void no_more_solutions()
+-  {
+-    retbox.put(resolver_result(true, false));
+-  }
+-
+-  void no_more_time()
+-  {
+-    retbox.put(resolver_result(false, true));
+-  }
+-
+-  void interrupted()
+-  {
+-    abort();
+-  }
+-};
+-
+-/** \return the resolver's current solution; if it needs to be calculated
+- *          first, run the calculation in the background and display
+- *          a spinner in the foreground.
+- */
+-static
+-aptitude_solution calculate_current_solution()
+-{
+-  if(resman->get_selected_solution() < resman->generated_solution_count())
+-    return resman->get_solution(resman->get_selected_solution(), 0);
+-
+-
+-  cmdline_spinner spin(aptcfg->FindI("Quiet", 0));
+-
+-  std::cout << "Resolving dependencies..." << std::endl;
+-
+-  threads::box<cmdline_resolver_continuation::resolver_result> retbox;
+-
+-  resman->get_solution_background(resman->generated_solution_count(),
+-				  aptcfg->FindI(PACKAGE "::ProblemResolver::StepLimit", 5000),
+-				  new cmdline_resolver_continuation(retbox));
+-
+-  cmdline_resolver_continuation::resolver_result res;
+-  bool done = false;
+-  // The number of milliseconds to step per display.
+-  long spin_step = aptcfg->FindI(PACKAGE "::Spin-Interval", 500);
+-
+-  do
+-    {
+-      timeval until;
+-      gettimeofday(&until, 0);
+-
+-      until.tv_usec += spin_step * 1000L;
+-      until.tv_sec += until.tv_usec / (1000L * 1000L);
+-      until.tv_usec = until.tv_usec % (1000L * 1000L);
+-
+-      timespec until_ts;
+-      until_ts.tv_sec = until.tv_sec;
+-      until_ts.tv_nsec = until.tv_usec * 1000;
+-
+-      done = retbox.timed_take(res, until_ts);
+-
+-      if(!done)
+-	{
+-	  resolver_manager::state state = resman->state_snapshot();
+-
+-	  spin.set_msg(ssprintf(_("open: %d; closed: %d; defer: %d; conflict: %d"),
+-				state.open_size, state.closed_size,
+-				state.deferred_size, state.conflicts_size));
+-	  spin.display();
+-	  spin.tick();
+-	}
+-    } while(!done);
+-
+-  if(res.out_of_time)
+-    throw NoMoreTime();
+-  else if(res.out_of_solutions)
+-    throw NoMoreSolutions();
+-  else
+-    return res.sol;
+-}
+-
+-bool cmdline_resolve_deps(pkgset &to_install,
+-			  pkgset &to_hold,
+-			  pkgset &to_remove,
+-			  pkgset &to_purge,
+-			  bool assume_yes,
+-			  bool force_no_change,
+-			  int verbose)
+-{
+-  while(!show_broken())
+-    {
+-      setup_resolver(to_install, to_hold, to_remove, to_purge,
+-		     force_no_change);
+-      aptitude_solution lastsol;
+-
+-      // The inner loop tries to generate solutions until some
+-      // packages are modified (then the new set of broken packages,
+-      // if any, is displayed and we start over)
+-      bool modified_pkgs=false;
+-      while(!modified_pkgs)
+-	try
+-	  {
+-	    try
+-	      {
+-		aptitude_solution sol = calculate_current_solution();
+-
+-		if(_error->PendingError())
+-		  _error->DumpErrors();
+-
+-		if(sol != lastsol)
+-		  {
+-		    fragment *f=sequence_fragment(flowbox(text_fragment(_("The following actions will resolve these dependencies:"))),
+-						  newline_fragment(),
+-						  solution_fragment(sol),
+-						  NULL);
+-
+-		    update_screen_width();
+-
+-		    fragment_contents lines=f->layout(screen_width, screen_width, style());
+-
+-		    delete f;
+-
+-		    cout << lines << endl;
+-		    lastsol=sol;
+-		  }
+-
+-		string response=assume_yes?"Y":prompt_string(_("Accept this solution? [Y/n/q/?] "));
+-
+-		string::size_type loc=0;
+-		while(loc<response.size() && isspace(response[loc]))
+-		  ++loc;
+-		if(loc == response.size())
+-		  {
+-		    response='Y';
+-		    loc=0;
+-		  }
+-
+-		switch(toupper(response[loc]))
+-		  {
+-		  case 'Y':
+-		    (*apt_cache_file)->apply_solution(calculate_current_solution(), NULL);
+-		    modified_pkgs=true;
+-		    break;
+-		  case 'N':
+-		    {
+-		      int curr_count = resman->generated_solution_count();
+-
+-		      if(curr_count>0)
+-			while(resman->get_selected_solution() < curr_count)
+-			  resman->select_next_solution();
+-		    }
+-		    break;
+-		  case 'Q':
+-		    cout << _("Abandoning all efforts to resolve these dependencies.") << endl;
+-		    return false;
+-		  case 'O':
+-		    {
+-		      fragment *f = solution_story(sol);
+-		      update_screen_width();
+-		      cout << f->layout(screen_width, screen_width,
+-					style()) << endl;
+-		      delete f;
+-		      break;
+-		    }
+-		  case 'E':
+-		    ui_solution_screen();
+-		    break;
+-		  case 'R':
+-		    reject_or_mandate_version(string(response, 1), true);
+-		    break;
+-		  case 'A':
+-		    reject_or_mandate_version(string(response, 1), false);
+-		    break;
+-		  case '.':
+-		    resman->select_next_solution();
+-		    break;
+-		  case ',':
+-		    resman->select_previous_solution();
+-		    break;
+-		  case '?':
+-		    cout << _("The following commands are available:") << endl;
+-		    resolver_help(cout);
+-		    break;
+-		  case '+':
+-		  case '-':
+-		  case '=':
+-		  case '_':
+-		  case ':':
+-		    /// \todo Maybe only do auto-installation of dependencies
+-		    /// after the parse?
+-		    cmdline_parse_action(response, to_install, to_hold,
+-					 to_remove, to_purge, verbose, false);
+-		    modified_pkgs=true;
+-		    break;
+-		    // Undocumented debug feature:
+-		  case '~':
+-		    {
+-		      string fn=prompt_string(_("File to write resolver state to: "));
+-		      ofstream f(fn.c_str());
+-		      if(!f)
+-			_error->Errno("dump_resolver", _("Unable to open %s for writing"), fn.c_str());
+-		      else
+-			{
+-			  resman->dump(f);
+-			  if(!f)
+-			    _error->Errno("dump_resolver", _("Error writing resolver state to %s"), fn.c_str());
+-			  else
+-			    cout << _("Resolver state successfully written!");
+-			}
+-		    }
+-		    break;
+-		  default:
+-		    cout << _("Invalid response; please enter one of the following commands:") << endl;
+-		    resolver_help(cout);
+-		    break;
+-		  }
+-	      }
+-	    catch(NoMoreTime)
+-	      {
+-		bool done=false;
+-		while(!done)
+-		  {
+-		    string response;
+-// FIXME: translate Y, N
+-		    if(!assume_yes)
+-		      response = prompt_string(_("No solution found within the allotted time.  Try harder? [Y/n]"));
+-
+-		    string::size_type loc=0;
+-		    while(loc<response.size() && isspace(response[loc]))
+-		      ++loc;
+-		    if(loc == response.size())
+-		      {
+-			loc=0;
+-			response='Y';
+-		      }
+-// FIXME: translate Y, N
+-		    switch(toupper(response[loc]))
+-		      {
+-		      case 'Y':
+-			try
+-			  {
+-			    calculate_current_solution();
+-			    done=true;
+-			  }
+-			catch(NoMoreTime)
+-			  {
+-			    // ignore and continue looping.
+-			  }
+-			// NoMoreExceptions flows to the outer catch.
+-			break;
+-		      case 'N':
+-			cout << _("Abandoning all efforts to resolve these dependencies.") << endl;
+-			return false;
+-		      default:
+-			cout << _("Invalid response; please enter 'y' or 'n'.") << endl;
+-		      }
+-		  }
+-	      }
+-	  }
+-	catch(NoMoreSolutions)
+-	  {
+-	    if(resman->generated_solution_count()==0)
+-	      {
+-		cout << _("Unable to resolve dependencies!  Giving up...") << endl;
+-		return false;
+-	      }
+-	    else
+-	      {
+-		cout << endl
+-		     << _("*** No more solutions available ***")
+-		     << endl
+-		     << endl;
+-		// Force it to re-print the last solution.
+-		resman->select_previous_solution();
+-		lastsol.nullify();
+-	      }
+-	  }
+-    }
+-
+-  return true;
+-}
+diff --git a/src/cmdline/cmdline_resolver.h b/src/cmdline/cmdline_resolver.h
+deleted file mode 100644
+index 7504bd9..0000000
+--- a/src/cmdline/cmdline_resolver.h
++++ /dev/null
+@@ -1,55 +0,0 @@
+-// cmdline_resolver.h                              -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#ifndef CMDLINE_RESOLVER_H
+-#define CMDLINE_RESOLVER_H
+-
+-#include "cmdline_common.h"
+-
+-/** Run the resolver once, possibly prompting the user in the process.
+- *
+- *  \param to_install a list of packages which the user explicitly
+- *  asked to install
+- *
+- *  \param to_hold a list of packages which the user explicitly asked
+- *  to hold back
+- *
+- *  \param to_remove a list of packages which the user explicitly
+- *  asked to remove
+- *
+- *  \param to_purge a list of packages which the user explicitly asked
+- *  to purge
+- *
+- *  \param assume_yes if \b true, try to find a single solution
+- *  (regardless of how long it takes) and accept it immediately.
+- *
+- *  \param force_no_change if \b true, assign extra version scores to
+- *  heavily bias the resolver against changing any packages in the
+- *  supplied sets.
+- *  \param verbose the verbosity level set by the user
+- */
+-bool cmdline_resolve_deps(pkgset &to_install,
+-			  pkgset &to_hold,
+-			  pkgset &to_remove,
+-			  pkgset &to_purge,
+-			  bool assume_yes,
+-			  bool force_no_change,
+-			  int verbose);
+-
+-#endif // CMDLINE_RESOLVER_H
+diff --git a/src/cmdline/cmdline_show.cc b/src/cmdline/cmdline_show.cc
+index 40d966f..19dabf5 100644
+--- a/src/cmdline/cmdline_show.cc
++++ b/src/cmdline/cmdline_show.cc
+@@ -309,9 +309,6 @@ static fragment *state_fragment(pkgCache::PkgIterator pkg, pkgCache::VerIterator
+ 			 statestr,
+ 			 instver.VerStr());
+ 	}
+-      else if(state.Delete() && (state.iFlags&pkgDepCache::Purge) &&
+-	      pkg->CurrentState!=pkgCache::State::NotInstalled)
+-	return fragf(_("%s; will be purged"), statestr);
+       else
+ 	return fragf("%s", statestr);
+     }
+@@ -422,10 +419,6 @@ static fragment *version_file_fragment(pkgCache::VerIterator ver,
+ 			    get_short_description(ver).c_str()));
+   fragments.push_back(indentbox(1, 1, make_desc_fragment(get_long_description(ver))));
+ 
+-  fragment *tags = make_tags_fragment(pkg);
+-  if(tags)
+-    fragments.push_back(fragf("%n%F", tags));
+-
+   return sequence_fragment(fragments);
+ }
+ 
+diff --git a/src/cmdline/cmdline_simulate.cc b/src/cmdline/cmdline_simulate.cc
+index 38674f0..9227655 100644
+--- a/src/cmdline/cmdline_simulate.cc
++++ b/src/cmdline/cmdline_simulate.cc
+@@ -18,13 +18,12 @@
+ 
+ int cmdline_simulate(bool as_upgrade,
+ 		     pkgset &to_install, pkgset &to_hold, pkgset &to_remove,
+-		     pkgset &to_purge,
+ 		     bool showvers, bool showdeps, bool showsize,
+ 		     bool always_prompt, int verbose,
+ 		     bool assume_yes, bool force_no_change)
+ {
+   if(!cmdline_do_prompt(as_upgrade,
+-			to_install, to_hold, to_remove, to_purge,
++			to_install, to_hold, to_remove,
+ 			showvers, showdeps, showsize, always_prompt, verbose,
+ 			assume_yes, force_no_change))
+     {
+diff --git a/src/cmdline/cmdline_simulate.h b/src/cmdline/cmdline_simulate.h
+index 263dfd8..2f24355 100644
+--- a/src/cmdline/cmdline_simulate.h
++++ b/src/cmdline/cmdline_simulate.h
+@@ -16,7 +16,6 @@
+  *  \param to_install a set of packages to install.
+  *  \param to_hold a set of packages to hold.
+  *  \param to_remove a set of packages to remove.
+- *  \param to_purge a set of packages to purge.
+  *  \param showvers \b true to show version information in the preview.
+  *  \param showdeps \b true to show dependency information in the preview.
+  *  \param showsize \b true to show size information in the preview.
+@@ -30,7 +29,6 @@
+ 
+ int cmdline_simulate(bool as_upgrade,
+ 		     pkgset &to_install, pkgset &to_hold, pkgset &to_remove,
+-		     pkgset &to_purge,
+ 		     bool showvers, bool showdeps, bool showsize,
+ 		     bool always_prompt, int verbose,
+ 		     bool assume_yes, bool force_no_change);
+diff --git a/src/cmdline/cmdline_upgrade.cc b/src/cmdline/cmdline_upgrade.cc
+index 9aab7dd..e9b17fa 100644
+--- a/src/cmdline/cmdline_upgrade.cc
++++ b/src/cmdline/cmdline_upgrade.cc
+@@ -29,7 +29,7 @@ int cmdline_upgrade(int argc, char *argv[],
+ 		    bool always_prompt, bool queue_only,
+ 		    int verbose)
+ {
+-  pkgset to_install, to_hold, to_remove, to_purge;
++  pkgset to_install, to_hold, to_remove;
+ 
+   _error->DumpErrors();
+ 
+@@ -82,7 +82,7 @@ int cmdline_upgrade(int argc, char *argv[],
+       return 0;
+     }
+   else if(simulate)
+-    return cmdline_simulate(true, to_install, to_hold, to_remove, to_purge,
++    return cmdline_simulate(true, to_install, to_hold, to_remove,
+ 			    showvers, showdeps, showsize,
+ 			    always_prompt, verbose, assume_yes,
+ 			    false);
+@@ -97,7 +97,7 @@ int cmdline_upgrade(int argc, char *argv[],
+     {
+ 
+       if(!cmdline_do_prompt(true, to_install, to_hold, to_remove,
+-			    to_purge, showvers, showdeps, showsize,
++			    showvers, showdeps, showsize,
+ 			    always_prompt, verbose,
+ 			    assume_yes, false))
+ 	{
+diff --git a/src/cmdline/cmdline_util.cc b/src/cmdline/cmdline_util.cc
+index 6c4708d..f5c4dca 100644
+--- a/src/cmdline/cmdline_util.cc
++++ b/src/cmdline/cmdline_util.cc
+@@ -29,19 +29,6 @@ void ui_preview()
+   exit(0);
+ }
+ 
+-void ui_solution_screen()
+-{
+-  ui_init();
+-  file_quit.connect(sigc::ptr_fun(vscreen_exitmain));
+-
+-  vs_progress_ref p = gen_progress_bar();
+-  do_new_package_view(*p.unsafe_get_ref());
+-
+-  do_examine_solution();
+-  ui_main();
+-  exit(0);
+-}
+-
+ void cmdline_show_stringlist(strvector &items)
+ {
+   int loc=2;
+diff --git a/src/cmdline/cmdline_util.h b/src/cmdline/cmdline_util.h
+index 4633ec9..03913f3 100644
+--- a/src/cmdline/cmdline_util.h
++++ b/src/cmdline/cmdline_util.h
+@@ -24,11 +24,6 @@ pkgCache::VerIterator cmdline_find_ver(pkgCache::PkgIterator pkg,
+  */
+ void ui_preview();
+ 
+-/** Starts up the visual UI with the solution screen visible, exiting
+- *  when the UI shuts down.
+- */
+-void ui_solution_screen();
+-
+ /** Splits the given input string into a package name/pattern and a
+  *  version source.  If the input string is an output string, the
+  *  function will still behave sanely.
+diff --git a/src/defaults.cc b/src/defaults.cc
+index 629f3c8..fecbf1b 100644
+--- a/src/defaults.cc
++++ b/src/defaults.cc
+@@ -31,7 +31,6 @@ static void init_keybindings()
+   global_bindings.set("Install", key(L'+', false));
+   global_bindings.set("Remove", key(L'-', false));
+   global_bindings.set("Hold", key(L'=', false));
+-  global_bindings.set("Purge", key(L'_', false));
+   global_bindings.set("Keep", key(L':', false));
+   global_bindings.set("SetAuto", key(L'M', false));
+   global_bindings.set("ClearAuto", key(L'm', false));
+@@ -42,7 +41,6 @@ static void init_keybindings()
+   global_bindings.set("ReverseDependencies", key(L'r', false));
+   global_bindings.set("InfoScreen", key(KEY_ENTER, true));
+   global_bindings.set("Versions", key(L'v', false));
+-  global_bindings.set("Changelog", key(L'C', false));
+ 
+   global_bindings.set("DoInstallRun", key(L'g', false));
+   global_bindings.set("InstallSingle", key(L'I', false));
+@@ -60,11 +58,6 @@ static void init_keybindings()
+   global_bindings.set("DpkgReconfigure", key(L'R', false));
+   global_bindings.set("BugReport", key(L'B', false));
+ 
+-  // Hierarchy editor
+-  global_bindings.set("Commit", key(L'N', false));
+-  global_bindings.set("SaveHier", key(L'S', false));
+-  global_bindings.set("EditHier", key(L'E', false));
+-
+   global_bindings.set("SearchBroken", key(L'b', false));
+ 
+   global_bindings.set("NextSolution", key(L'.', false));
+@@ -119,7 +112,6 @@ static void init_styles()
+   set_style("DownloadProgress", style_fg(COLOR_BLUE)+style_bg(COLOR_YELLOW));
+   set_style("DownloadHit", style_fg(COLOR_BLACK)+style_bg(COLOR_GREEN));
+ 
+-  set_style("ChangelogNewerVersion", style_attrs_on(A_BOLD));
+   set_style("Bullet", style_fg(COLOR_YELLOW)+style_attrs_on(A_BOLD));
+   set_style("TrustWarning", style_fg(COLOR_RED)+style_bg(COLOR_BLACK)+style_attrs_on(A_BOLD));
+ 
+diff --git a/src/dep_item.cc b/src/dep_item.cc
+index 0423e5c..3e3e531 100644
+--- a/src/dep_item.cc
++++ b/src/dep_item.cc
+@@ -31,7 +31,8 @@
+ #include <generic/apt/apt.h>
+ #include <generic/apt/config_signal.h>
+ 
+-#include <apt-pkg/version.h>
++#include <apt-pkg/pkgsystem.h>
++#include <apt-pkg/configuration.h>
+ 
+ using namespace std;
+ using namespace __gnu_cxx;
+diff --git a/src/desc_parse.cc b/src/desc_parse.cc
+index e4c1c3b..5bdff04 100644
+--- a/src/desc_parse.cc
++++ b/src/desc_parse.cc
+@@ -26,7 +26,6 @@
+ 
+ #include <generic/apt/apt.h>
+ #include <generic/apt/config_signal.h>
+-#include <generic/apt/tags.h>
+ 
+ #include <vscreen/fragment.h>
+ #include <vscreen/transcode.h>
+@@ -92,7 +91,7 @@ static fragment *make_level_fragment(const wstring &desc,
+ 	{
+ 	  nspaces=0;
+ 
+-	  while(loc<desc.size() && desc[loc]==L' ' && nspaces<indent)
++	  while(loc<desc.size() && (desc[loc]==L' ' || desc[loc]==L'\t') && nspaces<indent)
+ 	    {
+ 	      ++loc;
+ 	      ++nspaces;
+@@ -135,6 +134,8 @@ static fragment *make_level_fragment(const wstring &desc,
+       switch(desc[loc])
+ 	{
+ 	case L' ':
++	case L'\t':
++	  // preformatted:
+ 	  {
+ 	    // Stores the number of spaces up to a bullet, if any.
+ 	    unsigned int nspaces2=nspaces+1;
+@@ -214,7 +215,7 @@ static fragment *make_level_fragment(const wstring &desc,
+ 
+ 	      // If we hit a newline and didn't just output a whitespace
+ 	      // character, insert one.
+-	      if(loc<desc.size() && par.size()>0 && par[par.size()-1]!=' ')
++	      if(loc<desc.size() && par.size()>0 && par[par.size()-1]!=L' ')
+ 		par+=L" ";
+ 
+ 	      // Skip the newline
+@@ -226,7 +227,7 @@ static fragment *make_level_fragment(const wstring &desc,
+ 
+ 	      // Find how much indentation this line has.
+ 	      nspaces=0;
+-	      while(loc<desc.size() && desc[loc]==L' ')
++	      while(loc<desc.size() && (desc[loc]==L' ' || desc[loc]==L'\t'))
+ 		{
+ 		  ++loc;
+ 		  ++nspaces;
+@@ -258,44 +259,8 @@ fragment *make_desc_fragment(const wstring &desc)
+   wstring::size_type loc=0;
+   vector<fragment*> fragments;
+ 
+-  // Skip the short description
+-  while(loc<desc.size() && desc[loc]!=L'\n')
+-    ++loc;
+-
+-  if(loc<desc.size()) // Skip the '\n'
+-    ++loc;
+-
+-  // Skip leading whitespace on the first line if there is any.
+-  if(loc<desc.size() && desc[loc] == L' ')
+-    ++loc;
+-
+-  // Note that the starting amount of indentation is 1...
+   return make_level_fragment(desc, 0, 1, loc,
+ 			     aptcfg->FindB(PACKAGE "::Parse-Description-Bullets",
+ 					   true));
+ }
+ 
+-
+-fragment *make_tags_fragment(const pkgCache::PkgIterator &pkg)
+-{
+-  if(pkg.end())
+-    return NULL;
+-
+-  const set<tag> *s = get_tags(pkg);
+-  if(!s->empty())
+-    {
+-      vector<fragment *> tags;
+-
+-      for(set<tag>::const_iterator i = s->begin(); i != s->end(); ++i)
+-	tags.push_back(text_fragment(i->str(), style_attrs_on(A_BOLD)));
+-
+-      wstring tagstitle = transcode(_("Tags"));
+-
+-      return fragf("%ls: %F",
+-		   tagstitle.c_str(),
+-		   indentbox(0, wcswidth(tagstitle.c_str(), tagstitle.size())+2,
+-			     wrapbox(join_fragments(tags, L", "))));
+-    }
+-  else
+-    return NULL;
+-}
+diff --git a/src/desc_parse.h b/src/desc_parse.h
+index e701121..6175b05 100644
+--- a/src/desc_parse.h
++++ b/src/desc_parse.h
+@@ -34,9 +34,4 @@ class fragment;
+  */
+ fragment *make_desc_fragment(const std::wstring &desc);
+ 
+-/** \return a fragment listing the tags of the given package, or \b
+- *  NULL if there are no tags.
+- */
+-fragment *make_tags_fragment(const pkgCache::PkgIterator &pkg);
+-
+ #endif
+diff --git a/src/download_item.cc b/src/download_item.cc
+index 30ad60d..4385fa3 100644
+--- a/src/download_item.cc
++++ b/src/download_item.cc
+@@ -42,8 +42,11 @@ style download_item::get_normal_style()
+ 	return vs_treeitem::get_normal_style()+get_style("DownloadHit");
+     case pkgAcquire::Item::StatError:
+       return vs_treeitem::get_normal_style()+get_style("Error");
++// Not yet implemented in apt 0.5
++#if 0
+     case pkgAcquire::Item::StatAuthError:
+       return vs_treeitem::get_normal_style()+get_style("Error");
++#endif
+     default:
+       eassert(0);
+     }
+@@ -104,9 +107,12 @@ void download_item::paint(vs_tree *win, int y, bool hierarchical,
+     case pkgAcquire::Item::StatError:
+       output+=item.Owner->ErrorText;
+       break;
++// Not yet implemented in apt 0.5
++#if 0
+     case pkgAcquire::Item::StatAuthError:
+       output+=item.Owner->ErrorText;
+       break;
++#endif
+     }
+ 
+   win->show_string_as_progbar(0, y, transcode(output),
+diff --git a/src/edit_pkg_hier.cc b/src/edit_pkg_hier.cc
+deleted file mode 100644
+index 5b2c9d6..0000000
+--- a/src/edit_pkg_hier.cc
++++ /dev/null
+@@ -1,372 +0,0 @@
+-// edit_pkg_hier.cc
+-//
+-//   Copyright (C) 2000-2001, 2004-2006 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-
+-#include "edit_pkg_hier.h"
+-
+-#include "aptitude.h"
+-#include "ui.h"
+-
+-#include <apt-pkg/error.h>
+-
+-#include <sigc++/adaptors/bind.h>
+-#include <sigc++/functors/mem_fun.h>
+-#include <sigc++/trackable.h>
+-
+-#include <generic/apt/apt.h>
+-
+-#include <generic/util/util.h>
+-
+-#include <vscreen/config/keybindings.h>
+-#include <vscreen/vs_subtree.h>
+-#include <vscreen/transcode.h>
+-
+-using namespace std;
+-using namespace __gnu_cxx;
+-
+-// Stores a group (name) and a Y/N state
+-class vs_hier_editor::vs_hier_item:public sigc::trackable, public vs_treeitem
+-{
+-  bool selected;
+-  pkg_hier::group *group;
+-  pkg_hier::item *item;
+-  // whatever
+-  wstring group_name;
+-public:
+-  vs_hier_item(pkg_hier::group *_group, pkg_hier::item *_item)
+-    :vs_treeitem(true), group(_group), group_name(transcode(group->name, "ASCII"))
+-  {
+-    set_item(_item);
+-  }
+-
+-  bool dispatch_key(const key &k, vs_tree *owner)
+-  {
+-    if(global_bindings.key_matches(k, "PushButton") ||
+-       global_bindings.key_matches(k, "Confirm"))
+-      {
+-	selected=!selected;
+-	vscreen_update();
+-      }
+-    else
+-      return vs_treeitem::dispatch_key(k, owner);
+-
+-    return true;
+-  }
+-
+-  void dispatch_mouse(short id, int x, mmask_t bstate, vs_tree *owner)
+-  {
+-    if(bstate&BUTTON1_DOUBLE_CLICKED || bstate & BUTTON3_PRESSED ||
+-       bstate & BUTTON3_CLICKED)
+-      {
+-	selected=!selected;
+-	vscreen_update();
+-      }
+-    else
+-      vs_treeitem::dispatch_mouse(id, x, bstate, owner);
+-  }
+-
+-  void paint(vs_tree *win, int y, bool hierarchical, const style &st)
+-  {
+-    string::size_type width=win->get_width();
+-    string todisp=" ";
+-
+-    if(selected)
+-      todisp+='*';
+-    else
+-      todisp+=' ';
+-
+-    todisp+=" ";
+-    todisp+=group->name;
+-    todisp+=" : ";
+-    todisp+=group->description;
+-
+-    while(todisp.size()<width)
+-      todisp+=" ";
+-
+-    win->mvaddnstr(y, 0, transcode(todisp, "ASCII"), width);
+-  }
+-
+-  const wchar_t *tag()
+-  {
+-    return group_name.c_str();
+-  }
+-
+-  const wchar_t *label()
+-  {
+-    return group_name.c_str();
+-  }
+-
+-  void commit()
+-  {
+-    if(selected)
+-      item->parents.insert(group->name);
+-    else
+-      item->parents.erase(group->name);
+-  }
+-
+-  void set_item(pkg_hier::item *_item)
+-  {
+-    if(item!=_item)
+-      // Don't unnecessarily clobber our state.
+-      {
+-	item=_item;
+-
+-	if(item)
+-	  selected=item->parents.find(group->name)!=item->parents.end();
+-	else
+-	  selected=false;
+-      }
+-  }
+-};
+-
+-// FIXME: I shouldn't have to do this.
+-class silly_subtree:public vs_subtree_generic
+-{
+-  wstring txt;
+-public:
+-  silly_subtree(bool expanded, const wstring &_txt)
+-    :vs_subtree_generic(expanded), txt(_txt) {}
+-
+-  void paint(vs_tree *win, int y, bool hierarchical, const style &st)
+-  {
+-    vs_subtree_generic::paint(win, y, hierarchical, txt);
+-  }
+-
+-  const wchar_t *tag() {return txt.c_str();}
+-  const wchar_t *label() {return txt.c_str();}
+-};
+-
+-vs_hier_editor::vs_hier_editor():item(NULL)
+-{
+-  hier_reloaded.connect(sigc::mem_fun(*this, &vs_hier_editor::handle_reload));
+-}
+-
+-void vs_hier_editor::handle_reload()
+-{
+-  vs_widget_ref tmpref(this);
+-
+-  set_root(NULL);
+-  items.clear();
+-
+-  item=NULL;
+-
+-  set_package(pkgCache::PkgIterator(),
+-	      pkgCache::VerIterator(*apt_cache_file));
+-}
+-
+-bool vs_hier_editor::get_cursorvisible()
+-{
+-  if(!item)
+-    return false;
+-  else
+-    return true;
+-}
+-
+-void vs_hier_editor::paint(const style &st)
+-{
+-  if(!item)
+-    mvaddnstr(0, 0, _("No hierarchy information to edit"), get_width());
+-  else
+-    vs_tree::paint(st);
+-}
+-
+-// Creates a new list of edit-widgets if pkg isn't an end iterator.
+-//
+-// (yes, it would be nicer in some ways to not recreate the tree continually)
+-void vs_hier_editor::set_package(const pkgCache::PkgIterator &pkg)
+-{
+-  vs_widget_ref tmpref(this);
+-
+-  shown_conn.disconnect();
+-  if(get_visible())
+-    {
+-      pkg_hier *user_pkg_hier=get_user_pkg_hier();
+-
+-      if(user_pkg_hier && !pkg.end())
+-	{
+-	  // Get a reference to the item stored in the hierarchy, or
+-	  // create it if it isn't there.
+-	  pkg_hier::pkgmap::iterator found=user_pkg_hier->pkgs.find(pkg.Name());
+-	  item=NULL;
+-
+-	  if(found==user_pkg_hier->pkgs.end())
+-	    {
+-	      user_pkg_hier->pkgs[pkg.Name()]=pkg_hier::item(pkg.Name());
+-	      item=&user_pkg_hier->pkgs[pkg.Name()];
+-	    }
+-	  else
+-	    item=&found->second;
+-
+-	  if(items.empty())
+-	    {
+-	      silly_subtree *newroot=new silly_subtree(true, L"All groups");
+-
+-	      // Add all available groups to the list.
+-	      for(pkg_hier::groupmap::iterator i=user_pkg_hier->groups.begin();
+-		  i!=user_pkg_hier->groups.end();
+-		  ++i)
+-		{
+-		  vs_hier_item *tmp=new vs_hier_item(&i->second, item);
+-		  commit_changes.connect(sigc::mem_fun(*tmp, &vs_hier_item::commit));
+-
+-		  newroot->add_child(tmp);
+-		  items.push_back(tmp);
+-		}
+-
+-	      newroot->sort();
+-
+-	      set_root(newroot);
+-	    }
+-
+-	  for(vector<vs_hier_item *>::iterator i=items.begin();
+-	      i!=items.end(); ++i)
+-	    (*i)->set_item(item);
+-	}
+-      else
+-	item=NULL;
+-    }
+-  else
+-    {
+-      string name=pkg.end()?"":pkg.Name();
+-
+-      shown_conn=shown_sig.connect(sigc::bind(sigc::mem_fun(*this,
+-							    (void (vs_hier_editor::*) (string)) &vs_hier_editor::set_package),
+-					      name));
+-    }
+-}
+-
+-void vs_hier_editor::set_package(const pkgCache::PkgIterator &pkg,
+-				 const pkgCache::VerIterator &ver)
+-{
+-  set_package(pkg);
+-}
+-
+-void vs_hier_editor::set_package(std::string name)
+-{
+-  if(apt_cache_file)
+-    set_package((*apt_cache_file)->FindPkg(name));
+-}
+-
+-// Lets us sort stuff by name:
+-struct item_cmp
+-{
+-  bool operator()(const pkg_hier::item *a, const pkg_hier::item *b)
+-  {
+-    return a->name<b->name;
+-  }
+-};
+-
+-void vs_hier_editor::save_hier(string file)
+-{
+-  // We copy references to items into a list, then sort it (so that the
+-  // output is in a predictable order -- this makes diffs against an
+-  // autogenerated file much more useful)
+-  vector<pkg_hier::item *> items;
+-
+-  FILE *f=fopen(file.c_str(), "w");
+-
+-  if(!f)
+-    {
+-      _error->Errno("save_hier", _("Couldn't open \"%s\" for writing"), file.c_str());
+-      return;
+-    }
+-
+-  for(pkg_hier::pkgmap::iterator i=get_user_pkg_hier()->pkgs.begin();
+-      i!=get_user_pkg_hier()->pkgs.end();
+-      ++i)
+-    // Don't save items with no parents, it's pointless.
+-    if(!i->second.parents.empty())
+-      items.push_back(&i->second);
+-
+-  sort(items.begin(), items.end(), item_cmp());
+-
+-  for(vector<pkg_hier::item *>::iterator i=items.begin();
+-      i!=items.end();
+-      ++i)
+-    {
+-      string parentsstr;
+-
+-      for(hash_set<string>::iterator j=(*i)->parents.begin();
+-	  j!=(*i)->parents.end(); ++j)
+-	{
+-	  if(j==(*i)->parents.begin())
+-	    parentsstr+=*j;
+-	  else
+-	    parentsstr+=", "+*j;
+-	}
+-
+-      fprintf(f, "%sPackage: %s\nParents: %s\n",
+-	      i==items.begin()?"":"\n",
+-	      (*i)->name.c_str(), parentsstr.c_str());
+-    }
+-
+-  fclose(f);
+-}
+-
+-bool vs_hier_editor::handle_key(const key &k)
+-{
+-  if(global_bindings.key_matches(k, "SaveHier"))
+-    {
+-      string homedir = get_homedir();
+-      string cfgfile;
+-
+-      if(homedir.empty())
+-	{
+-	  show_message(_("Unable to look up your home directory, saving to /tmp/function_pkgs!"),
+-		       NULL,
+-		       get_style("Error"));
+-	  cfgfile = "/tmp/function_pkgs";
+-	}
+-      else
+-	cfgfile = homedir + "/.aptitude/function_pkgs";
+-      save_hier(cfgfile);
+-    }
+-  else if(global_bindings.key_matches(k, "Quit"))
+-    {
+-      if(item)
+-	{
+-	  item->parents.clear();
+-
+-	  for(vector<vs_hier_item *>::iterator i=items.begin();
+-	      i!=items.end(); ++i)
+-	    (*i)->commit();
+-	}
+-
+-      hide();
+-    }
+-  else if(global_bindings.key_matches(k, "Commit"))
+-    {
+-      if(item)
+-	{
+-	  item->parents.clear();
+-
+-	  for(vector<vs_hier_item *>::iterator i=items.begin();
+-	      i!=items.end(); ++i)
+-	    (*i)->commit();
+-	}
+-
+-      commit_changes();
+-    }
+-  else if(global_bindings.key_matches(k, "Abort"))
+-    hide();
+-  else
+-    return vs_tree::handle_key(k);
+-
+-  return true;
+-}
+diff --git a/src/edit_pkg_hier.h b/src/edit_pkg_hier.h
+deleted file mode 100644
+index 32de0c2..0000000
+--- a/src/edit_pkg_hier.h
++++ /dev/null
+@@ -1,83 +0,0 @@
+-// edit_pkg_hier.h           -*-c++-*-
+-//
+-//  Copyright 2001, 2005 Daniel Burrows
+-//
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-//
+-// This provides a convenient way to tweak the package hierarchy.  It lets
+-// the user select which 'groups' a package appears in, then allows them to
+-// save the changes to a file.
+-//
+-// Changes to the hierarchy are stored in GLOBAL VARIABLES.  Specifically,
+-// the user_pkg_hier global variable.
+-
+-#ifndef EDIT_PKG_HIER
+-#define EDIT_PKG_HIER
+-
+-#include <generic/apt/pkg_hier.h>
+-
+-#include <apt-pkg/pkgcache.h>
+-
+-#include <vscreen/vs_tree.h>
+-
+-class vs_hier_editor:public vs_tree
+-{
+-  class vs_hier_item;
+-
+-  // Ugh..track all the children we created..
+-  std::vector<vs_hier_item *> items;
+-
+-  pkg_hier::item *item;
+-
+-  // Used for the "lazily load package hierarchies" behavior -- if we
+-  // get a "set package" command and this widget is invisible, it gets
+-  // deferred until the widget is shown.  This connection is used to
+-  // avoid connecting this command more than once.
+-  sigc::connection shown_conn;
+-
+-  void save_hier(std::string file);
+-
+-  void handle_reload();
+-protected:
+-  virtual bool handle_key(const key &k);
+-
+-  void paint(const style &st);
+-
+-  vs_hier_editor();
+-public:
+-  static ref_ptr<vs_hier_editor> create()
+-  {
+-    ref_ptr<vs_hier_editor> rval(new vs_hier_editor);
+-    rval->decref();
+-    return rval;
+-  }
+-
+-  bool get_cursorvisible();
+-
+-  void set_package(const pkgCache::PkgIterator &pkg);
+-
+-  void set_package(const pkgCache::PkgIterator &pkg,
+-		   const pkgCache::VerIterator &ver);
+-
+-  void set_package(std::string name);
+-
+-  sigc::signal0<void> commit_changes;
+-};
+-
+-typedef ref_ptr<vs_hier_editor> vs_hier_editor_ref;
+-
+-#endif
+diff --git a/src/generic/Makefile.am b/src/generic/Makefile.am
+index ab09ccb..aceb806 100644
+--- a/src/generic/Makefile.am
++++ b/src/generic/Makefile.am
+@@ -1,3 +1,3 @@
+ MAINTAINERCLEANFILES=Makefile.in
+ 
+-SUBDIRS = util problemresolver apt
++SUBDIRS = util apt
+diff --git a/src/generic/apt/Makefile.am b/src/generic/apt/Makefile.am
+index 6353d41..8c458b8 100644
+--- a/src/generic/apt/Makefile.am
++++ b/src/generic/apt/Makefile.am
+@@ -8,7 +8,6 @@ LDADD = @LIBINTL@
+ EXTRA_DIST = README.hier
+ 
+ noinst_LIBRARIES = libgeneric-apt.a
+-noinst_PROGRAMS  = pkg_hier_dump
+ 
+ libgeneric_apt_a_SOURCES = \
+         acqprogress.cc      \
+@@ -19,10 +18,6 @@ libgeneric_apt_a_SOURCES = \
+         apt.h               \
+         aptitudepolicy.cc   \
+         aptitudepolicy.h    \
+-        aptitude_resolver.cc \
+-        aptitude_resolver.h \
+-        aptitude_resolver_universe.cc \
+-        aptitude_resolver_universe.h \
+         apt_undo_group.cc   \
+         apt_undo_group.h    \
+         config_signal.cc    \
+@@ -43,17 +38,4 @@ libgeneric_apt_a_SOURCES = \
+         matchers.h          \
+         pkg_acqfile.cc      \
+         pkg_acqfile.h       \
+-        pkg_changelog.cc    \
+-        pkg_changelog.h     \
+-        pkg_hier.cc         \
+-        pkg_hier.h          \
+-        resolver_manager.cc \
+-        resolver_manager.h  \
+-        rev_dep_iterator.h  \
+-        tags.cc             \
+-        tags.h              \
+-        tasks.cc            \
+-        tasks.h
+-
+-pkg_hier_dump_SOURCES = pkg_hier_dump.cc
+-pkg_hier_dump_LDADD = $(top_builddir)/src/generic/util/libgeneric-util.a libgeneric-apt.a
++        rev_dep_iterator.h
+diff --git a/src/generic/apt/apt.cc b/src/generic/apt/apt.cc
+index 0204332..b4cd707 100644
+--- a/src/generic/apt/apt.cc
++++ b/src/generic/apt/apt.cc
+@@ -25,11 +25,7 @@
+ 
+ 
+ #include "config_signal.h"
+-#include "pkg_hier.h"
+-#include "resolver_manager.h"
+ #include "rev_dep_iterator.h"
+-#include "tags.h"
+-#include "tasks.h"
+ 
+ #include <generic/util/undo.h>
+ #include <generic/util/util.h>
+@@ -65,8 +61,6 @@ signalling_config *aptcfg=NULL;
+ pkgRecords *apt_package_records=NULL;
+ pkgSourceList *apt_source_list=NULL;
+ undo_list *apt_undos=NULL;
+-pkg_hier *user_pkg_hier=NULL;
+-resolver_manager *resman = NULL;
+ 
+ string *pendingerr=NULL;
+ bool erroriswarning=false;
+@@ -75,7 +69,6 @@ static Configuration *theme_config;
+ static Configuration *user_config;
+ 
+ sigc::signal0<void> cache_closed, cache_reloaded, cache_reload_failed;
+-sigc::signal0<void> hier_reloaded;
+ sigc::signal0<void> consume_errors;
+ 
+ static void reset_interesting_dep_memoization()
+@@ -90,24 +83,6 @@ static void reset_surrounding_or_memoization()
+   cached_surrounding_or = NULL;
+ }
+ 
+-static void reload_user_pkg_hier()
+-{
+-  delete user_pkg_hier;
+-  user_pkg_hier=new pkg_hier;
+-
+-  user_pkg_hier->input_file(PKGDATADIR "/function_groups");
+-
+-  string cfgloc(get_homedir());
+-  if(!cfgloc.empty())
+-    {
+-      string user_hier=cfgloc+string("/.aptitude/function_pkgs");
+-      if(access(user_hier.c_str(), R_OK)==0)
+-	user_pkg_hier->input_file(user_hier);
+-      else
+-	user_pkg_hier->input_file(PKGDATADIR "/function_pkgs");
+-    }
+-}
+-
+ void apt_preinit()
+ {
+   signal(SIGPIPE, SIG_IGN);
+@@ -243,20 +218,6 @@ void apt_close_cache()
+ {
+   cache_closed();
+ 
+-  //   DANGER WILL ROBINSON!
+-  //
+-  // This must be done *** BEFORE BEFORE BEFORE *** we delete the
+-  // current cache file, since until the resolver manager is deleted,
+-  // there might actually be an active resolver thread trying to use
+-  // the cache!
+-  if(resman)
+-    {
+-      delete resman;
+-      resman = NULL;
+-    }
+-
+-  reset_tasks();
+-
+   if(apt_package_records)
+     {
+       delete apt_package_records;
+@@ -327,17 +288,6 @@ void apt_load_cache(OpProgress *progress_bar, bool do_initselections,
+   // Um, good time to clear our undo info.
+   apt_undos->clear_items();
+ 
+-  load_tasks(*progress_bar);
+-  load_tags(*progress_bar);
+-
+-  if(user_pkg_hier)
+-    {
+-      reload_user_pkg_hier();
+-      hier_reloaded();
+-    }
+-
+-  resman = new resolver_manager(*new_file);
+-
+   cache_reloaded();
+ }
+ 
+@@ -348,14 +298,6 @@ void apt_reload_cache(OpProgress *progress_bar, bool do_initselections,
+   apt_load_cache(progress_bar, do_initselections, status_fname);
+ }
+ 
+-pkg_hier *get_user_pkg_hier()
+-{
+-  if(!user_pkg_hier)
+-    reload_user_pkg_hier();
+-
+-  return user_pkg_hier;
+-}
+-
+ pkg_action_state find_pkg_state(pkgCache::PkgIterator pkg)
+ {
+   aptitudeDepCache::StateCache &state=(*apt_cache_file)[pkg];
+@@ -604,6 +546,8 @@ bool package_recommended(const pkgCache::PkgIterator &pkg)
+ 
+ bool package_trusted(const pkgCache::VerIterator &ver)
+ {
++// Not yet implemented in apt 0.5
++#if 0
+   for(pkgCache::VerFileIterator i = ver.FileList(); !i.end(); ++i)
+     {
+       pkgIndexFile *index;
+@@ -615,8 +559,8 @@ bool package_trusted(const pkgCache::VerIterator &ver)
+       else if(index->IsTrusted())
+ 	return true;
+     }
+-
+-  return false;
++#endif
++  return true;
+ }
+ 
+ /** \return \b true if d1 subsumes d2; that is, if one of the
+diff --git a/src/generic/apt/apt.h b/src/generic/apt/apt.h
+index ac2d8c7..2ca881b 100644
+--- a/src/generic/apt/apt.h
++++ b/src/generic/apt/apt.h
+@@ -32,27 +32,15 @@
+ class OpProgress;
+ class pkgRecords;
+ class pkgSourceList;
+-class pkg_hier;
+ class signalling_config;
+ class undo_list;
+-class resolver_manager;
+ 
+ // Global state variables for the apt stuff:
+ extern signalling_config *aptcfg;
+ extern aptitudeCacheFile *apt_cache_file;
+-extern resolver_manager *resman;
+ extern pkgSourceList *apt_source_list;
+ extern pkgRecords *apt_package_records;
+ 
+-pkg_hier *get_user_pkg_hier();
+-// Currently, package hierarchies are (by default) loaded using
+-// DATADIR/aptitude/hier_groups and ~/.aptitude/pkgclass.  This is to
+-// facilitate the editing of hierarchies.  user_pkg_hier contains the
+-// information which is loaded in this way.  It is accessible only
+-// through an accessor method in order to implement lazy loading (so
+-// people who don't use the browser don't take the hit of having to
+-// load in the (BIG) hierarchy info file)
+-
+ void apt_preinit();
+ // Performs initialization of stuff that has to happen before apt_init is
+ // called (eg, pkgInitialize and setting up the undo structure)
+@@ -99,10 +87,6 @@ extern sigc::signal0<void> cache_closed;
+ // This means that anyone using it should immediately drop references to it.
+ // Generally followed by cache_reloaded; always followed by cache_reloaded
+ // or cache_reload_failed.
+-extern sigc::signal0<void> hier_reloaded;
+-// Announces that user_pkg_hier has been reloaded.  (it's necessary to
+-// do this BEFORE cache_reloaded, as some things try to use the old
+-// user_pkg_hier in cache_reloaded if we don't)
+ extern sigc::signal0<void> cache_reloaded;
+ // Announces that the cache has been reloaded
+ extern sigc::signal0<void> cache_reload_failed;
+diff --git a/src/generic/apt/aptcache.cc b/src/generic/apt/aptcache.cc
+index 5289334..491e02d 100644
+--- a/src/generic/apt/aptcache.cc
++++ b/src/generic/apt/aptcache.cc
+@@ -22,11 +22,9 @@
+ #include <aptitude.h>
+ 
+ #include "apt.h"
+-#include "aptitude_resolver_universe.h"
+ #include "aptitudepolicy.h"
+ #include "config_signal.h"
+ #include "matchers.h"
+-#include <generic/problemresolver/solution.h>
+ #include <generic/util/undo.h>
+ 
+ #include <apt-pkg/error.h>
+@@ -98,7 +96,7 @@ public:
+       {
+       case ModeDelete:
+ 	// the unused_delete parameter isn't that important..
+-	owner->internal_mark_delete(pkg, prev_flags&Purge, prev_removereason==unused, NULL, false);
++	owner->internal_mark_delete(pkg, false, prev_removereason==unused, NULL, false);
+ 	break;
+       case ModeKeep:
+ 	owner->internal_mark_keep(pkg, prev_flags&AutoKept, prev_selection_state==pkgCache::State::Hold, NULL, false);
+@@ -388,6 +386,7 @@ bool aptitudeDepCache::build_selection_list(OpProgress &Prog, bool WithLock,
+ 
+ 	  MarkKeep(i, false);
+ 	  break;
++	case pkgCache::State::Purge:
+ 	case pkgCache::State::DeInstall:
+ 	  if(!do_initselections)
+ 	    break;
+@@ -395,13 +394,6 @@ bool aptitudeDepCache::build_selection_list(OpProgress &Prog, bool WithLock,
+ 	  if(!i.CurrentVer().end())
+ 	    MarkDelete(i, false);
+ 	  break;
+-	case pkgCache::State::Purge:
+-	  if(!do_initselections)
+-	    break;
+-
+-	  if(!i.CurrentVer().end())
+-	    MarkDelete(i, true);
+-	  break;
+ 	}
+ 
+       ++num;
+@@ -757,8 +749,6 @@ void aptitudeDepCache::cleanup_after_change(undo_group *undo, bool alter_stickie
+ 
+ 		  if(!pkg.CurrentVer().end())
+ 		    package_states[pkg->ID].selection_state=pkgCache::State::Install;
+-		  else if(pkg->CurrentState==pkgCache::State::NotInstalled)
+-		    package_states[pkg->ID].selection_state=pkgCache::State::Purge;
+ 		  else
+ 		    package_states[pkg->ID].selection_state=pkgCache::State::DeInstall;
+ 		  break;
+@@ -849,10 +839,10 @@ void aptitudeDepCache::internal_mark_delete(const PkgIterator &Pkg,
+ 
+   bool previously_to_delete=(*this)[Pkg].Delete();
+ 
+-  pkgDepCache::MarkDelete(Pkg, Purge);
++  pkgDepCache::MarkDelete(Pkg);
+   pkgDepCache::SetReInstall(Pkg, false);
+ 
+-  get_ext_state(Pkg).selection_state=(Purge?pkgCache::State::Purge:pkgCache::State::DeInstall);
++  get_ext_state(Pkg).selection_state=(pkgCache::State::DeInstall);
+   get_ext_state(Pkg).reinstall=false;
+ 
+   if(!previously_to_delete)
+@@ -902,12 +892,7 @@ void aptitudeDepCache::internal_mark_keep(const PkgIterator &Pkg, bool Soft, boo
+   get_ext_state(Pkg).reinstall=false;
+ 
+   if(Pkg.CurrentVer().end())
+-    {
+-      if((*this)[Pkg].iFlags&Purge)
+-	get_ext_state(Pkg).selection_state=pkgCache::State::Purge;
+-      else
+-	get_ext_state(Pkg).selection_state=pkgCache::State::DeInstall;
+-    }
++    get_ext_state(Pkg).selection_state=pkgCache::State::DeInstall;
+   else if(SetHold)
+     get_ext_state(Pkg).selection_state=pkgCache::State::Hold;
+   else
+@@ -1082,23 +1067,18 @@ bool aptitudeDepCache::all_upgrade(bool with_autoinst, undo_group *undo)
+ 
+   pre_package_state_changed();
+ 
+-  pkgProblemResolver fixer(this);
+-
+   if(BrokenCount()!=0)
+     return false;
+ 
+   for(pkgCache::PkgIterator pkg=PkgBegin(); !pkg.end(); ++pkg)
+     {
+-      if((*this)[pkg].Install())
+-	fixer.Protect(pkg);
++      (*this)[pkg].Install();
+ 
+       if(!is_held(pkg) &&
+ 	 !pkg.CurrentVer().end() && !(*this)[pkg].Install())
+ 	MarkInstall(pkg, with_autoinst);
+     }
+ 
+-  bool rval=fixer.ResolveByKeep();
+-
+   if(group_level==0)
+     {
+       mark_and_sweep(undo);
+@@ -1110,69 +1090,7 @@ bool aptitudeDepCache::all_upgrade(bool with_autoinst, undo_group *undo)
+       package_state_changed();
+     }
+ 
+-  return rval;
+-}
+-
+-bool aptitudeDepCache::try_fix_broken(pkgProblemResolver &fixer, undo_group *undo)
+-{
+-  if(read_only && !read_only_permission())
+-    {
+-      if(group_level == 0)
+-	read_only_fail();
+-      return false;
+-    }
+-
+-  pre_package_state_changed();
+-  dirty=true;
+-  bool founderr=false;
+-  if(!fixer.Resolve(true))
+-    founderr=true;
+-
+-  if(founderr)
+-    _error->Error(_("Unable to correct dependencies, some packages cannot be installed"));
+-
+-  if(group_level==0)
+-    {
+-      mark_and_sweep(undo);
+-
+-      cleanup_after_change(undo);
+-
+-      duplicate_cache(&backup_state);
+-
+-      package_state_changed();
+-    }
+-
+-  return !founderr;
+-}
+-
+-bool aptitudeDepCache::try_fix_broken(undo_group *undo)
+-{
+-  if(read_only && !read_only_permission())
+-    {
+-      if(group_level == 0)
+-	read_only_fail();
+-      return false;
+-    }
+-
+-  pkgProblemResolver fixer(this);
+-  pre_package_state_changed();
+-  for(pkgCache::PkgIterator i=PkgBegin(); !i.end(); i++)
+-    {
+-      fixer.Clear(i);
+-      if(!i.CurrentVer().end() &&
+-	 get_ext_state(i).selection_state==pkgCache::pkgCache::State::Hold)
+-	fixer.Protect(i);
+-      else
+-	{
+-	  pkgDepCache::StateCache &state=(*this)[i];
+-	  if(state.InstBroken() || state.NowBroken())
+-	    MarkInstall(i,true);
+-	  else if(state.Delete())
+-	    fixer.Remove(i);
+-	}
+-    }
+-
+-  return try_fix_broken(fixer, undo);
++  return true;
+ }
+ 
+ /** Update the given package's aptitude state based on its state
+@@ -1198,11 +1116,6 @@ void aptitudeDepCache::MarkFromDselect(const PkgIterator &Pkg)
+ 	case pkgCache::State::Unknown:
+ 	  break;
+ 	case pkgCache::State::Purge:
+-	  if( (!Pkg.CurrentVer().end()) || !((*this)[Pkg].iFlags&Purge) )
+-	    mark_delete(Pkg, true, false, NULL);
+-	  else
+-	    mark_keep(Pkg, false, false, NULL);
+-	  break;
+ 	case pkgCache::State::DeInstall:
+ 	  if(!Pkg.CurrentVer().end())
+ 	    mark_delete(Pkg, false, false, NULL);
+@@ -1516,7 +1429,7 @@ void aptitudeDepCache::mark_and_sweep(undo_group *undo)
+ 
+ 	      if(do_delete)
+ 		mark_delete(p,
+-			    aptcfg->FindB(PACKAGE "::Purge-Unused", false),
++			    false,
+ 			    true,
+ 			    undo);
+ 	    }
+@@ -1534,50 +1447,6 @@ void aptitudeDepCache::mark_and_sweep(undo_group *undo)
+   end_action_group(undo);
+ }
+ 
+-void aptitudeDepCache::apply_solution(const generic_solution<aptitude_universe> &sol,
+-				      undo_group *undo)
+-{
+-  if(read_only && !read_only_permission())
+-    {
+-      if(group_level == 0)
+-	read_only_fail();
+-      return;
+-    }
+-
+-  begin_action_group();
+-
+-  for(imm::map<aptitude_resolver_package, generic_solution<aptitude_universe>::action>::const_iterator
+-	i = sol.get_actions().begin();
+-      i != sol.get_actions().end(); ++i)
+-    {
+-      pkgCache::PkgIterator pkg=i->first.get_pkg();
+-      pkgCache::VerIterator curver=pkg.CurrentVer();
+-      pkgCache::VerIterator actionver=i->second.ver.get_ver();
+-
+-      // Check what type of action it is.
+-      if(actionver.end())
+-	{
+-	  // removal.
+-	  internal_mark_delete(pkg, false, false, undo, false);
+-	  if(!curver.end())
+-	    get_ext_state(pkg).remove_reason=from_resolver;
+-	}
+-      else if(actionver == curver)
+-	// keep
+-	internal_mark_keep(pkg, false, false, undo, false);
+-      else
+-	// install a particular version that's not the current one.
+-	{
+-	  set_candidate_version(actionver, undo);
+-	  internal_mark_install(pkg, false, false, undo, false);
+-	  if(curver.end())
+-	    get_ext_state(pkg).install_reason=from_resolver;
+-	}
+-    }
+-
+-  end_action_group(undo);  
+-}
+-
+ aptitudeCacheFile::aptitudeCacheFile()
+   :Map(NULL), Cache(NULL), DCache(NULL), have_system_lock(false), Policy(NULL)
+ {
+diff --git a/src/generic/apt/aptcache.h b/src/generic/apt/aptcache.h
+index 12f779f..f25f0a7 100644
+--- a/src/generic/apt/aptcache.h
++++ b/src/generic/apt/aptcache.h
+@@ -42,9 +42,6 @@
+ 
+ class undoable;
+ class undo_group;
+-class pkgProblemResolver;
+-class aptitude_universe;
+-template<typename PackageUniverse> class generic_solution;
+ 
+ class aptitudeDepCache:public pkgDepCache, public sigc::trackable
+ {
+@@ -209,17 +206,6 @@ private:
+   apt_state_snapshot backup_state;
+   // Stores what the cache was like just before an action was performed
+ 
+-  /** Call whenever the cache state is modified; discards the
+-   *  state of the active resolver.
+-   *
+-   *  \param undo the undo group with which this discarding should be
+-   *  associated.
+-   */
+-  void discard_resolver(undo_group *undo);
+-
+-  /** Call whenever a new resolver should be instantiated. */
+-  void create_resolver();
+-
+   undoable *state_restorer(PkgIterator pkg, StateCache &state, aptitude_state &ext_state);
+   // Returns an 'undoable' object which will restore the given package to the
+   // given state via {Mark,Set}* routines
+@@ -360,13 +346,6 @@ public:
+    */
+   void set_read_only(bool new_read_only);
+ 
+-  /** Apply the given solution as a resolver result; any actions
+-   *  that it requests will be marked as having been performed to
+-   *  fulfill dependencies.
+-   */
+-  void apply_solution(const generic_solution<aptitude_universe> &solution,
+-		      undo_group *undo);
+-
+   /** \return \b true if automatic aptitude upgrades should ignore this
+    *  package.
+    */
+@@ -375,14 +354,6 @@ public:
+   bool all_upgrade(bool with_autoinst, undo_group *undo);
+   // Wrapper for pkgAllUpgrade (the engine of "apt-get upgrade")
+ 
+-  bool try_fix_broken(undo_group *undo);
+-  // Attempts to fix any broken packages, dumping the changes the problem
+-  // fixer creates into the given undo group.
+-
+-  bool try_fix_broken(pkgProblemResolver &fixer, undo_group *undo);
+-  // Just runs the resolver given and catches automatic changes.
+-  // (this lets callers customize the information given to the resolver)
+-
+   const apt_state_snapshot *snapshot_apt_state();
+   // Returns the current state of the *APT* cache (no information about
+   // Aptitude states is included); this is meant to be used to implement undo,
+diff --git a/src/generic/apt/aptitude_resolver.cc b/src/generic/apt/aptitude_resolver.cc
+deleted file mode 100644
+index 5f18b4a..0000000
+--- a/src/generic/apt/aptitude_resolver.cc
++++ /dev/null
+@@ -1,172 +0,0 @@
+-// aptitude_resolver.cc
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#include "aptitude_resolver.h"
+-
+-#include "config_signal.h"
+-
+-aptitude_resolver::aptitude_resolver(int step_score,
+-				     int broken_score,
+-				     int unfixed_soft_score,
+-				     int infinity,
+-				     int max_successors,
+-				     int resolution_score,
+-				     aptitudeDepCache *cache)
+-  :generic_problem_resolver<aptitude_universe>(step_score, broken_score, unfixed_soft_score, infinity, max_successors, resolution_score, aptitude_universe(cache))
+-{
+-  set_remove_stupid(aptcfg->FindB(PACKAGE "::ProblemResolver::Remove-Stupid-Pairs", true));
+-
+-  if(aptcfg->FindB(PACKAGE "::ProblemResolver::Discard-Null-Solution", true))
+-    {
+-      imm::map<package, action> null_solution;
+-
+-      for(pkgCache::PkgIterator i = cache->PkgBegin(); !i.end(); ++i)
+-	{
+-	  pkgDepCache::StateCache &s((*cache)[i]);
+-
+-	  if(!s.Keep())
+-	    null_solution.put(package(i, cache),
+-			      action(version(i, i.CurrentVer(), cache),
+-				     dep(), false, 0));
+-	}
+-
+-      if(!null_solution.empty())
+-	add_conflict(null_solution);
+-    }
+-}
+-
+-void aptitude_resolver::add_action_scores(int preserve_score, int auto_score,
+-					  int remove_score, int keep_score,
+-					  int install_score, int upgrade_score,
+-					  int non_default_score, int essential_remove,
+-					  int break_hold_score)
+-{
+-  // Should I stick with APT iterators instead?  This is a bit more
+-  // convenient, though..
+-  for(aptitude_universe::package_iterator pi = get_universe().packages_begin();
+-      !pi.end(); ++pi)
+-    {
+-      const aptitude_universe::package &p=*pi;
+-      aptitudeDepCache::aptitude_state &state=get_universe().get_cache()->get_ext_state(p.get_pkg());
+-
+-      // Packages are considered "manual" if either they were manually
+-      // installed, or if they are currently installed and were
+-      // manually removed.
+-      //
+-      // There is NO PENALTY for any change to a non-manual package's
+-      // state, other than the usual priority-based and non-default
+-      // version weighting.
+-      bool manual = ((!p.current_version().get_ver().end()) && state.install_reason == aptitudeDepCache::manual) ||
+-	(p.current_version().get_ver().end() && (p.get_pkg().CurrentVer().end() || state.remove_reason == aptitudeDepCache::manual));
+-
+-      for(aptitude_universe::package::version_iterator vi=p.versions_begin(); !vi.end(); ++vi)
+-	{
+-	  aptitude_universe::version v=*vi;
+-
+-	  // Remember, the "current version" is the InstVer.
+-	  if(v==p.current_version())
+-	    {
+-	      if(manual)
+-		add_version_score(v, preserve_score);
+-	      else
+-		add_version_score(v, auto_score);
+-	    }
+-	  // Ok, if this version is selected it'll be a change.
+-	  else if(v.get_ver()==p.get_pkg().CurrentVer())
+-	    {
+-	      if(manual)
+-		add_version_score(v, keep_score);
+-	    }
+-	  else if(v.get_ver().end())
+-	    {
+-	      if(manual)
+-		add_version_score(v, remove_score);
+-	    }
+-	  else if(v.get_ver()==(*get_universe().get_cache())[p.get_pkg()].CandidateVerIter(*get_universe().get_cache()))
+-	    {
+-	      if(manual)
+-		{
+-		  // Could try harder not to break holds.
+-		  if(p.get_pkg().CurrentVer().end())
+-		    add_version_score(v, install_score);
+-		  else
+-		    add_version_score(v, upgrade_score);
+-		}
+-
+-	      if(!p.get_pkg().CurrentVer().end() &&
+-		 (state.selection_state == pkgCache::State::Hold ||
+-		  state.forbidver == v.get_ver().VerStr()))
+-		add_version_score(v, break_hold_score);
+-	    }
+-	  else
+-	    // We know that:
+-	    //  - this version wasn't requrested by the user
+-	    //  - it's not the current version
+-	    //  - it's not the candidate version
+-	    //  - it's not a removal
+-	    //  - it follows that this is a non-default version.
+-	    add_version_score(v, non_default_score);
+-
+-	  // In addition, add the essential-removal score:
+-	  if((p.get_pkg()->Flags & pkgCache::Flag::Essential) &&
+-	     v.get_ver().end())
+-	    add_version_score(v, essential_remove);
+-	}
+-    }
+-}
+-
+-void aptitude_resolver::add_priority_scores(int important,
+-					    int required,
+-					    int standard,
+-					    int optional,
+-					    int extra)
+-{
+-  for(aptitude_universe::package_iterator pi = get_universe().packages_begin();
+-      !pi.end(); ++pi)
+-    for(aptitude_universe::package::version_iterator vi=(*pi).versions_begin(); !vi.end(); ++vi)
+-      {
+-	if(vi.get_ver().end())
+-	  continue;
+-
+-	int score_tweak=0;
+-	switch(vi.get_ver()->Priority)
+-	  {
+-	  case pkgCache::State::Important:
+-	    score_tweak=important;
+-	    break;
+-	  case pkgCache::State::Required:
+-	    score_tweak=required;
+-	    break;
+-	  case pkgCache::State::Standard:
+-	    score_tweak=standard;
+-	    break;
+-	  case pkgCache::State::Optional:
+-	    score_tweak=optional;
+-	    break;
+-	  case pkgCache::State::Extra:
+-	    score_tweak=extra;
+-	    break;
+-	  default:
+-	    // ??????
+-	    break;
+-	  }
+-
+-	add_version_score(*vi, score_tweak);
+-      }
+-}
+diff --git a/src/generic/apt/aptitude_resolver.h b/src/generic/apt/aptitude_resolver.h
+deleted file mode 100644
+index d44dbb3..0000000
+--- a/src/generic/apt/aptitude_resolver.h
++++ /dev/null
+@@ -1,107 +0,0 @@
+-// aptitude_resolver.h                  -*-c++-*-
+-//
+-// 
+-//   Copyright (C) 2005 Daniel Burrows
+-
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-//
+-// Glue code to make the resolver talk to the core aptitude classes.
+-//
+-// shootshootshoot...maybe I should just teach the core about
+-// conflicts...anyway, if not, then I need to be much more careful how
+-// I iterate over conflicts if an OR is involved (it should be
+-// basically ignored)
+-//
+-// General comment on how the iterators are handled: basically the
+-// technique is (generally) to have a normalize() routine that
+-// advances the current iterator(s) to the next "interesting"
+-// iterator.  For instance, broken_dep_iterator::normalize() moves to
+-// the next broken dependency (sort of).  If the current iterator is
+-// already interesting, nothing happens.  This is used on
+-// initialization and in operator++ (after advancing the iterator a
+-// single step manually).
+-
+-#ifndef APTITUDE_RESOLVER_H
+-#define APTITUDE_RESOLVER_H
+-
+-#include "aptitude_resolver_universe.h"
+-
+-#include <generic/problemresolver/problemresolver.h>
+-
+-class aptitude_resolver:public generic_problem_resolver<aptitude_universe>
+-{
+-public:
+-  aptitude_resolver(int step_score, int broken_score,
+-		    int unfixed_soft_score,
+-		    int infinity, int max_successors,
+-		    int resolution_score,
+-		    aptitudeDepCache *cache);
+-
+-  /** Assign scores to all packages and all package versions according
+-   *  to its arguments.  All scores are assigned with add_score, so
+-   *  this can be easily combined with other policies.
+-   *
+-   * \param preserve_score the score to assign to the version that the
+-   * user selected.
+-   *
+-   * \param auto_score the score to assign to automatically assigned
+-   * actions.  By making this smaller than preserve_score you can bias
+-   * the system towards overriding automatic decisions rather than
+-   * user actions.
+-   *
+-   * \param remove_score the score to assign to removing a package
+-   * against the user's wishes.
+-   *
+-   * \param keep_score the score to assign to cancelling actions on a
+-   * package against the user's wishes.
+-   *
+-   * \param install_score the score to assign to removing a package
+-   * against the user's wishes.
+-   *
+-   * \param upgrade_score the score to assign to upgrading a package
+-   * against the user's wishes.
+-   *
+-   * \param non_default_score the score to assign to installing a
+-   * non-default version of a package (such as a downgrade or an
+-   * experimental version).
+-   *
+-   * \param essential_remove an additional modification applied to the
+-   * removal of an essential package (typically used to deep-six such
+-   * solutions by, eg, setting it to -100000)
+-   *
+-   * \param break_hold_score an additional modification applied to
+-   * solutions that break a hold or violate a forbidding.
+-   */
+-  void add_action_scores(int preserve_score, int auto_score,
+-			 int remove_score, int keep_score,
+-			 int install_score, int upgrade_score,
+-			 int non_default_score, int essential_remove,
+-			 int break_hold_score);
+-
+-  /** Score packages/versions according to their priorities.  Normally
+-   *  you want important>=required>=standard>=optional>=extra.
+-   *
+-   *  \param important score modification for Important versions
+-   *  \param required score modification for Required versions
+-   *  \param standard score modification for Standard versions
+-   *  \param optional score modification for Optional versions
+-   *  \param extra score modification for Extra versions
+-   */
+-  void add_priority_scores(int important, int required, int standard,
+-			   int optional, int extra);
+-};
+-
+-#endif
+diff --git a/src/generic/apt/aptitude_resolver_universe.cc b/src/generic/apt/aptitude_resolver_universe.cc
+deleted file mode 100644
+index 962e174..0000000
+--- a/src/generic/apt/aptitude_resolver_universe.cc
++++ /dev/null
+@@ -1,589 +0,0 @@
+-// aptitude_resolver_universe.cc                       -*-c++-*-
+-
+-#include "aptitude_resolver_universe.h"
+-
+-#include <generic/problemresolver/solution.h>
+-
+-#include <sstream>
+-
+-using namespace std;
+-
+-static inline
+-bool ver_disappeared(const pkgCache::VerIterator ver)
+-{
+-  return
+-    !ver.Downloadable() &&
+-    (ver != ver.ParentPkg().CurrentVer() ||
+-     ver.ParentPkg()->CurrentState == pkgCache::State::ConfigFiles);
+-}
+-
+-
+-string aptitude_resolver_version::get_name() const
+-{
+-  if(!ver.end())
+-    {
+-      // If there are two distinct package files with the same
+-      // Version, apt will give them the same VerStr.  Detect and
+-      // compensate for this.
+-      int count=0;
+-      int idx=-1;
+-
+-      for(pkgCache::VerIterator i=pkg.VersionList(); !i.end(); ++i)
+-	{
+-	  if(i==ver)
+-	    {
+-	      idx=count;
+-	      ++count;
+-	    }
+-	  else if(!strcmp(i.VerStr(), ver.VerStr()))
+-	    ++count;
+-	}
+-
+-      // if not, we have a "version" of this package that's not in
+-      // its list of versions!
+-      eassert(idx>=0);
+-
+-      if(count>1)
+-	{
+-	  ostringstream s;
+-	  s << ver.VerStr() << "<" << idx+1 << ">";
+-	  return s.str();
+-	}
+-      else
+-	return ver.VerStr();
+-    }
+-  else
+-    // Note that this is an invalid version string for apt, so we
+-    // can't clash with real versions.
+-    return "[UNINST]";
+-}
+-
+-bool aptitude_resolver_version::revdep_iterator::applicable() const
+-{
+-  if(!is_interesting_dep(dep_lst, cache))
+-    return false;
+-
+-  // Unversioned deps always apply.
+-  if(!dep_lst.TargetVer())
+-    return true;
+-
+-  if(provides_open)
+-    return _system->VS->CheckDep(prv_lst.ProvideVersion(),
+-				 dep_lst->CompareOp, dep_lst.TargetVer());
+-  else
+-    return _system->VS->CheckDep(ver.VerStr(),
+-				 dep_lst->CompareOp, dep_lst.TargetVer());
+-}
+-
+-void aptitude_resolver_version::revdep_iterator::normalize()
+-{
+-  while(!dep_lst.end() && !applicable())
+-    ++dep_lst;
+-
+-  if(dep_lst.end() && !provides_open)
+-    {
+-      eassert(prv_lst.end());
+-      prv_lst=ver.ProvidesList();
+-      provides_open=true;
+-      if(!prv_lst.end())
+-	{
+-	  dep_lst=prv_lst.ParentPkg().RevDependsList();
+-	  while(!dep_lst.end() && !applicable())
+-	    ++dep_lst;
+-	}
+-    }
+-
+-  // When we've run out of provides, give up..
+-  while(dep_lst.end() && !prv_lst.end())
+-    {
+-      eassert(provides_open);
+-      ++prv_lst;
+-
+-      if(!prv_lst.end())
+-	{
+-	  eassert(!prv_lst.ParentPkg().end());
+-	  dep_lst=prv_lst.ParentPkg().RevDependsList();
+-
+-	  while(!dep_lst.end() && !applicable())
+-	    ++dep_lst;
+-	}
+-    }
+-}
+-
+-void aptitude_resolver_version::dep_iterator::normalize()
+-{
+-  if(prv_open)
+-    {
+-      eassert(!dep.end());
+-      eassert(dep->Type == pkgCache::Dep::Conflicts);
+-
+-      while(!prv.end() && prv.OwnerPkg()==dep.ParentPkg())
+-	++prv;
+-
+-      if(prv.end())
+-	{
+-	  prv_open=false;
+-	  ++dep;
+-	}
+-      else
+-	return;
+-    }
+-
+-  eassert(!prv_open);
+-
+-
+-  // Skip non-critical and self dependencies.  Need to do this here
+-  // as well as below in case dep already points to such a
+-  // dependency.
+-  while(!dep.end() &&
+-	(dep.ParentPkg() == dep.TargetPkg() ||
+-	 !is_interesting_dep(dep, cache)))
+-    ++dep;
+-
+-  // If we ran out of deps, we're done!
+-}
+-
+-
+-
+-void aptitude_resolver_dep::solver_iterator::normalize()
+-{
+-  if(dep_lst->Type != pkgCache::Dep::Conflicts)
+-    {
+-      while(!end())
+-	{
+-	  while(!ver_lst.end())
+-	    {
+-	      bool ver_matches =
+-		!dep_lst.TargetVer() ||
+-		_system->VS->CheckDep(ver_lst.VerStr(),
+-				      dep_lst->CompareOp,
+-				      dep_lst.TargetVer());
+-
+-	      if(ver_matches && ver_disappeared(ver_lst))
+-		ver_matches = false;
+-
+-	      if(ver_matches)
+-		// Found the next entry; drop out.
+-		return;
+-	      else
+-		++ver_lst;
+-	    }
+-
+-	  // If we ran out of versions, try provides instead.
+-	  while(!prv_lst.end())
+-	    {
+-	      bool prv_matches=(!dep_lst.TargetVer()) ||
+-		(prv_lst.ProvideVersion() &&
+-		 _system->VS->CheckDep(prv_lst.ProvideVersion(),
+-				       dep_lst->CompareOp,
+-				       dep_lst.TargetVer()));
+-
+-	      if(prv_matches &&
+-		 !ver_disappeared(prv_lst.OwnerVer()))
+-		return;
+-	      else
+-		++prv_lst;
+-	    }
+-
+-	  // No more target versions or providers of the target;
+-	  // increment the dependency list if we aren't yet at the
+-	  // end of the OR group.
+-
+-	  if(!(dep_lst->CompareOp & pkgCache::Dep::Or))
+-	    finished=true;
+-	  else
+-	    {
+-	      ++dep_lst;
+-	      // Since we aren't finished, dep_lst should still be
+-	      // valid.
+-	      eassert(!dep_lst.end());
+-	      ver_lst=dep_lst.TargetPkg().VersionList();
+-
+-	      // Only set the prv_lst to non-end if there is no target
+-	      // version.
+-	      prv_lst=dep_lst.TargetPkg().ProvidesList();
+-	    }
+-	}
+-    }
+-  else
+-    {
+-      // For Conflicts, we're iterating over all the versions of
+-      // *one* package for *one* dep, either the owner of the
+-      // dep or a provided package.  (prv_lst is mostly
+-      // unnecessary, but it makes it simple to remember whether
+-      // we have a provides).  Note that the efficiency of this
+-      // stanza is based on the *assumption* that most packages
+-      // only Provide a few things.
+-
+-      // For provided packages, return exactly those packages
+-      // that *don't* have a matching Provides.
+-      if(!prv_lst.end())
+-	{
+-	  while(!ver_lst.end())
+-	    {
+-	      if(ver_lst != prv_lst.OwnerVer() &&
+-		 !ver_disappeared(ver_lst))
+-		return;
+-
+-	      ++ver_lst;
+-	    }
+-	  // Important point: end version iterators always match
+-	  // a Conflicts! (i.e., any Conflicts can be resolved
+-	  // by removing the conflicted package)
+-	  return;
+-	}
+-      else
+-	{
+-	  while(!ver_lst.end())
+-	    {
+-	      bool ver_matches=(!dep_lst.TargetVer()) ||
+-		(ver_lst.VerStr() &&
+-		 _system->VS->CheckDep(ver_lst.VerStr(),
+-				       dep_lst->CompareOp,
+-				       dep_lst.TargetVer()));
+-
+-	      if(!ver_matches && !ver_disappeared(ver_lst))
+-		// This version resolves the conflict.
+-		return;
+-	      else
+-		++ver_lst;
+-	    }
+-
+-	  // Ignore provides; as above, end versions are A-OK.
+-	  return;
+-	}
+-    }
+-}
+-
+-bool aptitude_resolver_dep::solved_by(const aptitude_resolver_version &v) const
+-{
+-  // First check for moving the source.
+-  if(v.get_pkg() == const_cast<pkgCache::DepIterator &>(start).ParentPkg() && v.get_ver() != const_cast<pkgCache::DepIterator &>(start).ParentVer())
+-    return true;
+-
+-  // Now check each of the members of the OR group.
+-  pkgCache::DepIterator d = start;
+-
+-  if(start->Type != pkgCache::Dep::Conflicts)
+-    {
+-      // Of course, installing an end version never fixes a
+-      // non-conflict unless it removes the source (tested for above).
+-      if(v.get_ver().end())
+-	return false;
+-
+-      while(1)
+-	{
+-	  if(d.TargetPkg() == v.get_pkg() &&
+-	     (!d.TargetVer() || _system->VS->CheckDep(v.get_ver().VerStr(),
+-						      d->CompareOp,
+-						      d.TargetVer())))
+-	    return true;
+-
+-	  // Check for a resolution via Provides.
+-	  if(!d.TargetVer())
+-	    for(pkgCache::PrvIterator p2 = v.get_ver().ProvidesList();
+-		!p2.end(); ++p2)
+-	      if(const_cast<pkgCache::PrvIterator &>(p2).ParentPkg() == d.TargetPkg())
+-		return true;
+-
+-	  if((d->CompareOp & pkgCache::Dep::Or) != 0)
+-	    ++d;
+-	  else
+-	    return false;
+-	}
+-    }
+-  else if(prv.end())
+-    {
+-      if(d.TargetPkg() != v.get_pkg())
+-	return false;
+-
+-      if(v.get_ver().end())
+-	return true;
+-
+-      // Check the non-virtual part of the conflict: the package is
+-      // the same and the version **doesn't** match.
+-      return !(!d.TargetVer() || _system->VS->CheckDep(v.get_ver().VerStr(),
+-						       d->CompareOp,
+-						       d.TargetVer()));
+-    }
+-  else
+-    {
+-      // Only other versions of the provider can solve this.
+-      if(v.get_pkg() != const_cast<pkgCache::PrvIterator &>(prv).OwnerPkg())
+-	return false;
+-      else
+-	return v.get_ver() != const_cast<pkgCache::PrvIterator &>(prv).OwnerVer();
+-    }
+-}
+-
+-aptitude_resolver_dep::solver_iterator &aptitude_resolver_dep::solver_iterator::operator++()
+-{
+-  eassert(!end());
+-
+-  // Advance whatever needs to be advanced next in the
+-  // sub-list.
+-
+-  if(!ver_lst.end())
+-    ++ver_lst;
+-  else if(dep_lst->Type != pkgCache::Dep::Conflicts)
+-    {
+-      if(!prv_lst.end())
+-	++prv_lst;
+-    }
+-  else
+-    finished=true;
+-
+-  normalize();
+-
+-  return *this;
+-}
+-
+-aptitude_resolver_version::dep_iterator &aptitude_resolver_version::dep_iterator::operator++()
+-{
+-  eassert(!dep.end());
+-
+-  // If the Provides list is nonempty, advance it.
+-  if(!prv.end())
+-    ++prv;
+-  // If we weren't trying to iterate over a Provides list *and* the
+-  // current dep is a non-versioned Conflicts, start such an
+-  // iteration.
+-  else if(!prv_open && dep->Type == pkgCache::Dep::Conflicts &&
+-	  !dep.TargetVer())
+-    {
+-      prv_open=true;
+-      prv=dep.TargetPkg().ProvidesList();
+-    }
+-  // Otherwise push on to the next top-level dep.
+-  else
+-    {
+-      if(!dep.end() && dep->Type == pkgCache::Dep::Conflicts)
+-	++dep;
+-      else
+-	{
+-	  // If it's not a conflict, skip a whole OR group.
+-	  while(!dep.end() && (dep->CompareOp & pkgCache::Dep::Or))
+-	    ++dep;
+-
+-	  // Now we're on the last element of the OR group, push
+-	  // forward.
+-	  if(!dep.end())
+-	    ++dep;
+-	}
+-    }
+-
+-  normalize();
+-
+-  return *this;
+-}
+-
+-aptitude_resolver_version aptitude_resolver_dep::solver_iterator::operator*() const
+-{
+-  eassert(!end());
+-
+-  if(!ver_lst.end())
+-    return aptitude_resolver_version(ver_lst.ParentPkg(),ver_lst,cache);
+-  else // In this case we're trying to remove some package or other.
+-    {
+-      if(dep_lst->Type != pkgCache::Dep::Conflicts)
+-	{
+-	  // Assume this because otherwise end() should be true.
+-	  eassert(!prv_lst.end());
+-
+-	  return aptitude_resolver_version(const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerPkg(),const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerVer(),cache);
+-	}
+-      else if(!prv_lst.end())
+-	return aptitude_resolver_version(const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerPkg(),ver_lst,cache);
+-      else
+-	return aptitude_resolver_version(const_cast<pkgCache::DepIterator &>(dep_lst).TargetPkg(),ver_lst,cache);
+-    }
+-}
+-
+-void aptitude_universe::dep_iterator::normalize()
+-{
+-  while(dep.end() && !pkg.end())
+-    {
+-      while(dep.end() && !ver.end())
+-	{
+-	  ++ver;
+-	  if(!ver.end())
+-	    dep=aptitude_resolver_version::dep_iterator(ver, cache);
+-	}
+-
+-      if(dep.end())
+-	{
+-	  ++pkg;
+-	  if(!pkg.end())
+-	    {
+-	      ver=pkg.VersionList();
+-	      if(!ver.end())
+-		dep=aptitude_resolver_version::dep_iterator(ver, cache);
+-	    }
+-	}
+-    }
+-}
+-
+-bool aptitude_universe::broken_dep_iterator::dep_is_inst_broken(const pkgCache::DepIterator &d) const
+-{
+-  pkgCache::DepIterator d2=d;
+-
+-  while(d2->CompareOp & pkgCache::Dep::Or)
+-    ++d2;
+-
+-  return ((*cache)[d2] & pkgDepCache::DepGInstall)==0;
+-}
+-
+-void aptitude_universe::broken_dep_iterator::normalize()
+-{
+-  while(!the_dep.end() &&
+-	!(is_interesting_dep(the_dep, cache) &&
+-	  dep_is_inst_broken(the_dep)))
+-    ++the_dep;
+-
+-  while(the_dep.end() && !pkg.end())
+-    {
+-      // Make sure we move at least one package forward!
+-      // Otherwise we just spin on the same package over and over,
+-      // since it's still broken..
+-      ++pkg;
+-
+-      if(!pkg.end())
+-	{
+-	  // Examine just the InstVer of the package.
+-	  pkgCache::VerIterator ver=(*cache)[pkg].InstVerIter(*cache);
+-
+-	  if(!ver.end())
+-	    the_dep=ver.DependsList();
+-
+-	  while(!the_dep.end() &&
+-		!(is_interesting_dep(the_dep, cache) &&
+-		  dep_is_inst_broken(the_dep)))
+-	    ++the_dep;
+-
+-	  if(the_dep.end())
+-	    ++ver;
+-	}
+-    }
+-
+-  eassert(the_dep.end() || is_interesting_dep(the_dep, cache));
+-
+-  // Now dep is a broken critical dep or an end dep.  If it is a
+-  // conflicts, we might need to push down into Provides...
+-  if(!the_dep.end() && the_dep->Type == pkgCache::Dep::Conflicts)
+-    {
+-      // If we aren't in provides, check whether the dep is
+-      // trivially broken (i.e., without following provides).
+-      if(!prv_open)
+-	{
+-	  // If it's a direct self-conflict, jump into provides
+-	  // right away.
+-	  if(the_dep.TargetPkg() != the_dep.ParentPkg())
+-	    {
+-	      pkgCache::VerIterator ver=(*cache)[the_dep.TargetPkg()].InstVerIter(*cache);
+-
+-	      if(!ver.end() &&
+-		 !ver_disappeared(ver) &&
+-		 (!the_dep.TargetVer() ||
+-		  (ver.VerStr() &&
+-		   _system->VS->CheckDep(ver.VerStr(),
+-					 the_dep->CompareOp,
+-					 the_dep.TargetVer()))))
+-		// OK, the dep is broken without provides, no need
+-		// to descend.
+-		return;
+-	    }
+-
+-	  prv_open=true;
+-	  prv=the_dep.TargetPkg().ProvidesList();
+-	}
+-
+-      // Ok, we have found something that causes breakage.  The
+-      // provides-list is a list of all the package versions that
+-      // provide this package name; move forward until we find one
+-      // that matches.
+-      while(!prv.end())
+-	{
+-	  // Ignore indirect self-conflicts.
+-	  if(prv.OwnerPkg() != the_dep.ParentPkg())
+-	    {
+-	      // First, is the providing version going to be
+-	      // installed?
+-	      if((*cache)[prv.OwnerPkg()].InstVerIter(*cache) == prv.OwnerVer())
+-		{
+-		  // Ok, does it match the version string?
+-		  bool matches =
+-		    !the_dep.TargetVer() ||
+-		    (prv.ProvideVersion() &&
+-		     _system->VS->CheckDep(prv.ProvideVersion(),
+-					   the_dep->CompareOp,
+-					   the_dep.TargetVer()));
+-
+-		  if(ver_disappeared(prv.OwnerVer()))
+-		    matches = false;
+-
+-		  if(matches)
+-		    return;
+-		}
+-	    }
+-
+-	  ++prv;
+-	}
+-
+-      // if all provides are exhausted, increment the dep and try
+-      // again.  (probably this was only a self-conflict and
+-      // nothing else)
+-      ++the_dep;
+-      prv_open=false;
+-      normalize();
+-      // hopefully g++ is smart enough to optimize this into a
+-      // tail call.
+-      return;
+-    }
+-}
+-
+-aptitude_universe::broken_dep_iterator &aptitude_universe::broken_dep_iterator::operator++()
+-{
+-  eassert(!pkg.end());
+-  // If the_dep.end() we have pkg.end().
+-  eassert(!the_dep.end());
+-
+-  if(!prv_open && the_dep->Type == pkgCache::Dep::Conflicts)
+-    {
+-      prv_open = true;
+-      prv = the_dep.TargetPkg().ProvidesList();
+-    }
+-  else if(prv_open && !prv.end())
+-    ++prv;
+-  else
+-    ++the_dep;
+-
+-  normalize();
+-  return *this;
+-}
+-
+-std::ostream &operator<<(ostream &out, aptitude_resolver_dep d)
+-{
+-  std::vector<aptitude_resolver_version> solvers;
+-  for(aptitude_resolver_dep::solver_iterator i=d.solvers_begin(); !i.end(); ++i)
+-    solvers.push_back(*i);
+-
+-  generic_solution<aptitude_universe>::ver_name_lt lt;
+-  sort(solvers.begin(), solvers.end(), lt);
+-
+-  out << d.get_source().get_package().get_name()
+-      << " "
+-      << d.get_source().get_name()
+-      << " -> {";
+-
+-  for(std::vector<aptitude_resolver_version>::const_iterator i = solvers.begin();
+-      i != solvers.end(); ++i)
+-    {
+-      if(i != solvers.begin())
+-	out << " ";
+-      out << (*i).get_package().get_name() << " "
+-	  << (*i).get_name();
+-    }
+-  out << "}";
+-
+-  return out;
+-}
+diff --git a/src/generic/apt/aptitude_resolver_universe.h b/src/generic/apt/aptitude_resolver_universe.h
+deleted file mode 100644
+index 3e5bbca..0000000
+--- a/src/generic/apt/aptitude_resolver_universe.h
++++ /dev/null
+@@ -1,1148 +0,0 @@
+-// aptitude_resolver_universe.h                     -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#ifndef APTITUDE_RESOLVER_UNIVERSE_H
+-#define APTITUDE_RESOLVER_UNIVERSE_H
+-
+-#include <apt-pkg/pkgcache.h>
+-#include <apt-pkg/pkgsystem.h>
+-#include <apt-pkg/version.h>
+-
+-#include <generic/util/eassert.h>
+-
+-#include "apt.h"
+-#include "aptcache.h"
+-
+-class aptitude_resolver_version;
+-
+-/** \brief Translates an APT package into the abstract realm.
+- *
+- *  This class is a model of the \ref universe_package "Package concept".
+- *
+- *  \sa \ref universe_package
+- */
+-class aptitude_resolver_package
+-{
+-  pkgDepCache *cache;
+-  pkgCache::PkgIterator pkg;
+-public:
+-  /** \brief Create an invalid package object. */
+-  aptitude_resolver_package()
+-    :cache(0)
+-  {
+-  }
+-
+-  /** \brief Create a package object corresponding to the given APT
+-   *  package.
+-   *
+-   *  \param _pkg The package to be represented by the new object.
+-   *  \param _cache The cache with which the new object is to be associated.
+-   */
+-  aptitude_resolver_package(const pkgCache::PkgIterator &_pkg,
+-			    pkgDepCache *_cache)
+-    :cache(_cache), pkg(_pkg)
+-  {
+-    eassert(cache!=0);
+-    eassert(pkg.Cache()!=0);
+-  }
+-
+-  /** \brief Generate a unique ID for this package.
+-   *
+-   *  \return The APT ID of the package.
+-   */
+-  unsigned int get_id() const
+-  {
+-    return pkg->ID;
+-  }
+-
+-  /** \return The name of the package. */
+-  const char *get_name() const
+-  {
+-    return pkg.Name();
+-  }
+-
+-  /** \return The underlying APT package wrapped by this object. */
+-  pkgCache::PkgIterator get_pkg() const
+-  {
+-    return pkg;
+-  }
+-
+-  /** \return \b true if other is the same package as this. */
+-  bool operator==(const aptitude_resolver_package &other) const
+-  {
+-    return pkg==other.pkg;
+-  }
+-
+-  /** \return \b true if other is not the same package as this. */
+-  bool operator!=(const aptitude_resolver_package &other) const
+-  {
+-    return pkg!=other.pkg;
+-  }
+-
+-  /** \brief Order packages by their memory location. */
+-  bool operator<(const aptitude_resolver_package &other) const
+-  {
+-    return ((const pkgCache::Package *) pkg) < ((const pkgCache::Package *) other.pkg);
+-  }
+-
+-  /** \return The to-be-installed version of this package. */
+-  aptitude_resolver_version current_version() const;
+-
+-  class version_iterator;
+-
+-  /** \return The first entry in the list of versions of this package. */
+-  version_iterator versions_begin() const;
+-};
+-
+-/** \brief Translates a version of an apt package into the abstract
+- *  realm.
+- *
+- *  This class is a model of the \ref universe_version "Version concept".
+- *
+- *  The version in question may be either a real version of the
+- *  package, or the "not-installed" version, which indicates that the
+- *  package is removed.
+- *
+- *  \sa \ref universe_version
+- */
+-class aptitude_resolver_version
+-{
+-  pkgDepCache *cache;
+-  pkgCache::PkgIterator pkg;
+-  pkgCache::VerIterator ver;
+-public:
+-  /** \brief Create an invalid version object. */
+-  aptitude_resolver_version()
+-    :cache(0)
+-  {
+-  }
+-
+-  /** \brief Create a version wrapper for the given version of the
+-   *  given package.
+-   *
+-   *  \param _pkg The package of which this is a version.  Must not be
+-   *  an end iterator.
+-   *
+-   *  \param _ver The version to be wrapped.  If an end iterator, the
+-   *  new object will represent the removal of _pkg.
+-   */
+-  aptitude_resolver_version(const pkgCache::PkgIterator &_pkg,
+-			    const pkgCache::VerIterator &_ver,
+-			    pkgDepCache *_cache)
+-    :cache(_cache), pkg(_pkg), ver(_ver)
+-  {
+-    eassert(cache!=0);
+-    eassert(pkg.Cache()!=0);
+-    eassert(ver.Cache()!=0);
+-  }
+-
+-  /** \return The APT package of which this is a version.
+-   *
+-   *  \sa get_package()
+-   */
+-  pkgCache::PkgIterator get_pkg() const
+-  {
+-    return pkg;
+-  }
+-
+-  /** \return The APT version wrapped by this object, or an end
+-   *  iterator if this is a "removal version".
+-   */
+-  pkgCache::VerIterator get_ver() const
+-  {
+-    return ver;
+-  }
+-
+-  /** \return The APT ID of this version if it is a real version,
+-   *  or a fake ID if it is a "removal version".
+-   */
+-  unsigned int get_id() const
+-  {
+-    if(!ver.end())
+-      return ver->ID;
+-    else
+-      // non-installed versions are faked.
+-      //
+-      // If this eats a lot of time, it could be memoized..but then
+-      // there's more to copy.  I could also teach the resolver about
+-      // "null" versions...but that would mean a bunch of pointless
+-      // special-casing caller-side anyway.
+-      return cache->Head().VersionCount+pkg->ID;
+-  }
+-
+-  /** \return The version string of this version, mangled if multiple
+-   *  distinct APT versions exist with identical version strings.
+-   */
+-  std::string get_name() const;
+-
+-  /** \return An abstract wrapper of the package with which this
+-   *  version is associated.
+-   *
+-   *  \sa get_pkg()
+-   */
+-  aptitude_resolver_package get_package() const
+-  {
+-    return aptitude_resolver_package(pkg, cache);
+-  }
+-
+-  /** \return \b true if this is the same version as other. */
+-  bool operator==(const aptitude_resolver_version &other) const
+-  {
+-    return pkg == other.pkg && ver == other.ver;
+-  }
+-
+-  /** \return \b true if this is not the same version as other. */
+-  bool operator!=(const aptitude_resolver_version &other) const
+-  {
+-    return pkg != other.pkg || ver != other.ver;
+-  }
+-
+-  /** \brief Order versions according to their memory location. */
+-  bool operator<(const aptitude_resolver_version &other) const
+-  {
+-    if(((const pkgCache::Package *) pkg) < ((const pkgCache::Package *) other.pkg))
+-      return true;
+-    else if(((const pkgCache::Package *) other.pkg) < ((const pkgCache::Package *) pkg))
+-      return false;
+-    else if(((const pkgCache::Version *) ver) < ((const pkgCache::Version *) other.ver))
+-      return true;
+-    else // if(((pkgCache::Version *) other.ver) < ((pkgCache::Version *) ver))
+-      return false;
+-  }
+-
+-  class revdep_iterator;
+-  class dep_iterator;
+-
+-  /** \brief Return the first entry in the list of reverse
+-   *  dependencies for this version.
+-   */
+-  revdep_iterator revdeps_begin() const;
+-
+-  /** \brief Return the first entry in the list of forward
+-   *  dependencies for this version.
+-   */
+-  dep_iterator deps_begin() const;
+-};
+-
+-inline aptitude_resolver_version aptitude_resolver_package::current_version() const
+-{
+-  // Transmute removed-with-config-files packages into not-installed
+-  // packages.
+-  if((*cache)[pkg].Keep() &&
+-     pkg->CurrentState == pkgCache::State::ConfigFiles)
+-    return aptitude_resolver_version(pkg, pkgCache::VerIterator(*cache, 0), cache);
+-  else
+-    return aptitude_resolver_version(pkg, (*cache)[pkg].InstVerIter(*cache),
+-				     cache);
+-}
+-
+-/** \brief Translates an apt dependency into the abstract realm.
+- *
+- *  This class is a model of the \ref universe_dep "Dependency concept".
+- *
+- *  Dependency relationships other than Conflicts are translated in a
+- *  very straightforward manner: unversioned dependencies collect all
+- *  the versions of the target package and are pushed backwards
+- *  through Provides, while versioned dependencies collect all
+- *  matching versions.  ORed dependencies collect all the versions
+- *  targeted by their subcomponents.
+- *
+- *  Conflicts relationships are handled by generating one abstract
+- *  dependency for the immediate conflict, and then a separate one for
+- *  \e each provider of the conflicted name (if the conflict is
+- *  unversioned, of course).  The solvers of these conflicts are the
+- *  non-conflicted versions of the conflicted package (including the
+- *  non-installed version), or the versions of the providing package
+- *  other than the immediate provider, respectively.
+- *
+- *  \sa \ref universe_dep
+- */
+-class aptitude_resolver_dep
+-{
+-  pkgDepCache *cache;
+-  pkgCache::DepIterator start;
+-  /** If start is a Conflicts and prv is not an end iterator, then the
+-   *  object represents "V -> {V'_1 V'_2 ..} where the V'-s are
+-   *  versions of prv.OwnerPkg() that do *not* provide V.ParentPkg().
+-   *  Otherwise, if start is a Conflicts and prv is an end iterator,
+-   *  the object represents the non-virtual part of the Conflicts; if
+-   *  start is not a Conflicts, prv is unused.
+-   *
+-   *  All that discussion is mainly important when checking if the dep
+-   *  is broken and/or when finding its solvers.
+-   */
+-  pkgCache::PrvIterator prv;
+-public:
+-  /** \brief Generate an invalid dependency object.
+-   */
+-  aptitude_resolver_dep()
+-    :cache(0), prv()
+-  {
+-  }
+-
+-  /** \brief Generate a new dependency.
+-   *
+-   *  \param dep The APT dependency to represent.
+-   *
+-   *  \param _prv If dep is a Conflicts, then this is either an end
+-   *  iterator (indicating that this object represents the conflict on
+-   *  the real target package), or the Provides through which the
+-   *  conflict should be projected.
+-   *
+-   *  \param _cache The package cache in which this dependency exists.
+-   */
+-  aptitude_resolver_dep(const pkgCache::DepIterator dep,
+-			const pkgCache::PrvIterator _prv,
+-			pkgDepCache *_cache)
+-    :cache(_cache), prv(_prv)
+-  {
+-    eassert(cache!=0);
+-    eassert(const_cast<pkgCache::DepIterator &>(dep).Cache()!=0);
+-    eassert(prv.Cache()!=0);
+-    eassert(!dep.end());
+-    if(dep->Type != pkgCache::Dep::Conflicts)
+-      {
+-	// Throw away the end, since it's not necessary.
+-	pkgCache::DepIterator end;
+-	surrounding_or(dep, start, end, &cache->GetCache());
+-      }
+-    else
+-      // Ignore ORs and just use the selected conflict.
+-      //
+-      //  NOTE: as of this writing, no known package does something as
+-      // stupid as ORed conflicts.
+-      start=dep;
+-  }
+-
+-  /** \brief Test whether the encapsulated dependency is a
+-   *   Recommends.
+-   */
+-  bool is_soft() const
+-  {
+-    return start->Type == pkgCache::Dep::Recommends;
+-  }
+-
+-  /** \brief Compare two dependencies for equality. */
+-  bool operator==(const aptitude_resolver_dep &other) const
+-  {
+-    return start == other.start &&
+-      (start->Type != pkgCache::Dep::Conflicts || prv == other.prv);
+-  }
+-
+-  /** \brief Compare two dependencies for equality. */
+-  bool operator!=(const aptitude_resolver_dep &other) const
+-  {
+-    return start != other.start ||
+-      (start->Type == pkgCache::Dep::Conflicts && prv != other.prv);
+-  }
+-
+-  /** \brief Orders dependencies according to their memory
+-   *  location.
+-   */
+-  bool operator<(const aptitude_resolver_dep &other) const
+-  {
+-    if(((const pkgCache::Dependency *) start) < ((const pkgCache::Dependency *) other.start))
+-      return true;
+-    else if(((const pkgCache::Dependency *) start) > ((const pkgCache::Dependency *) other.start))
+-      return false;
+-    else if(start->Type != pkgCache::Dep::Conflicts)
+-      return false;
+-    else if(((const pkgCache::Provides *) prv) < ((const pkgCache::Provides *) other.prv))
+-      return true;
+-    else
+-      return false;
+-  }
+-
+-  /** \brief Test whether a given solution breaks this dependency.
+-   *
+-   *  \param InstallationType A model of \ref universe_installation Installation.
+-   *
+-   *  \param I An installation to test against.
+-   *
+-   *  \return \b true if this dependency is not satisfied by I.
+-   */
+-  template<typename InstallationType>
+-  bool broken_under(const InstallationType &I) const;
+-
+-  /** \return The APT dependency associated with this abstract dependency. */
+-  pkgCache::DepIterator get_dep() const
+-  {
+-    return start;
+-  }
+-
+-  /** \return The APT Provides relationship associated with this
+-   *  abstract dependency.
+-   */
+-  pkgCache::PrvIterator get_prv() const
+-  {
+-    return prv;
+-  }
+-
+-  /** \return \b true if the given version will resolve this dependency. */
+-  bool solved_by(const aptitude_resolver_version &v) const;
+-
+-  /** \return The source version of this dependency. */
+-  aptitude_resolver_version get_source() const
+-  {
+-    eassert(!start.end());
+-    eassert(!const_cast<pkgCache::DepIterator &>(start).ParentPkg().end());
+-    return aptitude_resolver_version(const_cast<pkgCache::DepIterator &>(start).ParentPkg(),
+-				     const_cast<pkgCache::DepIterator &>(start).ParentVer(),
+-				     cache);
+-  }
+-
+-  class solver_iterator;
+-
+-  /** \return The head of the target list for this dependency. */
+-  solver_iterator solvers_begin() const;
+-};
+-
+-/** \brief Iterate over the versions of a package.
+- *
+- *  \sa aptitude_resolver_package, aptitude_resolver_version
+- */
+-class aptitude_resolver_package::version_iterator
+-{
+-  pkgDepCache *cache;
+-  pkgCache::PkgIterator pkg;
+-  pkgCache::VerIterator ver;
+-
+-  void normalize()
+-  {
+-    // This loop should only trigger once.
+-    while(!ver.end() &&
+-	  !ver.Downloadable() &&
+-	  (ver != pkg.CurrentVer() || pkg->CurrentState == pkgCache::State::ConfigFiles))
+-    ++ver;
+-  }
+-public:
+-  /** \brief Create an invalid version_iterator. */
+-  version_iterator()
+-    :cache(0)
+-  {
+-  }
+-
+-  /** \brief Create a version_iterator pointing at the first version of the given package.
+-   */
+-  version_iterator(pkgCache::PkgIterator _pkg,
+-		   pkgDepCache *_cache)
+-    :cache(_cache), pkg(_pkg), ver(_pkg.VersionList())
+-  {
+-  }
+-
+-  /** \return The APT package corresponding to this abstract package. */
+-  pkgCache::PkgIterator get_pkg() {return pkg;}
+-
+-  /** \return The APT version corresponding to this abstract version.
+-   *  If this is an end iterator, then this version corresponds to
+-   *  removing the package.
+-   */
+-  pkgCache::VerIterator get_ver() {return ver;}
+-
+-  /** \return \b true if this iterator is identical to other. */
+-  bool operator==(const version_iterator &other) const
+-  {
+-    return pkg == other.pkg && ver == other.ver;
+-  }
+-
+-  /** \return \b true if this iterator differs from other. */
+-  bool operator!=(const version_iterator &other) const
+-  {
+-    return pkg != other.pkg || ver != other.ver;
+-  }
+-
+-  /** \return The version at which this iterator currently points. */
+-  aptitude_resolver_version operator *() const
+-  {
+-    return aptitude_resolver_version(pkg, ver, cache);
+-  }
+-
+-  /** \brief Advance to the next version in the list.
+-   *
+-   *  \return A reference to this iterator.
+-   */
+-  version_iterator &operator++()
+-  {
+-    if(!ver.end())
+-      {
+-	++ver;
+-	normalize();
+-      }
+-    else
+-      pkg=pkgCache::PkgIterator();
+-    return *this;
+-  }
+-
+-  /** \return \b true if this is an end iterator. */
+-  bool end() const
+-  {
+-    return pkg.end();
+-  }
+-};
+-
+-inline aptitude_resolver_package::version_iterator aptitude_resolver_package::versions_begin() const
+-{
+-  return version_iterator(pkg, cache);
+-}
+-
+-/** \brief Iterates over the reverse dependencies of a version.
+- *
+- *  As explained in the definition of the \ref universe_version
+- *  "Version concept", this is not necessarily the set of dependencies
+- *  that impinge on the version.
+- *
+- *  \sa aptitude_resolver_version, aptitude_resolver_dep
+- */
+-class aptitude_resolver_version::revdep_iterator
+-{
+-  pkgDepCache *cache;
+-  /** The Depends which is currently being tried. */
+-  pkgCache::DepIterator dep_lst;
+-  /** The Provides which is currently being tried. */
+-  pkgCache::PrvIterator prv_lst;
+-  /** The package version to which this dep should apply (used
+-   *  to check versioned deps).
+-   */
+-  pkgCache::VerIterator ver;
+-  /** Whether we've started looking at provides yet. */
+-  bool provides_open;
+-
+-  /** Advance to the next valid iterator. */
+-  void normalize();
+-
+-  /** \return true if dep_lst applies to ver: this is, if it is
+-   *               a strong dependency on ver.
+-   */
+-  bool applicable() const;
+-public:
+-#if 0
+-  revdep_iterator()
+-    :cache(0)
+-  {
+-  }
+-#endif
+-
+-  /** \brief Generate a revdep_iterator to cover the reverse deps of
+-   *  the given version.
+-   *
+-   *  \param v The version whose reverse dependencies are to be
+-   *  enumerated.  If this is an end iterator, the resulting list will
+-   *  be empty.
+-   *
+-   *  \param _cache The cache in which to operate.
+-   */
+-  revdep_iterator(const pkgCache::VerIterator &v,
+-		  pkgDepCache *_cache)
+-    :cache(_cache),
+-     prv_lst(*_cache, 0, (pkgCache::Package *) 0), ver(v),
+-     provides_open(false)
+-  {
+-    // Note that if v is an end iterator, we present an empty list and
+-    // hence don't need to know its package.  This is safe because the
+-    // [UNINST] version has no reverse dependencies (except conflicts,
+-    // but those are handled in the usual way).
+-    if(!v.end())
+-      dep_lst=v.ParentPkg().RevDependsList();
+-    else
+-      // Immediately flag this as an end iterator, and avoid crashing
+-      // in normalize() when we look at v.ProvidesList().
+-      provides_open=true;
+-    normalize();
+-  }
+-
+-//   bool operator==(const revdep_iterator &other) const
+-//   {
+-//     return dep == other.dep && ver == other.ver;
+-//   }
+-
+-//   bool operator!=(const revdep_iterator &other) const
+-//   {
+-//     return dep != other.dep || ver != other.ver;
+-//   }
+-
+-  /** \brief Test whether this is an end iterator. */
+-  bool end() const
+-  {
+-    return dep_lst.end();
+-  }
+-
+-  /** \return The dependency at which this iterator currently
+-   *  points.
+-   */
+-  aptitude_resolver_dep operator*() const
+-  {
+-    return aptitude_resolver_dep(dep_lst, prv_lst, cache);
+-  }
+-
+-  /** \brief Advance to the next entry in the list.
+-   *
+-   *  \return A reference to this iterator.
+-   */
+-  revdep_iterator &operator++()
+-  {
+-    ++dep_lst;
+-    normalize();
+-
+-    return *this;
+-  }
+-};
+-
+-/** \brief Iterates over the distinct dependencies of a version.
+- *
+- *  \sa aptitude_resolver_version, aptitude_resolver_dep
+- */
+-class aptitude_resolver_version::dep_iterator
+-{
+-  pkgDepCache *cache;
+-  pkgCache::DepIterator dep;
+-  pkgCache::PrvIterator prv;
+-  /** If \b true, then dep is a Conflicts and we are iterating over
+-   *  the packages providing its target.
+-   */
+-  bool prv_open;
+-
+-  void normalize();
+-
+-public:
+-  /** \brief Create an invalid dep iterator for the given cache.
+-   *
+-   *  \param cache The cache in which to create a dep iterator.
+-   */
+-  dep_iterator(pkgDepCache *_cache)
+-    :cache(_cache),
+-     prv(*_cache, 0, (pkgCache::Package *) 0),
+-     prv_open(false)
+-  {
+-  }
+-
+-  /** \brief Create an iterator for the given version's dependencies in the given cache.
+-   *
+-   *  \param ver The version whose dependencies should be iterated over.
+-   *
+-   *  \param _cache The cache in which to operate.
+-   */
+-  dep_iterator(const pkgCache::VerIterator &ver,
+-	       pkgDepCache *_cache)
+-    :cache(_cache),
+-     dep(ver.DependsList()),
+-     prv(*_cache, 0, (pkgCache::Package *) 0),
+-     prv_open(false)
+-  {
+-    normalize();
+-  }
+-
+-  /** \brief Assignment operator. */
+-  dep_iterator &operator=(const dep_iterator &other)
+-  {
+-    cache=other.cache;
+-    dep=other.dep;
+-    prv=other.prv;
+-    prv_open=other.prv_open;
+-
+-    return *this;
+-  }
+-
+-  /** \return The dependency at which this iterator currently points. */
+-  aptitude_resolver_dep operator*() const
+-  {
+-    return aptitude_resolver_dep(dep, prv, cache);
+-  }
+-
+-  /** \brief Test whether this is an end iterator. */
+-  bool end() const
+-  {
+-    return dep.end();
+-  }
+-
+-  /** \brief Advance to the next dependency of this version.
+-   *
+-   *  \return A reference to this iterator.
+-   */
+-  dep_iterator &operator++();
+-};
+-
+-inline aptitude_resolver_version::revdep_iterator aptitude_resolver_version::revdeps_begin() const
+-{
+-  return revdep_iterator(ver, cache);
+-}
+-
+-inline aptitude_resolver_version::dep_iterator aptitude_resolver_version::deps_begin() const
+-{
+-  if(ver.end())
+-    return dep_iterator(cache);
+-  else
+-    return dep_iterator(ver, cache);
+-}
+-
+-/** \brief Iterates over the targets of a dependency.
+- *
+- *  \sa aptitude_resolver_dep
+- */
+-class aptitude_resolver_dep::solver_iterator
+-{
+-  pkgDepCache *cache;
+-
+-  pkgCache::DepIterator dep_lst;
+-  pkgCache::VerIterator ver_lst;
+-  pkgCache::PrvIterator prv_lst;
+-  /** \b true if we exhausted all options; needed because
+-   *          dep_lst might not be an end iterator (since it'll
+-   *          move to the next OR group)
+-   */
+-  bool finished;
+-
+-  /** Advance to the next interesting version/provides -- i.e., skip
+-   *  uninteresting ones.
+-   */
+-  void normalize();
+-
+-public:
+-  /** \brief Initialize a solution iterator for a dependency that is
+-   *  not a Conflicts.
+-   *
+-   *  \param start The dependency whose targets should be enumerated.
+-   *
+-   *  \param _cache The package cache in which this dependency is
+-   *  located.
+-   */
+-  solver_iterator(const pkgCache::DepIterator &start,
+-		  pkgDepCache *_cache)
+-    :cache(_cache),
+-     dep_lst(start),
+-     prv_lst(*cache, 0, (pkgCache::Package *) 0),
+-     finished(start.end())
+-  {
+-    if(!dep_lst.end())
+-      {
+-	eassert(dep_lst->Type != pkgCache::Dep::Conflicts);
+-
+-	ver_lst=const_cast<pkgCache::DepIterator &>(start).TargetPkg().VersionList();
+-	prv_lst=const_cast<pkgCache::DepIterator &>(start).TargetPkg().ProvidesList();
+-      }
+-
+-    normalize();
+-  }
+-
+-  /** \brief Initialize a solution iterator for a Conflicts.
+-   *
+-   *  \param d The conflict that we should iterate over solutions to.
+-   *
+-   *  \param p The Provides through which the Conflicts is being
+-   *  projected, or an end iterator if we are handling a straight
+-   *  Conflicts.
+-   *
+-   *  \param _cache The package cache in which to work.
+-   */
+-  solver_iterator(const pkgCache::DepIterator &d,
+-		  const pkgCache::PrvIterator &p,
+-		  pkgDepCache *_cache)
+-    :cache(_cache), dep_lst(d), prv_lst(p), finished(d.end())
+-  {
+-    if(!dep_lst.end())
+-      {
+-	eassert(d->Type == pkgCache::Dep::Conflicts);
+-	// Either we're looking at all versions of the named dep, or
+-	// at all versions of the providing package.
+-	if(prv_lst.end())
+-	  ver_lst=const_cast<pkgCache::DepIterator &>(dep_lst).TargetPkg().VersionList();
+-	else
+-	  ver_lst=const_cast<pkgCache::PrvIterator &>(p).OwnerPkg().VersionList();
+-      }
+-
+-    normalize();
+-  }
+-
+-#if 0
+-  solver_iterator()
+-    :cache(0),
+-     // shouldn't do this, but otherwise we crash!!
+-     prv_lst(*apt_cache_file, 0, (pkgCache::Package *) 0), finished(true)
+-  {
+-  }
+-#endif
+-
+-  /** \brief Compare two solver iterators for equality. */
+-  bool operator==(const solver_iterator &other) const
+-  {
+-    return dep_lst == other.dep_lst &&
+-      ver_lst == other.ver_lst &&
+-      prv_lst == other.prv_lst &&
+-      finished == other.finished;
+-  }
+-
+-  /** \brief Compare two solver iterators for equality. */
+-  bool operator!=(const solver_iterator &other) const
+-  {
+-    return dep_lst != other.dep_lst ||
+-      ver_lst != other.ver_lst ||
+-      prv_lst != other.prv_lst ||
+-      finished != other.finished;
+-  }
+-
+-  /** \brief Advance to the next solution.
+-   *
+-   *  \return a reference to this iterator.
+-   */
+-  solver_iterator &operator++();
+-
+-  /** \return The version at which this iterator currently points. */
+-  aptitude_resolver_version operator*() const;
+-
+-  /** \brief Test whether this is an end iterator. */
+-  bool end() const
+-  {
+-    return finished;
+-  }
+-};
+-
+-inline aptitude_resolver_dep::solver_iterator aptitude_resolver_dep::solvers_begin() const
+-{
+-  if(start->Type != pkgCache::Dep::Conflicts)
+-    return solver_iterator(start, cache);
+-  else
+-    return solver_iterator(start, prv, cache);
+-}
+-
+-template<typename InstallationType>
+-bool aptitude_resolver_dep::broken_under(const InstallationType &I) const
+-{
+-  // First, check that the solution actually installs the source.
+-  if(const_cast<pkgCache::DepIterator &>(start).ParentVer() != I.version_of(aptitude_resolver_package(const_cast<pkgCache::DepIterator &>(start).ParentPkg(), cache)).get_ver())
+-    return false;
+-
+-  if(start->Type != pkgCache::Dep::Conflicts)
+-    {
+-      pkgCache::DepIterator dep=start;
+-
+-      while(!dep.end())
+-	{
+-	  pkgCache::VerIterator direct_ver=I.version_of(aptitude_resolver_package(dep.TargetPkg(), cache)).get_ver();
+-	  if(!direct_ver.end() &&
+-	     _system->VS->CheckDep(direct_ver.VerStr(),
+-				   dep->CompareOp,
+-				   dep.TargetVer()))
+-	    return false;
+-
+-	  if(!dep.TargetVer())
+-	    {
+-	      for(pkgCache::PrvIterator prv=dep.TargetPkg().ProvidesList();
+-		  !prv.end(); ++prv)
+-		if(prv.OwnerVer() == I.version_of(aptitude_resolver_package(prv.OwnerPkg(), cache)).get_ver())
+-		  return false;
+-	    }
+-
+-	  if(!(dep->CompareOp & pkgCache::Dep::Or))
+-	    break;
+-	  ++dep;
+-	}
+-
+-      return true;
+-    }
+-  else
+-    {
+-      // Recall that a Conflicts dep iterator is looking at a single
+-      // element of the Conflicts: either a direct conflict or an
+-      // indirect conflict (i.e., via a virtual pkg).
+-
+-      if(prv.end())
+-	{
+-	  if(const_cast<pkgCache::DepIterator &>(start).TargetPkg() == const_cast<pkgCache::DepIterator &>(start).ParentPkg())
+-	    return false;
+-
+-	  pkgCache::VerIterator direct_ver=I.version_of(aptitude_resolver_package(const_cast<pkgCache::DepIterator &>(start).TargetPkg(), cache)).get_ver();
+-
+-	  if(!direct_ver.end() &&
+-	     _system->VS->CheckDep(direct_ver.VerStr(),
+-				   start->CompareOp,
+-				   start.TargetVer()))
+-	    return true;
+-	  else
+-	    return false;
+-	}
+-      else
+-	{
+-	  if(const_cast<pkgCache::PrvIterator &>(prv).OwnerPkg() == const_cast<pkgCache::DepIterator &>(start).ParentPkg())
+-	    return false;
+-
+-	  if(start.TargetVer())
+-	    return false;
+-
+-	  return I.version_of(aptitude_resolver_package(const_cast<pkgCache::PrvIterator &>(prv).OwnerPkg(), cache)).get_ver()==const_cast<pkgCache::PrvIterator &>(prv).OwnerVer();
+-	}
+-    }
+-}
+-
+-/** \brief This class translates an APT package system into the
+- *  abstract package system as described in \ref abstract_universe.
+- *
+- *  \sa \ref universe_universe
+- */
+-class aptitude_universe
+-{
+-  aptitudeDepCache *cache;
+-
+-  aptitude_universe();
+-public:
+-  typedef aptitude_resolver_package package;
+-  typedef aptitude_resolver_version version;
+-  typedef aptitude_resolver_dep dep;
+-
+-  aptitude_universe(aptitudeDepCache *_cache)
+-    :cache(_cache)
+-  {
+-  }
+-
+-  aptitudeDepCache *get_cache() const {return cache;}
+-
+-  /** \brief Iterate over all the packages in the universe. */
+-  class package_iterator
+-  {
+-    pkgDepCache *cache;
+-    pkgCache::PkgIterator realiter;
+-  public:
+-    /** \brief Create an invalid package iterator. */
+-    package_iterator()
+-      :cache(0)
+-    {
+-    }
+-
+-    /** \brief Create an iterator pointing at the first package in the
+-     *  cache.
+-     *
+-     *  \param _cache The package cache to iterate over.
+-     */
+-    package_iterator(pkgDepCache *_cache)
+-      :cache(_cache), realiter(_cache->PkgBegin())
+-    {
+-    }
+-
+-    /** \brief Compare two package iterators for equality. */
+-    bool operator==(const package_iterator &other) const
+-    {
+-      return realiter==other.realiter;
+-    }
+-
+-    /** \brief Compare two package iterators for equality. */
+-    bool operator!=(const package_iterator &other) const
+-    {
+-      return realiter!=other.realiter;
+-    }
+-
+-    /** \brief Retrieve the underlying apt iterator. */
+-    pkgCache::PkgIterator get_pkg() const
+-    {
+-      return realiter;
+-    }
+-
+-    /** \brief Extract the package at which this iterator currently points. */
+-    package operator*() const
+-    {
+-      return package(realiter, cache);
+-    }
+-
+-    /** \brief Advance to the next package.
+-     *
+-     *  \return A reference to this iterator.
+-     */
+-    package_iterator &operator++()
+-    {
+-      ++realiter;
+-      return *this;
+-    }
+-
+-    /** \brief Test whether this is an end iterator. */
+-    bool end() const
+-    {
+-      return realiter.end();
+-    }
+-  };
+-
+-  /** \brief Iterate over all the interesting dependencies in the apt
+-   *  cache.
+-   */
+-  class dep_iterator
+-  {
+-    pkgDepCache *cache;
+-
+-    pkgCache::PkgIterator pkg;
+-    pkgCache::VerIterator ver;
+-    aptitude_resolver_version::dep_iterator dep;
+-
+-    /** \brief Advance to the earliest interesting dependency that is
+-     *  no earlier than the current dependency.
+-     */
+-    void normalize();
+-
+-  public:
+-    /** \brief Create a dep_iterator for the given cache.
+-     *
+-     *  \param _cache The package cache whose dependencies should be
+-     *  iterated over.
+-     */
+-    dep_iterator(pkgDepCache *_cache)
+-      :cache(_cache),
+-       pkg(_cache->PkgBegin()),
+-       ver(),
+-       dep(_cache)
+-    {
+-      if(!pkg.end())
+-	ver=pkg.VersionList();
+-      if(!ver.end())
+-	dep=aptitude_resolver_version::dep_iterator(ver, _cache);
+-
+-      normalize();
+-    }
+-
+-    /** \return the dependency at which this iterator currently points. */
+-    aptitude_universe::dep operator*() const
+-    {
+-      return *dep;
+-    }
+-
+-    /** \brief Advance to the next dependency in the cache.
+-     *
+-     *  \return a reference to this iterator.
+-     */
+-    dep_iterator &operator++()
+-    {
+-      eassert(!dep.end());
+-
+-      ++dep;
+-
+-      normalize();
+-
+-      return *this;
+-    }
+-
+-    /** \brief Test whether this is an end iterator. */
+-    bool end() const
+-    {
+-      return pkg.end();
+-    }
+-  };
+-
+-  /** \brief Iterate over the broken interesting dependencies in an
+-   *  apt cache.
+-   *
+-   *  A bit like dep_iterator, but skips non-broken packages and deps.
+-   *  Since the "exposed version" of a package is its InstVersion, we
+-   *  need to test at most one version per package, so no need to keep
+-   *  a version iterator here.
+-   *
+-   *  Note on OR groups: DepGInstall is only set on the last entry in
+-   *  an OR group.  But Conflicts should be handled individually.  As
+-   *  I'm not even sure ORed conflicts are valid, none exist in the
+-   *  wild, and ORed conflicts are a Pointless Idea[tm] anyway, THIS
+-   *  WILL NOT PRODUCE CORRECT OUTPUT for ORed conflicts.  \todo try
+-   *  to find a way to get correct output without compromising in the
+-   *  main codepath.
+-   */
+-  class broken_dep_iterator
+-  {
+-    pkgDepCache *cache;
+-
+-    class pkgCache::PkgIterator pkg;
+-    class pkgCache::DepIterator the_dep;
+-    /** If the_dep is a Conflicts, then the following keep track
+-     *  of which sub-relationship is being examined.
+-     */
+-    class pkgCache::PrvIterator prv;
+-    bool prv_open;
+-
+-    /** \return \b true if the given non-end dep is InstBroken. */
+-    bool dep_is_inst_broken(const pkgCache::DepIterator &d) const;
+-
+-    // Push forward to the next interesting point.
+-    void normalize();
+-
+-  public:
+-#if 0
+-    broken_dep_iterator()
+-      :cache(0)
+-    {
+-    }
+-#endif
+-
+-    /** \brief Create a broken_dep_iterator for the given package cache. */
+-    broken_dep_iterator(pkgDepCache *_cache)
+-      :cache(_cache),
+-       pkg(_cache->PkgBegin()), prv(*_cache, 0, (pkgCache::Package *) 0),
+-       prv_open(false)
+-    {
+-      if(!pkg.end())
+-	{
+-	  pkgCache::VerIterator ver=(*cache)[pkg].InstVerIter(*cache);
+-
+-	  if(!ver.end())
+-	    the_dep=ver.DependsList();
+-	}
+-
+-      normalize();
+-    }
+-
+-    /** \return the dependency at which this iterator currently points. */
+-    aptitude_universe::dep operator*() const
+-    {
+-      return aptitude_universe::dep(the_dep, prv, cache);
+-    }
+-
+-    /** \brief Advance to the next broken dependency.
+-     *
+-     *  \return a reference to this iterator.
+-     */
+-    broken_dep_iterator &operator++();
+-
+-    /** \brief Test whether this is an end iterator. */
+-    bool end() const
+-    {
+-      return pkg.end();
+-    }
+-  };
+-
+-  package_iterator packages_begin() const
+-  {
+-    return package_iterator(cache);
+-  }
+-
+-  dep_iterator deps_begin() const
+-  {
+-    return dep_iterator(cache);
+-  }
+-
+-  broken_dep_iterator broken_begin() const
+-  {
+-    return broken_dep_iterator(cache);
+-  }
+-
+-  unsigned long get_version_count() const
+-  {
+-    // PackageCount is added to make room for the UNINST versions.
+-    return cache->Head().VersionCount+cache->Head().PackageCount;
+-  }
+-
+-  unsigned long get_package_count() const
+-  {
+-    return cache->Head().PackageCount;
+-  }
+-};
+-
+-/** \brief Write an aptitude_resolver_dep to the given stream. */
+-std::ostream &operator<<(ostream &out, aptitude_resolver_dep d);
+-
+-#endif
+diff --git a/src/generic/apt/download_install_manager.cc b/src/generic/apt/download_install_manager.cc
+index f4d5275..7333d00 100644
+--- a/src/generic/apt/download_install_manager.cc
++++ b/src/generic/apt/download_install_manager.cc
+@@ -26,9 +26,9 @@
+ #include <aptitude.h>
+ 
+ #include <apt-pkg/acquire-item.h>
+-#include <apt-pkg/dpkgpm.h>
+ #include <apt-pkg/error.h>
+ #include <apt-pkg/sourcelist.h>
++#include <apt-pkg/pkgsystem.h>
+ 
+ #include <pthread.h>
+ #include <signal.h>
+@@ -36,7 +36,7 @@
+ using namespace std;
+ 
+ download_install_manager::download_install_manager(bool _download_only)
+-  : log(NULL), download_only(_download_only), pm(new pkgDPkgPM(*apt_cache_file))
++  : log(NULL), download_only(_download_only), pm(_system->CreatePM(*apt_cache_file))
+ {
+ }
+ 
+@@ -130,9 +130,9 @@ download_manager::result download_install_manager::execute_install_run(pkgAcquir
+ 
+   pre_install_hook();
+ 
+-  // Note that someone could grab the lock before dpkg takes it;
++  // Note that someone could grab the lock before rpm takes it;
+   // without a more complicated synchronization protocol (and I don't
+-  // control the code at dpkg's end), them's the breaks.
++  // control the code at rpm's end), them's the breaks.
+   apt_cache_file->ReleaseLock();
+ 
+   result rval = success;
+@@ -142,15 +142,14 @@ download_manager::result download_install_manager::execute_install_run(pkgAcquir
+   sigfillset(&allsignals);
+ 
+   pthread_sigmask(SIG_UNBLOCK, &allsignals, &oldsignals);
+-  pkgPackageManager::OrderResult pmres = pm->DoInstall(aptcfg->FindI("APT::Status-Fd", -1));
++  pkgPackageManager::OrderResult pmres = pm->DoInstall();
+   pthread_sigmask(SIG_SETMASK, &oldsignals, NULL);
+ 
+   switch(pmres)
+     {
+     case pkgPackageManager::Failed:
+       _error->DumpErrors();
+-      cerr << _("A package failed to install.  Trying to recover:") << endl;
+-      system("dpkg --configure -a");
++      cerr << _("A package failed to install.") << endl;
+       _error->Discard();
+       
+       rval = failure;
+@@ -173,7 +172,7 @@ download_manager::result download_install_manager::execute_install_run(pkgAcquir
+   if(!apt_cache_file->GainLock())
+     // This really shouldn't happen.
+     {
+-      _error->Error(_("Could not regain the system lock!  (Perhaps another apt or dpkg is running?)"));
++      _error->Error(_("Could not regain the system lock!  (Perhaps another apt or rpm is running?)"));
+       return failure;
+     }
+ 
+diff --git a/src/generic/apt/download_manager.cc b/src/generic/apt/download_manager.cc
+index c2ae4db..2cd2a49 100644
+--- a/src/generic/apt/download_manager.cc
++++ b/src/generic/apt/download_manager.cc
+@@ -36,5 +36,5 @@ pkgAcquire::RunResult download_manager::do_download()
+ 
+ pkgAcquire::RunResult download_manager::do_download(int PulseInterval)
+ {
+-  return fetcher->Run(PulseInterval);
++  return fetcher->Run();
+ }
+diff --git a/src/generic/apt/matchers.cc b/src/generic/apt/matchers.cc
+index 86e4f12..161d51b 100644
+--- a/src/generic/apt/matchers.cc
++++ b/src/generic/apt/matchers.cc
+@@ -33,8 +33,6 @@
+ #include "matchers.h"
+ 
+ #include "apt.h"
+-#include "tags.h"
+-#include "tasks.h"
+ 
+ #include <aptitude.h>
+ 
+@@ -49,7 +47,7 @@
+ #include <apt-pkg/pkgcache.h>
+ #include <apt-pkg/pkgrecords.h>
+ #include <apt-pkg/pkgsystem.h>
+-#include <apt-pkg/version.h>
++#define pkgCheckDep _system->checkDep
+ 
+ #include <generic/util/eassert.h>
+ #include <ctype.h>
+@@ -479,95 +477,6 @@ public:
+   }
+ };
+ 
+-class pkg_task_matcher : public pkg_string_matcher
+-{
+-public:
+-  pkg_task_matcher(const string &s) : pkg_string_matcher(s)
+-  {
+-  }
+-
+-  bool matches(const pkgCache::PkgIterator &pkg,
+-	       const pkgCache::VerIterator &v)
+-  {
+-    list<string> *l=get_tasks(pkg);
+-
+-    if(!l)
+-      return false;
+-
+-    for(list<string>::iterator i=l->begin();
+-	i!=l->end();
+-	++i)
+-      if(string_matches(i->c_str()))
+-	return true;
+-
+-    return false;
+-  }
+-
+-  // Uses the fact that the result returns NULL <=> nothing matched
+-  pkg_match_result *get_match(const pkgCache::PkgIterator &pkg,
+-			      const pkgCache::VerIterator &ver)
+-  {
+-    list<string> *l=get_tasks(pkg);
+-
+-    if(!l)
+-      return NULL;
+-
+-    for(list<string>::iterator i=l->begin();
+-	i!=l->end();
+-	++i)
+-      {
+-	pkg_match_result *r=get_string_match(i->c_str());
+-
+-	if(r != NULL)
+-	  return r;
+-      }
+-
+-    return NULL;
+-  }
+-};
+-
+-class pkg_tag_matcher : public pkg_string_matcher
+-{
+-public:
+-  pkg_tag_matcher(const string &s)
+-    : pkg_string_matcher(s)
+-  {
+-  }
+-
+-  bool matches(const pkgCache::PkgIterator &pkg,
+-	       const pkgCache::VerIterator &ver)
+-  {
+-    const std::set<tag> *tags = get_tags(pkg);
+-
+-    if(tags == NULL)
+-      return false;
+-
+-    for(std::set<tag>::const_iterator i=tags->begin(); i!=tags->end(); ++i)
+-      if(string_matches(i->str().c_str()))
+-	return true;
+-
+-    return false;
+-  }
+-
+-  pkg_match_result *get_match(const pkgCache::PkgIterator &pkg,
+-			      const pkgCache::VerIterator &ver)
+-  {
+-    const set<tag> *tags = get_tags(pkg);
+-
+-    if(tags == NULL)
+-      return NULL;
+-
+-    for(set<tag>::const_iterator i=tags->begin(); i!=tags->end(); ++i)
+-      {
+-	pkg_match_result *res = get_string_match(i->str().c_str());
+-	if(res != NULL)
+-	  return res;
+-      }
+-
+-    return NULL;
+-  }
+-};
+-
+ //  Package-file info matchers.  Match a package if any of its
+ // available files (for all versions) match the given criteria.
+ //
+@@ -839,44 +748,37 @@ public:
+ class pkg_action_matcher:public pkg_matcher
+ {
+   pkg_action_state type;
+-  bool require_purge;
+ public:
+-  pkg_action_matcher(pkg_action_state _type, bool _require_purge)
+-    :type(_type), require_purge(_require_purge)
++  pkg_action_matcher(pkg_action_state _type)
++    :type(_type)
+   {
+   }
+ 
+   bool matches(const pkgCache::PkgIterator &pkg,
+ 	       const pkgCache::VerIterator &ver)
+   {
+-    if(require_purge &&
+-       ((*apt_cache_file)[pkg].iFlags & pkgDepCache::Purge) == 0)
+-      return false;
+-    else
++    switch(type)
+       {
+-	switch(type)
+-	  {
+-	  case pkg_install:
+-	    {
+-	      pkg_action_state thetype=find_pkg_state(pkg);
+-	      return thetype==pkg_install || thetype==pkg_auto_install;
+-	    }
+-	  case pkg_hold:
+-	    return !pkg.CurrentVer().end() && (*apt_cache_file)->get_ext_state(pkg).selection_state==pkgCache::State::Hold;
+-	  case pkg_remove:
+-	    {
+-	      pkg_action_state thetype=find_pkg_state(pkg);
+-
+-	      return thetype==pkg_remove || thetype==pkg_auto_remove ||
+-		thetype==pkg_unused_remove;
+-	    }
+-	  default:
+-	    {
+-	      pkg_action_state thetype=find_pkg_state(pkg);
+-
+-	      return thetype==type;
+-	    }
+-	  }
++      case pkg_install:
++        {
++          pkg_action_state thetype=find_pkg_state(pkg);
++          return thetype==pkg_install || thetype==pkg_auto_install;
++        }
++      case pkg_hold:
++        return !pkg.CurrentVer().end() && (*apt_cache_file)->get_ext_state(pkg).selection_state==pkgCache::State::Hold;
++      case pkg_remove:
++        {
++          pkg_action_state thetype=find_pkg_state(pkg);
++
++	  return thetype==pkg_remove || thetype==pkg_auto_remove ||
++	      thetype==pkg_unused_remove;
++        }
++      default:
++        {
++          pkg_action_state thetype=find_pkg_state(pkg);
++
++          return thetype==type;
++        }
+       }
+   }
+ 
+@@ -2144,30 +2046,26 @@ pkg_matcher *parse_atom(string::const_iterator &start,
+ 		      {
+ 			// Match packages to be installed
+ 			if(!strcasecmp(substr.c_str(), "install"))
+-			  return new pkg_action_matcher(pkg_install, false);
++			  return new pkg_action_matcher(pkg_install);
+ 
+ 			// Match packages to be upgraded
+ 			else if(!strcasecmp(substr.c_str(), "upgrade"))
+-			  return new pkg_action_matcher(pkg_upgrade, false);
++			  return new pkg_action_matcher(pkg_upgrade);
+ 
+ 			else if(!strcasecmp(substr.c_str(), "downgrade"))
+-			  return new pkg_action_matcher(pkg_downgrade, false);
++			  return new pkg_action_matcher(pkg_downgrade);
+ 
+ 			// Match packages to be removed OR purged
+ 			else if(!strcasecmp(substr.c_str(), "remove"))
+-			  return new pkg_action_matcher(pkg_remove, false);
+-
+-			// Match packages to be purged
+-			else if(!strcasecmp(substr.c_str(), "purge"))
+-			  return new pkg_action_matcher(pkg_remove, true);
++			  return new pkg_action_matcher(pkg_remove);
+ 
+ 			// Match packages to be reinstalled
+ 			else if(!strcasecmp(substr.c_str(), "reinstall"))
+-			  return new pkg_action_matcher(pkg_reinstall, false);
++			  return new pkg_action_matcher(pkg_reinstall);
+ 
+ 			// Match held packages
+ 			else if(!strcasecmp(substr.c_str(), "hold"))
+-			  return new pkg_action_matcher(pkg_hold, false);
++			  return new pkg_action_matcher(pkg_hold);
+ 			else if(!strcasecmp(substr.c_str(), "keep"))
+ 			  return new pkg_keep_matcher;
+ 
+@@ -2189,8 +2087,6 @@ pkg_matcher *parse_atom(string::const_iterator &start,
+ 		      }
+ 		    case 'd':
+ 		      return new pkg_description_matcher(substr);
+-		    case 'G':
+-		      return new pkg_tag_matcher(substr);
+ 		    case 'F':
+ 		      return new pkg_false_matcher;
+ 		    case 'm':
+@@ -2233,8 +2129,6 @@ pkg_matcher *parse_atom(string::const_iterator &start,
+ 		      }
+ 		    case 's':
+ 		      return new pkg_section_matcher(substr);
+-		    case 't':
+-		      return new pkg_task_matcher(substr);
+ 		    case 'T':
+ 		      return new pkg_true_matcher;
+ 		    case 'V':
+diff --git a/src/generic/apt/matchers.h b/src/generic/apt/matchers.h
+index fd07dce..a8550df 100644
+--- a/src/generic/apt/matchers.h
++++ b/src/generic/apt/matchers.h
+@@ -27,6 +27,7 @@
+ #include <vector>
+ 
+ #include <apt-pkg/pkgcache.h>
++#include <apt-pkg/version.h>
+ 
+ /* For the cases where you want to investigate just what you matched a
+  * bit more thoroughly.
+diff --git a/src/generic/apt/pkg_acqfile.cc b/src/generic/apt/pkg_acqfile.cc
+index bb2775b..42537d7 100644
+--- a/src/generic/apt/pkg_acqfile.cc
++++ b/src/generic/apt/pkg_acqfile.cc
+@@ -1,6 +1,6 @@
+ // pkg_acqfile.cc
+ //
+-//  Copyright 2002, 2005 Daniel Burrows
++//  Copyright 2002 Daniel Burrows
+ //
+ //  This program is free software; you can redistribute it and/or modify
+ //  it under the terms of the GNU General Public License as published by
+@@ -35,10 +35,46 @@
+ #include <sys/stat.h>
+ 
+ #include <apt-pkg/error.h>
++#include <apt-pkg/configuration.h>
+ #include <apt-pkg/acquire-item.h>
+ #include <apt-pkg/sourcelist.h>
+ #include <apt-pkg/strutl.h>
+ 
++pkgAcqFileSane::pkgAcqFileSane(pkgAcquire *Owner, string URI,
++			       string Description, string ShortDesc,
++			       string filename):
++  Item(Owner)
++{
++  Retries=_config->FindI("Acquire::Retries",0);
++  DestFile=filename;
++
++  Desc.URI=URI;
++  Desc.Description=Description;
++  Desc.Owner=this;
++  Desc.ShortDesc=ShortDesc;
++
++  QueueURI(Desc);
++}
++
++// Straight from acquire-item.cc
++/* Here we try other sources */
++void pkgAcqFileSane::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
++{
++  ErrorText = LookupTag(Message,"Message");
++
++  // This is the retry counter
++  if (Retries != 0 &&
++      Cnf->LocalOnly == false &&
++      StringToBool(LookupTag(Message,"Transient-Failure"),false) == true)
++    {
++      Retries--;
++      QueueURI(Desc);
++      return;
++    }
++
++  Item::Failed(Message,Cnf);
++}
++
+ // Mostly copied from pkgAcqArchive.
+ bool get_archive(pkgAcquire *Owner, pkgSourceList *Sources,
+ 		 pkgRecords *Recs, pkgCache::VerIterator const &Version,
+@@ -93,8 +129,7 @@ bool get_archive(pkgAcquire *Owner, pkgSourceList *Sources,
+       if (_error->PendingError() == true)
+          return false;
+ 
+-      const string PkgFile = Parse.FileName();
+-      const string MD5     = Parse.MD5Hash();
++      string PkgFile = Parse.FileName();
+       if (PkgFile.empty() == true)
+          return _error->Error(_("The package index files are corrupted. No Filename: "
+                               "field for package %s."),
+@@ -103,13 +138,9 @@ bool get_archive(pkgAcquire *Owner, pkgSourceList *Sources,
+       string DestFile = directory + "/" + flNotDir(StoreFilename);
+ 
+       // Create the item
+-      new pkgAcqFile(Owner,
+-		     Index->ArchiveURI(PkgFile),
+-		     MD5,
+-		     Version->Size,
+-		     Index->ArchiveInfo(Version),
+-		     Version.ParentPkg().Name(),
+-		     "", DestFile);
++      new pkgAcqFileSane(Owner, Index->ArchiveURI(PkgFile),
++			 Index->ArchiveInfo(Version),
++			 Version.ParentPkg().Name(), DestFile);
+ 
+       Vf++;
+       return true;
+diff --git a/src/generic/apt/pkg_acqfile.h b/src/generic/apt/pkg_acqfile.h
+index 14ceeac..1403f4b 100644
+--- a/src/generic/apt/pkg_acqfile.h
++++ b/src/generic/apt/pkg_acqfile.h
+@@ -1,27 +1,30 @@
+-// pkg_acqfile.h                  -*-c++-*-
++// pkg_acqfile.h
+ //
+-//   Copyright (C) 2002, 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
++//  File acquirers that Don't Suck.
+ 
+ #include <apt-pkg/acquire-item.h>
+ 
+-/** Like pkgAcqArchive, but uses generic File objects to download to
+- *  the cwd (and copies from file:/ URLs).
+- */
++class pkgAcqFileSane:public pkgAcquire::Item
++// This is frustrating: pkgAcqFile is **almost** good enough, but has some
++// hardcoded stuff that makes it not quite work.
++//
++//  Based heavily on that class, though.
++{
++  pkgAcquire::ItemDesc Desc;
++  string Md5Hash;
++  unsigned int Retries;
++
++public:
++  pkgAcqFileSane(pkgAcquire *Owner, string URI,
++		 string Description, string ShortDesc, string filename);
++
++  void Failed(string Message, pkgAcquire::MethodConfig *Cnf);
++  string MD5Sum() {return Md5Hash;}
++  string DescURI() {return Desc.URI;}
++  virtual ~pkgAcqFileSane() {}
++};
++
++// Hack around the broken pkgAcqArchive.
+ bool get_archive(pkgAcquire *Owner, pkgSourceList *Sources,
+ 		 pkgRecords *Recs, pkgCache::VerIterator const &Version,
+ 		 std::string directory, std::string &StoreFilename);
+diff --git a/src/generic/apt/pkg_changelog.cc b/src/generic/apt/pkg_changelog.cc
+deleted file mode 100644
+index b0758d9..0000000
+--- a/src/generic/apt/pkg_changelog.cc
++++ /dev/null
+@@ -1,212 +0,0 @@
+-// pkg_changelog.cc
+-//
+-//  Copyright 2000, 2004-2005 Daniel Burrows
+-//
+-//  This program is free software; you can redistribute it and/or modify
+-//  it under the terms of the GNU General Public License as published by
+-//  the Free Software Foundation; either version 2 of the License, or
+-//  (at your option) any later version.
+-//
+-//  This program is distributed in the hope that it will be useful,
+-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-//  GNU General Public License for more details.
+-//
+-//  You should have received a copy of the GNU General Public License
+-//  along with this program; see the file COPYING.  If not, write to
+-//  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//  Boston, MA 02111-1307, USA.
+-
+-#include "pkg_changelog.h"
+-
+-#include "apt.h"
+-#include "download_manager.h"
+-#include "pkg_acqfile.h"
+-
+-#include <aptitude.h>
+-#include <config.h>
+-
+-#include <stdio.h>
+-#include <errno.h>
+-#include <unistd.h>
+-#include <fcntl.h>
+-#include <signal.h>
+-#include <sys/stat.h>
+-
+-#include <generic/util/util.h>
+-
+-#include <apt-pkg/error.h>
+-#include <apt-pkg/configuration.h>
+-#include <apt-pkg/acquire-item.h>
+-#include <apt-pkg/strutl.h>
+-
+-using namespace std;
+-
+-class download_changelog_manager : public download_manager
+-{
+-  string srcpkg;
+-  string ver;
+-  string section;
+-  string name;
+-  string uri;
+-
+-  sigc::slot1<void, temp::name> k;
+-
+-  download_signal_log *log;
+-
+-  /** The name of the file into which the changelog is downloaded. */
+-  temp::name tempname;
+-
+-  bool failed;
+-
+-
+-  /** HACK: This just overrides the failure method to catch 404s. */
+-  class AcqWithFail:public pkgAcqFile
+-  {
+-    bool &failed;
+-  public:
+-    AcqWithFail(pkgAcquire *Owner,
+-		const string &URI,
+-		const string &MD5,
+-		unsigned long Size,
+-		const string &Description,
+-		const string &ShortDesc,
+-		const string &filename,
+-		bool &_failed):
+-      pkgAcqFile(Owner, URI, MD5, Size, Description, ShortDesc, "", filename),
+-      failed(_failed)
+-    {
+-      failed=false;
+-    }
+-
+-    void Failed(string Message, pkgAcquire::MethodConfig *Cnf)
+-    {
+-      failed=true;
+-    }
+-
+-    void get_failed();
+-  };
+-
+-public:
+-  download_changelog_manager(const string &_srcpkg,
+-			     const string &_ver,
+-			     const string &_section,
+-			     const string &_name,
+-			     const sigc::slot1<void, temp::name> &_k)
+-    : srcpkg(_srcpkg), ver(_ver), section(_section), name(_name),
+-      k(_k), log(NULL), failed(false)
+-  {
+-  }
+-
+-  bool prepare(OpProgress &progress,
+-	       pkgAcquireStatus &acqlog,
+-	       download_signal_log *signallog)
+-  {
+-    log = signallog;
+-
+-    temp::dir tempdir;
+-
+-    try
+-      {
+-	tempdir = temp::dir("aptitude");
+-	tempname = temp::name(tempdir, "changelog");
+-      }
+-    catch(temp::TemporaryCreationFailure e)
+-      {
+-	_error->Error("%s", e.errmsg().c_str());
+-	return false;
+-      }
+-
+-    string realsection;
+-
+-    if(section.find('/') != section.npos)
+-      realsection.assign(section, 0, section.find('/'));
+-    else
+-      realsection.assign("main");
+-
+-    string prefix;
+-
+-    if(srcpkg.size() > 3 &&
+-       srcpkg[0] == 'l' && srcpkg[1] == 'i' && srcpkg[2] == 'b')
+-      prefix = std::string("lib") + srcpkg[3];
+-    else
+-      prefix = srcpkg[0];
+-
+-    string realver;
+-
+-    if(ver.find(':') != ver.npos)
+-      realver.assign(ver, ver.find(':')+1, ver.npos);
+-    else
+-      realver = ver;
+-
+-    uri = ssprintf("http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog",
+-		   realsection.c_str(),
+-		   prefix.c_str(),
+-		   srcpkg.c_str(),
+-		   srcpkg.c_str(),
+-		   realver.c_str());
+-
+-    fetcher = new pkgAcquire(&acqlog);
+-
+-    string title = ssprintf(_("ChangeLog of %s"), name.c_str());
+-
+-    failed = false;
+-    new AcqWithFail(fetcher,
+-		    uri,
+-		    "",
+-		    0,
+-		    title,
+-		    title,
+-		    tempname.get_name().c_str(),
+-		    failed);
+-
+-    return true;
+-  }
+-
+-  result finish(pkgAcquire::RunResult res,
+-		OpProgress &progress)
+-  {
+-    if(res != pkgAcquire::Continue || failed)
+-      {
+-	_error->Error("Couldn't fetch URL %s", uri.c_str());
+-
+-	return failure;
+-      }
+-    else
+-      {
+-	k(tempname);
+-
+-	return success;
+-      }
+-  }
+-};
+-
+-download_manager *get_changelog(pkgCache::VerIterator ver,
+-				const sigc::slot1<void, temp::name> &k)
+-{
+-  if(ver.end())
+-    return NULL;
+-
+-  if(ver.FileList().end())
+-    return NULL;
+-
+-  // Look up the source package.
+-  pkgRecords::Parser &rec =
+-    apt_package_records->Lookup(ver.FileList());
+-  string srcpkg =
+-    rec.SourcePkg().empty() ? ver.ParentPkg().Name() : rec.SourcePkg();
+-
+-  return get_changelog_from_source(srcpkg, ver.VerStr(),
+-				   ver.Section(),
+-				   ver.ParentPkg().Name(),
+-				   k);
+-}
+-
+-download_manager *get_changelog_from_source(const string &srcpkg,
+-					    const string &ver,
+-					    const string &section,
+-					    const string &name,
+-					    const sigc::slot1<void, temp::name> &k)
+-{
+-  return new download_changelog_manager(srcpkg, ver, section, name, k);
+-}
+diff --git a/src/generic/apt/pkg_changelog.h b/src/generic/apt/pkg_changelog.h
+deleted file mode 100644
+index e700a8c..0000000
+--- a/src/generic/apt/pkg_changelog.h
++++ /dev/null
+@@ -1,59 +0,0 @@
+-// pkg_changelog.h    -*-c++-*-
+-//
+-//  Copyright 2000, 2005 Daniel Burrows
+-//
+-//  This program is free software; you can redistribute it and/or modify
+-//  it under the terms of the GNU General Public License as published by
+-//  the Free Software Foundation; either version 2 of the License, or
+-//  (at your option) any later version.
+-//
+-//  This program is distributed in the hope that it will be useful,
+-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-//  GNU General Public License for more details.
+-//
+-//  You should have received a copy of the GNU General Public License
+-//  along with this program; see the file COPYING.  If not, write to
+-//  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//  Boston, MA 02111-1307, USA.
+-//
+-//  Routines to download a Debian changelog for a given package.
+-
+-#ifndef PKG_CHANGELOG_H
+-#define PKG_CHANGELOG_H
+-
+-#include <string>
+-
+-#include <generic/util/temp.h>
+-
+-#include <apt-pkg/pkgcache.h>
+-
+-#include <sigc++/slot.h>
+-
+-class download_manager;
+-
+-/** Generate a download process object that retrieves the given
+- *  package version's changelog.  When the download is complete, the
+- *  given slot will be invoked with the file to which the changelog
+- *  was downloaded as an argument.
+- */
+-download_manager *get_changelog(pkgCache::VerIterator ver,
+-				const sigc::slot1<void, temp::name> &k);
+-
+-/** Generate a download process object that retrieves a changelog for
+- *  the given source package.
+- *
+- *  \param srcpkg the source package name
+- *  \param ver the version of the source package
+- *  \param section the section of the source package
+- *  \param name the name of the package that the user provided
+- *              (e.g., the binary package that the changelog command
+- *               was executed on)
+- */
+-download_manager *get_changelog_from_source(const std::string &srcpkg,
+-					    const std::string &ver,
+-					    const std::string &section,
+-					    const std::string &name,
+-					    const sigc::slot1<void, temp::name> &k);
+-
+-#endif
+diff --git a/src/generic/apt/pkg_hier.cc b/src/generic/apt/pkg_hier.cc
+deleted file mode 100644
+index dbacd57..0000000
+--- a/src/generic/apt/pkg_hier.cc
++++ /dev/null
+@@ -1,307 +0,0 @@
+-// pkg_hier.cc
+-//
+-//  Implementation of pkg_hier.h
+-
+-#include "pkg_hier.h"
+-
+-#include <aptitude.h>
+-
+-#include "apt.h"
+-
+-#include <apt-pkg/error.h>
+-#include <apt-pkg/tagfile.h>
+-
+-using namespace std;
+-using namespace HASH_NAMESPACE;
+-
+-void pkg_hier::visit_item(pkg_hier::item *item, void *parent_data,
+-			  pkg_hier::hierarchy_realizer *realizer)
+-{
+-  realizer->realize_item(item, parent_data);
+-}
+-
+-void pkg_hier::visit_group(pkg_hier::group *group, void *parent_data,
+-			   pkg_hier::hierarchy_realizer *realizer)
+-{
+-  group::build_info *info=realizer->get_build_info(group->id);
+-
+-  if(info->active)
+-    _error->Warning(_("Warning: group %s is involved in a cycle"), group->name.c_str());
+-  else
+-    {
+-      info->active=true;
+-
+-      void *curr_data=realizer->realize_group(group, parent_data);
+-
+-      for(vector<item *>::iterator i=group->children.begin();
+-	  i!=group->children.end(); ++i)
+-	(*i)->realize_me(this, curr_data, realizer);
+-
+-      info->active=false;
+-    }
+-}
+-
+-void pkg_hier::realize_group_up(pkg_hier::group *group,
+-				pkg_hier::hierarchy_realizer *realizer)
+-{
+-  group::build_info *info=realizer->get_build_info(group->id);
+-
+-  if(info->active)
+-    _error->Warning(_("Warning: group %s is involved in a cycle"), group->name.c_str());
+-  else
+-    {
+-      info->active=true;
+-
+-      if(!info->seen)
+-	{
+-	  if(group->parents.empty())
+-	    info->node_data.push_back(realizer->realize_group(group, NULL));
+-	  else
+-	    for(hash_set<string>::iterator i=group->parents.begin();
+-		i!=group->parents.end(); ++i)
+-	      {
+-		groupmap::iterator found=groups.find(*i);
+-
+-		if(found!=groups.end())
+-		  {
+-		    // The group exists; realize it and then realize
+-		    // ourselves based on it.
+-		    realize_group_up(&found->second, realizer);
+-
+-		    group::build_info *parent_info=realizer->get_build_info(found->second.id);
+-
+-		    for(vector<void *>::iterator j=parent_info->node_data.begin();
+-			j!=parent_info->node_data.end(); ++j)
+-		      info->node_data.push_back(realizer->realize_group(group, *j));
+-		  }
+-	      }
+-
+-	  info->seen=true;
+-	}
+-
+-      info->active=false;
+-    }
+-}
+-
+-void pkg_hier::realize_item_up(pkg_hier::item *item,
+-			       pkg_hier::hierarchy_realizer *realizer)
+-{
+-  if(item->parents.empty())
+-    realizer->realize_item(item, NULL);
+-  else
+-    for(hash_set<string>::iterator i=item->parents.begin();
+-	i!=item->parents.end(); ++i)
+-      {
+-	groupmap::iterator found=groups.find(*i);
+-
+-	if(found!=groups.end())
+-	  {
+-	    realize_group_up(&found->second, realizer);
+-
+-	    group::build_info *info=realizer->get_build_info(found->second.id);
+-
+-	    for(vector<void *>::iterator j=info->node_data.begin();
+-		j!=info->node_data.end(); ++j)
+-	      realizer->realize_item(item, *j);
+-	  }
+-      }
+-}
+-
+-bool pkg_hier::realize_item_up(string item, hierarchy_realizer *realizer)
+-{
+-  pkgmap::iterator found=pkgs.find(item);
+-
+-  if(found!=pkgs.end())
+-    {
+-      realize_item_up(&found->second, realizer);
+-      return true;
+-    }
+-  else
+-    return false;
+-}
+-
+-void pkg_hier::item::realize_me(pkg_hier *hier, void *parent_data,
+-				hierarchy_realizer *realizer)
+-{
+-  hier->visit_item(this, parent_data, realizer);
+-}
+-
+-void pkg_hier::group::realize_me(pkg_hier *hier, void *parent_data,
+-				 hierarchy_realizer *realizer)
+-{
+-  hier->visit_group(this, parent_data, realizer);
+-}
+-
+-// TODO: display a progress meter?
+-void pkg_hier::input_file(string fn)
+-{
+-  FileFd f;
+-
+-  f.Open(fn, FileFd::ReadOnly);
+-
+-  if(!f.IsOpen())
+-    {
+-      _error->Error(_("Cannot open package hierarchy file %s"), fn.c_str());
+-      return;
+-    }
+-
+-  pkgTagFile tagfile(&f);
+-  pkgTagSection section;
+-
+-  bool first=true;
+-  string realm;
+-
+-  while(tagfile.Step(section))
+-    {
+-      unsigned long tmp=0;
+-      section.FindFlag("Global", tmp, 1);
+-
+-      if(tmp)
+-	{
+-	  if(first)
+-	    realm=section.FindS("Realm");
+-	  else
+-	    {
+-	      _error->Warning(_("Global block encountered after first record, ignoring"));
+-	    }
+-
+-	  first=false;
+-	}
+-      else
+-	{
+-	  first=false;
+-
+-	  string pkgname=section.FindS("Package");
+-	  string groupname=section.FindS("Group");
+-
+-	  if(pkgname=="" && groupname=="")
+-	    _error->Warning(_("Bad record encountered (no Package or Group entry), skipping"));
+-	  else if(pkgname!="" && groupname!="")
+-	    _error->Warning(_("Bad record encountered (Package=%s, Group=%s), skipping"), pkgname.c_str(), groupname.c_str());
+-	  else
+-	    {
+-	      string parents=section.FindS("Parents");
+-	      vector<string> parent_list;
+-
+-	      string::size_type start=0, firstcomma=0;
+-
+-	      while(1)
+-		{
+-		  while(firstcomma<parents.size() && parents[firstcomma]!=',')
+-		    ++firstcomma;
+-
+-		  if(firstcomma!=start)
+-		    {
+-		      if(firstcomma==parents.size())
+-			{
+-			  parent_list.push_back(string(parents, start));
+-			  break;
+-			}
+-		      else
+-			parent_list.push_back(string(parents, start,
+-						     firstcomma-start));
+-		    }
+-		  else if(firstcomma==parents.size())
+-		    break;
+-
+-		  while(firstcomma<parents.size() &&
+-			(parents[firstcomma]==' ' ||
+-			 parents[firstcomma]=='\t' ||
+-			 parents[firstcomma]==','))
+-		    ++firstcomma;
+-
+-		  start=firstcomma;
+-		}
+-
+-	      // Here we actually insert the package into our map
+-	      if(pkgname!="")
+-		{
+-		  pkgmap::iterator found=pkgs.find(pkgname);
+-
+-		  if(found!=pkgs.end())
+-		    for(vector<string>::iterator i=parent_list.begin();
+-			i!=parent_list.end(); ++i)
+-		      found->second.parents.insert(*i);
+-
+-		  else
+-		    pkgs[pkgname]=item(pkgname, parent_list);
+-		}
+-	      else
+-		{
+-		  string description=section.FindS("Description");
+-
+-		  groupmap::iterator found=groups.find(groupname);
+-
+-		  if(found!=groups.end())
+-		    {
+-		      for(vector<string>::iterator i=parent_list.begin();
+-			  i!=parent_list.end(); ++i)
+-			if(found->second.parents.find(*i)==found->second.parents.end())
+-			  found->second.parents.insert(*i);
+-
+-		      if(description!="" && found->second.description!="")
+-			_error->Warning(_("Multiple descriptions found for group %s, ignoring one"), groupname.c_str());
+-		      else if(description!="")
+-			found->second.description=description;
+-		    }
+-		  else
+-		    groups[groupname]=group(groupname, max_group_id++,
+-					    parent_list, description);
+-		}
+-	    }
+-	}
+-    }
+-}
+-
+-void pkg_hier::realize(string grp, void *init_parent_data,
+-		       hierarchy_realizer *realizer)
+-{
+-  groupmap::iterator found=groups.find(grp);
+-
+-  if(found!=groups.end())
+-    {
+-      // Resolve all dangling references (and bail out if we have loops?)
+-
+-      // First, resolve references between groups.
+-      for(groupmap::iterator i=groups.begin(); i!=groups.end(); ++i)
+-	i->second.children.clear();
+-
+-      for(groupmap::iterator i=groups.begin(); i!=groups.end(); ++i)
+-	for(hash_set<string>::iterator j=i->second.parents.begin();
+-	    j!=i->second.parents.end();
+-	    ++j)
+-	  {
+-	    groupmap::iterator target=groups.find(*j);
+-
+-	    if(target!=groups.end())
+-	      target->second.children.push_back(&i->second);
+-	  }
+-
+-      // Now, resolve references from packages to groups.
+-      for(pkgmap::iterator i=pkgs.begin(); i!=pkgs.end(); ++i)
+-	for(hash_set<string>::iterator j=i->second.parents.begin();
+-	    j!=i->second.parents.end();
+-	    ++j)
+-	  {
+-	    groupmap::iterator target=groups.find(*j);
+-
+-	    if(target!=groups.end())
+-	      target->second.children.push_back(&i->second);
+-	  }
+-
+-      // Now, visit stuff.
+-      found->second.realize_me(this, init_parent_data, realizer);
+-    }
+-}
+-
+-void pkg_hier::clear()
+-{
+-  pkgs.clear();
+-  groups.clear();
+-
+-  max_group_id=0;
+-}
+-
+-pkg_hier::~pkg_hier()
+-{
+-}
+diff --git a/src/generic/apt/pkg_hier.h b/src/generic/apt/pkg_hier.h
+deleted file mode 100644
+index 424f0bf..0000000
+--- a/src/generic/apt/pkg_hier.h
++++ /dev/null
+@@ -1,217 +0,0 @@
+-// pkg-hier.h               -*-c++-*-
+-//
+-//  Copyright 2001 Daniel Burrows
+-//
+-//  This file allows a "package hierarchy" as described in README.hier to
+-// be loaded and constructed.  Any number of files can be read into the
+-// database; then, the database is "realized" as a tree using two virtual
+-// callback routines.  (you should override them in a subclass to get
+-// any specific behavior you need)
+-//
+-//  Important note: once you start "realizing" the database, adding new
+-// nodes via input_file results in undefined behavior.
+-//
+-//  Second important note: Mixing top-down and bottom-up realization results
+-// in undefined behavior.
+-//
+-//  With the bottom-up realization, the caller may manually set a "seen"
+-// flag on a group to make it appear to be a "root".  (the caller should
+-// also set the node_data values if this is doine)  Also, for root nodes,
+-// realize_* will be called with a NULL parent_data argument.
+-
+-#ifndef PKG_HIER_H
+-#define PKG_HIER_H
+-
+-#ifdef HAVE_CONFIG_H
+-#include <config.h>
+-#endif
+-
+-#ifdef HAVE_HASH_MAP
+-#include <hash_map>
+-#else
+-#ifdef HAVE_EXT_HASH_MAP
+-#include <ext/hash_map>
+-#else
+-// Fallback to the non-hashing map class
+-#include <map>
+-#define hash_map map
+-#endif
+-#endif
+-
+-#ifdef HAVE_HASH_SET
+-#include <hash_set>
+-#else
+-#ifdef HAVE_EXT_HASH_SET
+-#include <ext/hash_set>
+-#else
+-#include <set>
+-#define hash_set set
+-#endif
+-#endif
+-
+-#include <generic/util/strhash.h>
+-
+-#include <string>
+-#include <vector>
+-
+-class pkg_hier
+-{
+-public:
+-  class hierarchy_realizer;
+-
+-  struct group;
+-
+-  struct item
+-  {
+-    std::string name;
+-    HASH_NAMESPACE::hash_set<std::string> parents;
+-
+-    // HACK: Used to build the hierarchy top-down.  Calls an appropriate
+-    // routine in the given hierarchy class.  parent_data is an opaque
+-    // value which stores data used to build the UI representation of
+-    // the tree.  It is associated with the parent of this node.
+-    virtual void realize_me(pkg_hier *hier, void *parent_data,
+-			    pkg_hier::hierarchy_realizer *realizer);
+-
+-    item(std::string _name, std::vector<std::string> &_parents)
+-      :name(_name)
+-    {
+-      for(std::vector<std::string>::iterator i=_parents.begin();
+-	  i!=_parents.end();
+-	  ++i)
+-	parents.insert(*i);
+-    }
+-
+-    item(std::string _name)
+-      :name(_name)
+-    {
+-    }
+-
+-    item() {}
+-
+-    virtual ~item() {}
+-  };
+-
+-  struct group:public item
+-  {
+-    std::string description;
+-
+-    // Stores this group's integer ID.
+-    int id;
+-
+-    // Used in the final stage of building the hierarchy:
+-    std::vector<item *> children;
+-
+-    // This structure stores dynamic information about the group which is
+-    // used while building a hierarchy.  The realizer stores one of these
+-    // for each group.
+-    struct build_info
+-    {
+-      // Similarly -- used to avoid cycles
+-      bool active;
+-
+-      // Similarly -- allows values to be cached.  (there may be multiple
+-      // values here if there are multiple parents)
+-      std::vector<void *> node_data;
+-
+-      // This is true iff node_data has already been calculated.
+-      bool seen;
+-
+-      build_info():active(false), seen(false) {}
+-    };
+-
+-    void realize_me(pkg_hier *hier, void *parent_data,
+-			    pkg_hier::hierarchy_realizer *realizer);
+-
+-    group(std::string _name, int _id, std::vector<std::string> &_parents,
+-	  std::string _description)
+-      :item(_name, _parents), description(_description), id(_id)
+-    {
+-    }
+-
+-    group():item(), id(0)
+-    {
+-    }
+-  };
+-
+-  friend struct item;
+-  friend struct group;
+-
+-  // Used so that group numbers are contiguous and unique
+-  int max_group_id;
+-
+-  typedef HASH_NAMESPACE::hash_map<std::string, item> pkgmap;
+-  typedef HASH_NAMESPACE::hash_map<std::string, group> groupmap;
+-
+-  pkgmap pkgs;
+-  groupmap groups;
+-
+-  class hierarchy_realizer
+-  {
+-  protected:
+-    pkg_hier::group::build_info *groupinfo;
+-    pkg_hier *hier;
+-
+-    void reset_groupinfo()
+-      // To be used if, eg, the realization needs to be performed again
+-      // with the same realizer.
+-    {
+-      delete[] groupinfo;
+-      groupinfo=new pkg_hier::group::build_info[hier->groups.size()];
+-    }
+-  public:
+-    hierarchy_realizer(pkg_hier *_hier):hier(_hier)
+-    {
+-      groupinfo=new pkg_hier::group::build_info[hier->groups.size()];
+-    }
+-
+-    pkg_hier::group::build_info *get_build_info(int group_num)
+-    {
+-      return groupinfo+group_num;
+-    }
+-
+-    // These routines should construct any UI state associated with the
+-    // given item or group.  realize_group returns the value which will
+-    // be used as parent_data for that group's children.
+-    virtual void realize_item(item *item, void *parent_data)=0;
+-    virtual void *realize_group(group *group, void *parent_data)=0;
+-
+-    virtual ~hierarchy_realizer()
+-    {
+-      delete[] groupinfo;
+-    }
+-  };
+-
+-private:
+-  // HACK: I don't like Visitor setups, but I'm in a hurry and it'll
+-  // be good enough..
+-  void visit_item(item *item, void *parent_data, hierarchy_realizer *realizer);
+-  void visit_group(group *group, void *parent_data, hierarchy_realizer *realizer);
+-
+-  // Helper routines for bottom-up realization
+-  void realize_group_up(group *group, hierarchy_realizer *realizer);
+-  void realize_item_up(item *item, hierarchy_realizer *realizer);
+-public:
+-  pkg_hier():max_group_id(0) {}
+-
+-  // Reads the given file and adds it to our database.
+-  void input_file(std::string fn);
+-
+-  // Generates a top-down postfix hierarchy beginning at the given group.
+-  void realize(std::string grp, void *init_parent_data,
+-	       hierarchy_realizer *_realizer);
+-
+-  // Generates part of a bottom-up hierarchy beginning at the given item.
+-  // May be called successively to add more items to the hierarchy.
+-  //
+-  // Returns false if the item is not in the database at all.
+-  bool realize_item_up(std::string item, hierarchy_realizer *_realizer);
+-
+-  // Clears all information stored in this object (invalidates group * and
+-  // item * pointers!)
+-  void clear();
+-
+-  virtual ~pkg_hier();
+-};
+-
+-#endif
+diff --git a/src/generic/apt/pkg_hier_dump.cc b/src/generic/apt/pkg_hier_dump.cc
+deleted file mode 100644
+index 57e892c..0000000
+--- a/src/generic/apt/pkg_hier_dump.cc
++++ /dev/null
+@@ -1,209 +0,0 @@
+-// pkg_hier_dump.cc
+-//
+-//  A test program for the hierarchy stuff.
+-
+-#include "pkg_hier.h"
+-
+-#include <stdio.h>
+-
+-#include <apt-pkg/error.h>
+-
+-using namespace std;
+-
+-class text_hier_realizer:public pkg_hier::hierarchy_realizer
+-{
+-public:
+-  struct node
+-  {
+-    string text;
+-    int depth;
+-
+-    node(string _text, int _depth):text(_text), depth(_depth) {}
+-
+-    virtual void print(bool do_sort)
+-    {
+-      for(int lvl=depth; lvl>0; --lvl)
+-	printf("|   ");
+-
+-      printf("| %s\n", text.c_str());
+-    }
+-
+-    virtual ~node() {}
+-  };
+-
+-  struct node_cmp
+-  {
+-  public:
+-    bool operator()(node *a, node *b)
+-    {
+-      return a->text<b->text;
+-    }
+-  };
+-
+-  struct group_node:public node
+-  {
+-    vector<node *> children;
+-    string description;
+-
+-    group_node(string _text, string _description, int _depth)
+-      :node(_text, _depth), description(_description) {}
+-
+-    virtual void print(bool do_sort)
+-    {
+-      for(int lvl=depth; lvl>0; --lvl)
+-	printf("|   ");
+-
+-      printf("+-%s: %s\n", text.c_str(), description.c_str());
+-
+-      if(do_sort)
+-	sort(children.begin(), children.end(), node_cmp());
+-
+-      for(vector<node *>::iterator i=children.begin(); i!=children.end(); ++i)
+-	(*i)->print(do_sort);
+-    }
+-
+-    ~group_node()
+-    {
+-      for(vector<node *>::iterator i=children.begin(); i!=children.end(); ++i)
+-	delete *i;
+-    }
+-  };
+-private:
+-  vector<node *> roots;
+-  bool verbose;
+-  bool do_sort;
+-protected:
+-  void realize_item(pkg_hier::item *item, void *parent_data)
+-  {
+-    group_node *parent=(group_node *) parent_data;
+-
+-    if(verbose)
+-      printf("Making %sitem '%s'\n", parent?"":"root ", item->name.c_str());
+-
+-    if(parent)
+-      parent->children.push_back(new node(item->name, parent->depth+1));
+-    else
+-      roots.push_back(new node(item->name, 0));
+-  }
+-
+-  void *realize_group(pkg_hier::group *group, void *parent_data)
+-  {
+-    group_node *parent=(group_node *) parent_data;
+-
+-    if(verbose)
+-      printf("Making %sgroup '%s'\n", parent?"":"root ", group->name.c_str());
+-
+-    group_node *rval=new group_node(group->name, group->description,
+-				    parent?parent->depth+1:0);
+-
+-    if(parent)
+-      parent->children.push_back(rval);
+-    else
+-      roots.push_back(rval);
+-
+-    return rval;
+-  }
+-
+-public:
+-  text_hier_realizer(pkg_hier *_hier, bool _verbose, bool _do_sort)
+-    :hierarchy_realizer(_hier), verbose(_verbose), do_sort(_do_sort) {}
+-
+-  void print()
+-  {
+-    if(do_sort)
+-      sort(roots.begin(), roots.end(), node_cmp());
+-
+-    for(vector<node *>::iterator i=roots.begin(); i!=roots.end(); ++i)
+-      (*i)->print(do_sort);
+-  }
+-
+-  virtual ~text_hier_realizer()
+-  {
+-    for(vector<node *>::iterator i=roots.begin(); i!=roots.end(); ++i)
+-      delete *i;
+-  }
+-};
+-
+-int main(int argc, char *argv[])
+-{
+-  pkg_hier hier;
+-  bool verbose=false;
+-  bool do_sort=false;
+-
+-  if(argc<2)
+-    fprintf(stderr, "pkg_hier_dump: no arguments!\n");
+-  else if(!strcmp(argv[1], "-b"))
+-    {
+-      vector<string> items;
+-
+-      if(argc<4)
+-	fprintf(stderr, "Not enough arguments; need at least 3\n");
+-
+-      hier.input_file(argv[2]);
+-
+-      for(int i=3; i<argc; ++i)
+-	{
+-	  // -f file for more input files
+-	  if(!strcmp(argv[i], "-f") && i<argc-1)
+-	    {
+-	      ++i;
+-	      hier.input_file(argv[i]);
+-	    }
+-	  else if(!strcmp(argv[i], "-v"))
+-	    verbose=true;
+-	  else if(!strcmp(argv[i], "-s"))
+-	    do_sort=true;
+-	  else
+-	    items.push_back(argv[i]);
+-	}
+-
+-      text_hier_realizer realizer(&hier, verbose, do_sort);
+-
+-      for(vector<string>::size_type i=0; i<items.size(); ++i)
+-	hier.realize_item_up(items[i], &realizer);
+-
+-      realizer.print();
+-    }
+-  else
+-    {
+-      vector<string> roots;
+-
+-      if(argc<2)
+-	{
+-	  fprintf(stderr, "Not enough arguments; need at least 1\n");
+-	  exit(-1);
+-	}
+-
+-      hier.input_file(argv[1]);
+-
+-      for(int i=2; i<argc; ++i)
+-	{
+-	  if(!strcmp(argv[i], "-f") && i<argc-1)
+-	    {
+-	      hier.input_file(argv[i+1]);
+-	      ++i;
+-	    }
+-	  else if(!strcmp(argv[i], "-v"))
+-	    verbose=true;
+-	  else if(!strcmp(argv[i], "-s"))
+-	    do_sort=true;
+-	  else
+-	    roots.push_back(argv[i]);
+-	}
+-
+-      text_hier_realizer realizer(&hier, verbose, do_sort);
+-
+-      if(!roots.empty())
+-	for(vector<string>::size_type i=0; i<roots.size(); ++i)
+-	  hier.realize(roots[i], NULL, &realizer);
+-      else
+-	for(pkg_hier::groupmap::iterator i=hier.groups.begin();
+-	    i!=hier.groups.end(); ++i)
+-	  if(i->second.parents.empty())
+-	    hier.realize(i->second.name, NULL, &realizer);
+-
+-      realizer.print();
+-    }
+-
+-  _error->DumpErrors();
+-}
+diff --git a/src/generic/apt/resolver_manager.cc b/src/generic/apt/resolver_manager.cc
+deleted file mode 100644
+index 2aecc0b..0000000
+--- a/src/generic/apt/resolver_manager.cc
++++ /dev/null
+@@ -1,928 +0,0 @@
+-// resolver_manager.cc
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#include "resolver_manager.h"
+-
+-#include "apt.h"
+-#include "aptitude_resolver.h"
+-#include "aptitude_resolver_universe.h"
+-#include "config_signal.h"
+-
+-#include <generic/problemresolver/problemresolver.h>
+-#include <generic/util/undo.h>
+-
+-#include <sigc++/functors/mem_fun.h>
+-
+-// NB: we need a recursive mutex because some routines can be called
+-// either by other routines of the class (already have a mutex lock)
+-// or by the user (don't have a mutex lock); I could sidestep this
+-// with some clever magic, but there's no point unless it turns out to
+-// be a bottleneck.
+-resolver_manager::resolver_manager(aptitudeDepCache *_cache)
+-  :cache(_cache),
+-   resolver(NULL),
+-   undos(new undo_list),
+-   selected_solution(0),
+-   background_thread_killed(false),
+-   background_thread_running(false),
+-   resolver_null(true),
+-   background_thread_suspend_count(0),
+-   background_thread_in_resolver(false),
+-   resolver_thread(NULL),
+-   mutex(threads::mutex::attr(PTHREAD_MUTEX_RECURSIVE))
+-{
+-  cache->pre_package_state_changed.connect(sigc::mem_fun(this, &resolver_manager::discard_resolver));
+-  cache->package_state_changed.connect(sigc::mem_fun(this, &resolver_manager::maybe_create_resolver));
+-
+-  aptcfg->connect(PACKAGE "::Recommends-Important",
+-		  sigc::mem_fun(this,
+-				&resolver_manager::discard_resolver));
+-
+-  start_background_thread();
+-
+-  maybe_create_resolver();
+-}
+-
+-resolver_manager::~resolver_manager()
+-{
+-  eassert(background_thread_running);
+-
+-  discard_resolver();
+-
+-  kill_background_thread();
+-
+-  for(unsigned int i = 0; i < solutions.size(); ++i)
+-    delete solutions[i];
+-
+-  delete undos;
+-}
+-
+-resolver_manager::background_continuation::~background_continuation()
+-{
+-}
+-
+-class resolver_manager::background_suspender
+-{
+-  resolver_manager &m;
+-
+-  bool suspended;
+-public:
+-  background_suspender(resolver_manager &_m)
+-    :m(_m), suspended(true)
+-  {
+-    m.suspend_background_thread();
+-  }
+-
+-  void unsuspend()
+-  {
+-    if(suspended)
+-      {
+-	m.unsuspend_background_thread();
+-	suspended = false;
+-      }
+-  }
+-
+-  ~background_suspender()
+-  {
+-    if(suspended)
+-      m.unsuspend_background_thread();
+-  }
+-};
+-
+-/** A class that assigns a value to an object when it is destroyed.
+- */
+-template<typename T>
+-class set_when_destroyed
+-{
+-  T &target;
+-  T val;
+-
+-public:
+-  /** Create a set_when_destroyed.
+-   *
+-   *  \param _target The object to be set.
+-   *  \param _val The value to assign to _target.
+-   */
+-  set_when_destroyed(T &_target, const T &_val)
+-    : target(_target), val(_val)
+-  {
+-  }
+-
+-  /** Assign val to target. */
+-  ~set_when_destroyed()
+-  {
+-    target = val;
+-  }
+-};
+-
+-// This assumes that background_resolver_active is empty when it
+-// starts (see restart_background_resolver)
+-//
+-// FIXME: max_steps should be changed when the configuration is (not a
+-// visible bug at the moment since you can't change that option
+-// interactively)
+-void resolver_manager::background_thread_execution()
+-{
+-  threads::mutex::lock l(background_control_mutex);
+-  set_when_destroyed<bool> cancel_set_running(background_thread_running, false);
+-
+-  while(1)
+-    {
+-      while((background_thread_suspend_count > 0 || resolver_null || pending_jobs.empty()) &&
+-	    !background_thread_killed)
+-	background_control_cond.wait(l);
+-
+-      if(background_thread_killed)
+-	break;
+-
+-      job_request job = pending_jobs.top();
+-      pending_jobs.pop();
+-      background_thread_in_resolver = true;
+-      background_resolver_cond.wake_all();
+-      l.release();
+-
+-      try
+-	{
+-	  aptitude_resolver::solution *sol = do_get_solution(job.max_steps,
+-							     job.sol_num);
+-
+-	  // Set the state variable BEFORE exiting the resolver; this
+-	  // is done so that if there are no more jobs, the foreground
+-	  // thread sees that we're out of the resolver when it
+-	  // examines the solution.
+-	  l.acquire();
+-	  background_thread_in_resolver = false;
+-	  background_resolver_cond.wake_all();
+-	  l.release();
+-
+-	  job.k->success(*sol);
+-	}
+-      catch(InterruptedException)
+-	{
+-	  // Put it back into the pot.
+-	  l.acquire();
+-	  background_thread_in_resolver = false;
+-	  background_resolver_cond.wake_all();
+-	  pending_jobs.push(job);
+-
+-	  // HACK: protect job.k from deletion.
+-	  job.k = NULL;
+-	  l.release();
+-	}
+-      catch(NoMoreSolutions)
+-	{
+-	  l.acquire();
+-	  background_thread_in_resolver = false;
+-	  background_resolver_cond.wake_all();
+-	  l.release();
+-
+-	  job.k->no_more_solutions();
+-	}
+-      catch(NoMoreTime)
+-	{
+-	  l.acquire();
+-	  background_thread_in_resolver = false;
+-	  background_resolver_cond.wake_all();
+-	  l.release();
+-
+-	  job.k->no_more_time();
+-	}
+-      catch(Exception &e)
+-	{
+-	  std::cerr << "*** Uncaught exception in resolver thread:" << std::endl;
+-	  std::cerr << e.errmsg() << std::endl;
+-	  abort();
+-	}
+-
+-      l.acquire();
+-      delete job.k;
+-
+-      background_thread_in_resolver = false;
+-      background_resolver_cond.wake_all();
+-    }
+-}
+-
+-// Need this because sigc slots aren't threadsafe :-(
+-struct resolver_manager::background_thread_bootstrap
+-{
+-  resolver_manager &m;
+-public:
+-  background_thread_bootstrap(resolver_manager &_m)
+-    :m(_m)
+-  {
+-  }
+-
+-  void operator()()
+-  {
+-    m.background_thread_execution();
+-  }
+-};
+-
+-void resolver_manager::start_background_thread()
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  if(resolver_thread == NULL)
+-    {
+-      background_thread_running = true;
+-      resolver_thread = new threads::thread(background_thread_bootstrap(*this));
+-    }
+-}
+-
+-void resolver_manager::kill_background_thread()
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  if(resolver_thread != NULL)
+-    {
+-      threads::mutex::lock control_lock(background_control_mutex);
+-
+-      if(resolver != NULL)
+-	resolver->cancel_solver();
+-      background_thread_killed = true;
+-      background_control_cond.wake_all();
+-
+-      control_lock.release();
+-
+-      resolver_thread->join();
+-      delete resolver_thread;
+-      resolver_thread = NULL;
+-
+-
+-      // Reset the associated data structures.
+-      control_lock.acquire();
+-      pending_jobs = std::priority_queue<job_request, std::vector<job_request>, job_request_compare>();
+-      background_thread_killed = false;
+-      background_thread_suspend_count = 0;
+-      background_thread_in_resolver = false;
+-    }
+-}
+-
+-void resolver_manager::suspend_background_thread()
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  // May occur due to background_suspend objects existing while
+-  // kill_background_thread runs.
+-  if(resolver_thread == NULL)
+-    return;
+-
+-  threads::mutex::lock control_lock(background_control_mutex);
+-
+-  if(resolver != NULL)
+-    resolver->cancel_solver();
+-
+-  ++background_thread_suspend_count;
+-  background_control_cond.wake_all();
+-
+-  while(background_thread_in_resolver)
+-    background_resolver_cond.wait(control_lock);
+-
+-  if(resolver != NULL)
+-    resolver->uncancel_solver();
+-}
+-
+-void resolver_manager::unsuspend_background_thread()
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  if(resolver_thread == NULL)
+-    return;
+-
+-  threads::mutex::lock control_lock(background_control_mutex);
+-
+-  eassert(background_thread_suspend_count > 0);
+-  --background_thread_suspend_count;
+-  background_control_cond.wake_all();
+-}
+-
+-void resolver_manager::maybe_create_resolver()
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  if(resolver == NULL && cache->BrokenCount() > 0)
+-    create_resolver();
+-
+-  // Always signal a state change: we are signalling for the whole
+-  // discard/create pair, and even if we didn't create a new resolver
+-  // we have to inform the listeners that the old one went away
+-  // (maybe).
+-  l.release();
+-  state_changed();
+-}
+-
+-void resolver_manager::discard_resolver()
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  if(resolver == NULL)
+-    return;
+-
+-  background_suspender bs(*this);
+-
+-  undos->clear_items();
+-
+-  delete resolver;
+-
+-  {
+-    threads::mutex::lock l2(solutions_mutex);
+-    solutions.clear();
+-    selected_solution = 0;
+-  }
+-
+-  resolver = NULL;
+-
+-  {
+-    threads::mutex::lock l2(background_control_mutex);
+-    resolver_null = true;
+-    while(!pending_jobs.empty())
+-      {
+-	delete pending_jobs.top().k;
+-	pending_jobs.pop();
+-      }
+-    background_control_cond.wake_all();
+-  }
+-}
+-
+-void resolver_manager::create_resolver()
+-{
+-  threads::mutex::lock l(mutex);
+-  eassert(resolver == NULL);
+-
+-  // NOTE: the performance of the resolver is highly sensitive to
+-  // these settings; choosing bad ones can result in hitting
+-  // exponential cases in practical situations.  In general,
+-  // penalizing actions means that the resolver will be more likely to
+-  // blow up trying to avoid them, with the danger increasing as the
+-  // penalty does.  Thus, aside from broken deps (which are penalized
+-  // to guide us towards a solution), I only penalize removals (which
+-  // are usually either unnecessary or easy to prove necessary) and
+-  // leaving soft dependencies (recommendations) unfixed.  The
+-  // relative penalties of these are also important; for instance,
+-  // penalizing unfixed soft deps more than removals means that the
+-  // resolver will actually remove packages rather than leaving their
+-  // Recommends: field unsatisfied!
+-
+-  resolver=new aptitude_resolver(aptcfg->FindI(PACKAGE "::ProblemResolver::StepScore", 10),
+-				 aptcfg->FindI(PACKAGE "::ProblemResolver::BrokenScore", -100),
+-				 aptcfg->FindI(PACKAGE "::ProblemResolver::UnfixedSoftScore", -200),
+-				 aptcfg->FindI(PACKAGE "::ProblemResolver::Infinity", 1000000),
+-				 aptcfg->FindI(PACKAGE "::ProblemResolver::Max-Successors", 0),
+-				 aptcfg->FindI(PACKAGE "::ProblemResolver::ResolutionScore", 50),
+-				 cache);
+-
+-  resolver->add_action_scores(aptcfg->FindI(PACKAGE "::ProblemResolver::PreserveManualScore", 60),
+-			      aptcfg->FindI(PACKAGE "::ProblemResolver::PreserveAutoScore", 0),
+-			      aptcfg->FindI(PACKAGE "::ProblemResolver::RemoveScore", -300),
+-			      aptcfg->FindI(PACKAGE "::ProblemResolver::KeepScore", 0),
+-			      aptcfg->FindI(PACKAGE "::ProblemResolver::InstallScore", -20),
+-			      aptcfg->FindI(PACKAGE "::ProblemResolver::UpgradeScore", 0),
+-			      aptcfg->FindI(PACKAGE "::ProblemResolver::NonDefaultScore", -40),
+-			      aptcfg->FindI(PACKAGE "::ProblemResolver::EssentialRemoveScore", -100000),
+-			      aptcfg->FindI(PACKAGE "::ProblemResolver::BreakHoldScore", -300));
+-
+-  resolver->add_priority_scores(aptcfg->FindI(PACKAGE "::ProblemResolver::ImportantScore", 5),
+-				aptcfg->FindI(PACKAGE "::ProblemResolver::RequiredScore", 4),
+-				aptcfg->FindI(PACKAGE "::ProblemResolver::StandardScore", 3),
+-				aptcfg->FindI(PACKAGE "::ProblemResolver::OptionalScore", 1),
+-				aptcfg->FindI(PACKAGE "::ProblemResolver::ExtraScore", -1));
+-
+-  {
+-    threads::mutex::lock l2(background_control_mutex);
+-    resolver_null = false;
+-    background_control_cond.wake_all();
+-  }
+-}
+-
+-void resolver_manager::set_debug(bool activate)
+-{
+-  threads::mutex::lock l(mutex);
+-  background_suspender bs(*this);
+-
+-  eassert(resolver_exists());
+-
+-  resolver->set_debug(activate);
+-}
+-
+-bool resolver_manager::resolver_exists() const
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  return resolver != NULL;
+-}
+-
+-unsigned int resolver_manager::generated_solution_count() const
+-{
+-  threads::mutex::lock l(mutex);
+-  threads::mutex::lock l2(solutions_mutex);
+-
+-  return solutions.size();
+-}
+-
+-bool resolver_manager::solution_generation_complete() // const
+-{
+-  return state_snapshot().solutions_exhausted;
+-}
+-
+-bool resolver_manager::solutions_at_start() const
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  if(!resolver_exists())
+-    return true;
+-  else
+-    return selected_solution == 0;
+-}
+-
+-bool resolver_manager::background_thread_active()
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  threads::mutex::lock ctl_l(background_control_mutex);
+-
+-  return !pending_jobs.empty() || background_thread_in_resolver;
+-}
+-
+-resolver_manager::state resolver_manager::state_snapshot()
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  threads::mutex::lock ctl_l(background_control_mutex);
+-
+-  threads::mutex::lock sol_l(solutions_mutex);
+-
+-  state rval;
+-
+-  rval.selected_solution        = selected_solution;
+-  rval.generated_solutions      = solutions.size();
+-  rval.resolver_exists          = (resolver != NULL);
+-  rval.background_thread_active = (!pending_jobs.empty() || background_thread_in_resolver);
+-
+-  if(resolver != NULL)
+-    {
+-      aptitude_resolver::queue_counts c = resolver->get_counts();
+-
+-      rval.open_size      = c.open;
+-      rval.closed_size    = c.closed;
+-      rval.deferred_size  = c.deferred;
+-      rval.conflicts_size = c.conflicts;
+-      rval.solutions_exhausted = (rval.open_size == 0 && c.finished);
+-    }
+-  else
+-    {
+-      rval.open_size      = 0;
+-      rval.closed_size    = 0;
+-      rval.deferred_size  = 0;
+-      rval.conflicts_size = 0;
+-
+-      rval.solutions_exhausted = false;
+-    }
+-
+-  return rval;
+-}
+-
+-aptitude_resolver::solution *resolver_manager::do_get_solution(int max_steps, unsigned int solution_num)
+-{
+-  threads::mutex::lock sol_l(solutions_mutex);
+-  if(solution_num < solutions.size())
+-    return solutions[solution_num];
+-
+-  while(solution_num >= solutions.size())
+-    {
+-      sol_l.release();
+-
+-      try
+-	{
+-	  generic_solution<aptitude_universe> sol = resolver->find_next_solution(max_steps);
+-
+-	  sol_l.acquire();
+-	  solutions.push_back(new aptitude_resolver::solution(sol.clone()));
+-	  sol_l.release();
+-	}
+-      catch(NoMoreTime)
+-	{
+-	  throw NoMoreTime();
+-	}
+-      catch(NoMoreSolutions)
+-	{
+-	  throw NoMoreSolutions();
+-	}
+-    }
+-
+-  return solutions[solution_num];
+-}
+-
+-/** A continuation that works by either placing \b true in the Boolean
+- *  variable corresponding to the thrown exception, or updating the
+- *  given solution, then signalling the given condition.  Note that
+- *  this only works because we expect to be able to
+- */
+-class solution_return_continuation : public resolver_manager::background_continuation
+-{
+-  const generic_solution<aptitude_universe> * &sol;
+-  bool &oot;
+-  bool &oos;
+-  threads::mutex &m;
+-  threads::condition &c;
+-public:
+-  solution_return_continuation(const generic_solution<aptitude_universe> * &_sol,
+-			       bool &_oot,
+-			       bool &_oos,
+-			       threads::mutex &_m,
+-			       threads::condition &_c)
+-    :sol(_sol), oot(_oot), oos(_oos), m(_m), c(_c)
+-  {
+-  }
+-
+-  void success(const generic_solution<aptitude_universe> &result)
+-  {
+-    threads::mutex::lock l(m);
+-
+-    sol = &result;
+-    c.wake_all();
+-  }
+-
+-  void no_more_time()
+-  {
+-    threads::mutex::lock l(m);
+-
+-    oot = true;
+-    c.wake_all();
+-  }
+-
+-  void no_more_solutions()
+-  {
+-    threads::mutex::lock l(m);
+-    oos = true;
+-    c.wake_all();
+-  }
+-
+-  void interrupted()
+-  {
+-    // Should never happen, since we hold the big lock.
+-    abort();
+-  }
+-};
+-
+-const aptitude_resolver::solution &resolver_manager::get_solution(unsigned int solution_num,
+-								  int max_steps)
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  eassert(resolver);
+-
+-  {
+-    threads::mutex::lock l2(solutions_mutex);
+-    if(solution_num < solutions.size())
+-      return *solutions[solution_num];
+-  }
+-
+-
+-  const generic_solution<aptitude_universe> *sol = NULL;
+-  bool oot = false;
+-  bool oos = false;
+-  threads::mutex m;
+-  threads::condition c;
+-
+-  get_solution_background(solution_num, max_steps, new solution_return_continuation(sol, oot, oos, m, c));
+-  l.release();
+-
+-  threads::mutex::lock cond_l(m);
+-
+-  while(!sol && !oot && !oos)
+-    c.wait(cond_l);
+-
+-  if(oot)
+-    throw NoMoreTime();
+-  else if(oos)
+-    throw NoMoreSolutions();
+-
+-  return *sol;
+-}
+-
+-void resolver_manager::get_solution_background(unsigned int solution_num,
+-					       int max_steps,
+-					       background_continuation *k)
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  // It's necessary to stop the background thread because we might be
+-  // decreasing the maximum number of steps to search.
+-  background_suspender bs(*this);
+-
+-  eassert(resolver_exists());
+-
+-  threads::mutex::lock sol_l(solutions_mutex);
+-  if(solution_num < solutions.size())
+-    {
+-      generic_solution<aptitude_universe> *sol = solutions[solution_num];
+-      sol_l.release();
+-
+-      k->success(*sol);
+-      return;
+-    }
+-  sol_l.release();
+-
+-
+-  threads::mutex::lock control_lock(background_control_mutex);
+-  pending_jobs.push(job_request(solution_num, max_steps, k));
+-  background_control_cond.wake_all();
+-}
+-
+-class blocking_continuation : public resolver_manager::background_continuation
+-{
+-  /** The real continuation */
+-  resolver_manager::background_continuation *k;
+-
+-  /** The solution for which we are searching. */
+-  unsigned int solution_num;
+-
+-  /** The channel through which the result should be announced. */
+-  threads::box<bool> &result_box;
+-
+-  /** The number of steps to try searching for a solution after this if
+-   *  time runs out.
+-   */
+-  int remaining_steps;
+-
+-  /** The manager associated with this continuation. */
+-  resolver_manager &m;
+-public:
+-  blocking_continuation(background_continuation *_k,
+-			unsigned int _solution_num,
+-			threads::box<bool> &_result_box,
+-			int _remaining_steps,
+-			resolver_manager &_m)
+-    : k(_k), solution_num(_solution_num), result_box(_result_box),
+-      remaining_steps(_remaining_steps), m(_m)
+-  {
+-  }
+-
+-  ~blocking_continuation()
+-  {
+-    delete k;
+-  }
+-
+-  void success(const generic_solution<aptitude_universe> &sol)
+-  {
+-    k->success(sol);
+-    result_box.put(true);
+-  }
+-
+-  void no_more_solutions()
+-  {
+-    k->no_more_solutions();
+-    result_box.put(true);
+-  }
+-
+-  void no_more_time()
+-  {
+-    m.get_solution_background(solution_num, remaining_steps, k);
+-    k = NULL;
+-    result_box.put(false);
+-  }
+-
+-  void interrupted()
+-  {
+-    result_box.put(false);
+-  }
+-};
+-
+-bool resolver_manager::get_solution_background_blocking(unsigned int solution_num,
+-							int max_steps,
+-							int block_steps,
+-							background_continuation *k)
+-{
+-  if(block_steps == 0)
+-    {
+-      get_solution_background(solution_num, max_steps, k);
+-      return false;
+-    }
+-
+-  int remaining;
+-
+-  if(block_steps < max_steps)
+-    remaining = max_steps - block_steps;
+-  else
+-    remaining = 0;
+-
+-  threads::box<bool> rbox;
+-
+-  get_solution_background(solution_num, block_steps,
+-			  new blocking_continuation(k, solution_num, rbox,
+-						    remaining, *this));
+-
+-  return rbox.take();
+-}
+-
+-template<typename T>
+-void resolver_manager::resolver_manipulation(const T &t,
+-					     void (generic_problem_resolver<aptitude_universe>::*action)(const T &, undo_group *))
+-{
+-  threads::mutex::lock l(mutex);
+-  background_suspender bs(*this);
+-
+-  undo_group *undo = new undo_group;
+-  (resolver->*action)(t, undo);
+-  if(undo->empty())
+-    delete undo;
+-  else
+-    undos->add_item(undo);
+-
+-  l.release();
+-  bs.unsuspend();
+-  state_changed();
+-}
+-
+-void resolver_manager::reject_version(const aptitude_resolver_version &ver)
+-{
+-  resolver_manipulation(ver, &aptitude_resolver::reject_version);
+-}
+-
+-void resolver_manager::unreject_version(const aptitude_resolver_version &ver)
+-{
+-  resolver_manipulation(ver, &aptitude_resolver::unreject_version);
+-}
+-
+-bool resolver_manager::is_rejected(const aptitude_resolver_version &ver)
+-{
+-  threads::mutex::lock l(mutex);
+-  eassert(resolver);
+-
+-  return resolver->is_rejected(ver);
+-}
+-
+-void resolver_manager::mandate_version(const aptitude_resolver_version &ver)
+-{
+-  resolver_manipulation(ver, &aptitude_resolver::mandate_version);
+-}
+-
+-void resolver_manager::unmandate_version(const aptitude_resolver_version &ver)
+-{
+-  resolver_manipulation(ver, &aptitude_resolver::unmandate_version);
+-}
+-
+-bool resolver_manager::is_mandatory(const aptitude_resolver_version &ver)
+-{
+-  threads::mutex::lock l(mutex);
+-  eassert(resolver);
+-
+-  return resolver->is_mandatory(ver);
+-}
+-
+-void resolver_manager::harden_dep(const aptitude_resolver_dep &dep)
+-{
+-  resolver_manipulation(dep, &aptitude_resolver::harden);
+-}
+-
+-void resolver_manager::unharden_dep(const aptitude_resolver_dep &dep)
+-{
+-  resolver_manipulation(dep, &aptitude_resolver::unharden);
+-}
+-
+-bool resolver_manager::is_hardened(const aptitude_resolver_dep &dep)
+-{
+-  threads::mutex::lock l(mutex);
+-  eassert(resolver);
+-
+-  return resolver->is_hardened(dep);
+-}
+-
+-void resolver_manager::approve_broken_dep(const aptitude_resolver_dep &dep)
+-{
+-  resolver_manipulation(dep, &aptitude_resolver::approve_break);
+-}
+-
+-void resolver_manager::unapprove_broken_dep(const aptitude_resolver_dep &dep)
+-{
+-  resolver_manipulation(dep, &aptitude_resolver::unapprove_break);
+-}
+-
+-bool resolver_manager::is_approved_broken(const aptitude_resolver_dep &dep)
+-{
+-  threads::mutex::lock l(mutex);
+-  eassert(resolver != NULL);
+-
+-  return resolver->is_approved_broken(dep);
+-}
+-
+-bool resolver_manager::has_undo_items()
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  return undos->size() > 0;
+-}
+-
+-bool resolver_manager::undo()
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  if(undos->size() > 0)
+-    {
+-      background_suspender bs(*this);
+-
+-      undos->undo();
+-
+-      bs.unsuspend();
+-      l.release();
+-
+-      state_changed();
+-
+-      return true;
+-    }
+-  else
+-    return false;
+-}
+-
+-void resolver_manager::select_solution(unsigned int solnum)
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  threads::mutex::lock sol_l(solutions_mutex);
+-  if(solnum >= 0 && solnum <= solutions.size())
+-    selected_solution = solnum;
+-  sol_l.release();
+-
+-  l.release();
+-  state_changed();
+-}
+-
+-void resolver_manager::select_next_solution()
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  threads::mutex::lock sol_l(solutions_mutex);
+-  if(selected_solution < solutions.size())
+-    ++selected_solution;
+-  sol_l.release();
+-
+-  l.release();
+-  state_changed();
+-}
+-
+-void resolver_manager::select_previous_solution()
+-{
+-  threads::mutex::lock l(mutex);
+-
+-  threads::mutex::lock sol_l(solutions_mutex);
+-  if(selected_solution > 0)
+-    --selected_solution;
+-  sol_l.release();
+-
+-  l.release();
+-  state_changed();
+-}
+-
+-void resolver_manager::tweak_score(const pkgCache::PkgIterator &pkg,
+-				   const pkgCache::VerIterator &ver,
+-				   int score)
+-{
+-  threads::mutex::lock l(mutex);
+-  background_suspender bs(*this);
+-
+-  eassert(resolver_exists());
+-  eassert(resolver->fresh());
+-
+-  resolver->add_version_score(aptitude_resolver_version(pkg, ver, cache),
+-			      score);
+-}
+-
+-void resolver_manager::dump(ostream &out)
+-{
+-  threads::mutex::lock l(mutex);
+-  background_suspender bs(*this);
+-
+-  if(!resolver_exists())
+-    return;
+-
+-  // First, dump the universe.
+-  dump_universe(resolver->get_universe(), out);
+-
+-  // Now dump the scores as a test instruction.
+-  out << "TEST " << resolver->get_step_score() << " "
+-      << resolver->get_broken_score() << " "
+-      << resolver->get_unresolved_soft_dep_score() << " "
+-      << resolver->get_infinity() << " "
+-      << resolver->get_max_successors() << " "
+-      << resolver->get_full_solution_score() << " ";
+-
+-  resolver->dump_scores(out);
+-
+-  out << "EXPECT ( " << aptcfg->FindI(PACKAGE "::Resolver::StepLimit", 5000) << " ANY )" << std::endl;
+-}
+diff --git a/src/generic/apt/resolver_manager.h b/src/generic/apt/resolver_manager.h
+deleted file mode 100644
+index f587a9c..0000000
+--- a/src/generic/apt/resolver_manager.h
++++ /dev/null
+@@ -1,520 +0,0 @@
+-// resolver_manager.h                                -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-//
+-// A higher-level resolver interface.  This code is responsible for
+-// maintaining a list of previously observed solutions, for passing
+-// certain actions on to the underlying resolver (protecting users
+-// from having to actually import the whole resolver definition), for
+-// managing the resolver in the face of cache reloads and resets, and
+-// for managing threaded access to the resolver.
+-
+-#ifndef RESOLVER_MANAGER_H
+-#define RESOLVER_MANAGER_H
+-
+-#include <generic/util/exception.h>
+-#include <generic/util/threads.h>
+-
+-#include <apt-pkg/pkgcache.h>
+-
+-#include <sigc++/signal.h>
+-#include <sigc++/trackable.h>
+-
+-#include <queue>
+-#include <vector>
+-
+-class aptitudeDepCache;
+-class aptitude_universe;
+-class aptitude_resolver_version;
+-class aptitude_resolver_dep;
+-template<typename PackageUniverse> class generic_solution;
+-template<typename PackageUniverse> class generic_problem_resolver;
+-class aptitude_resolver;
+-class undo_group;
+-class undo_list;
+-
+-/** Manages a resolver for a single cache object.  When broken
+- *  packages arise, a new resolver is created; whenever the state of a
+- *  package changes, the resolver is deleted and reset.  While a
+- *  resolver is active, users of this class can "select" a particular
+- *  solution, then "generate" it.
+- *
+- *  Solutions can be generated in a background thread, but of course
+- *  only one background thread may be running at a time.  The
+- *  solutions returned should only be accessed from one thread at a
+- *  time unless you clone() them.
+- *
+- *  Note: of course it would also be possible to simply query the
+- *  manager for the Nth solution; however, using a selection pointer
+- *  makes it easy for different UI modules to share information about
+- *  the currently selected solution.
+- */
+-class resolver_manager : public sigc::trackable
+-{
+-public:
+-  /** This class represents the continuation of get_solution() in a
+-   *  background thread.  See get_background_solution() for details.
+-   */
+-  class background_continuation
+-  {
+-  public:
+-    virtual ~background_continuation();
+-
+-    /** Invoked when a solution has been successfully generated. */
+-    virtual void success(const generic_solution<aptitude_universe> &) = 0;
+-    /** Invoked when all solutions have been exhausted (corresponds to
+-     *  the NoMoreSolutions exception).
+-     */
+-    virtual void no_more_solutions() = 0;
+-
+-    /** Invoked when time has expired. (corresponds to NoMoreTime) */
+-    virtual void no_more_time() = 0;
+-
+-    /** Invoked when the solver was interrupted. (corresponds to
+-     *  InterruptedException)
+-     */
+-    virtual void interrupted() = 0;
+-  };
+-
+-  /** A snapshot of the state of the resolver. */
+-  struct state
+-  {
+-    /** The currently selected solution. */
+-    int selected_solution;
+-
+-    /** The number of already-generated solutions. */
+-    int generated_solutions;
+-
+-    /** If \b true, then there are no more solutions to generate. */
+-    bool solutions_exhausted;
+-
+-    /** If \b true, then the resolver is not \b null (i.e., it exists;
+-     *  i.e., there are broken packages).
+-     */
+-    bool resolver_exists;
+-
+-    /** If \b true, the background thread has jobs. */
+-    bool background_thread_active;
+-
+-    /** The size of the resolver's open queue. */
+-    size_t open_size;
+-
+-    /** The size of the resolver's closed queue. */
+-    size_t closed_size;
+-
+-    /** The size of the resolver's deferred queue. */
+-    size_t deferred_size;
+-
+-    /** The number of conflicts discovered by the resolver. */
+-    size_t conflicts_size;
+-  };
+-
+-private:
+-  /** Information about a single request posted to the background
+-   *  thread.
+-   */
+-  struct job_request
+-  {
+-    /** The solution number to be calculated. */
+-    int sol_num;
+-
+-    /** The number of steps to allow for this calculation. */
+-    int max_steps;
+-
+-    /** The continuation of this computation. */
+-    background_continuation *k;
+-
+-    job_request(int _sol_num, int _max_steps, background_continuation *_k)
+-      :sol_num(_sol_num), max_steps(_max_steps), k(_k)
+-    {
+-    }
+-  };
+-
+-  /** Sort job requests by their solution number and step count. */
+-  struct job_request_compare
+-  {
+-    bool operator()(const job_request &jr1, const job_request &jr2) const
+-    {
+-      return jr1.sol_num < jr2.sol_num ||
+-	(jr1.sol_num == jr2.sol_num && jr1.max_steps < jr2.max_steps);
+-    }
+-  };
+-
+-  /** The cache file on which this manager operates. */
+-  aptitudeDepCache *cache;
+-
+-  /** The active resolver, or \b NULL if none is active. */
+-  aptitude_resolver *resolver;
+-
+-  /** An undo list for resolver-specific items.  This is cleared
+-   *  whenever the resolver is discarded.
+-   */
+-  undo_list *undos;
+-
+-  /** The solutions generated by this manager since the last change to
+-   *  the cache.
+-   */
+-  std::vector<generic_solution<aptitude_universe> *> solutions;
+-
+-  /** A lock for the list of solutions; used to allow the background
+-   *  thread to immediately post results without taking the big class
+-   *  lock (since that might be taken by stop_background_resolver())
+-   */
+-  mutable threads::mutex solutions_mutex;
+-
+-  /** The index of the currently selected solution. */
+-  unsigned int selected_solution;
+-
+-  /** The pending job requests for the background thread.
+-   */
+-  std::priority_queue<job_request, std::vector<job_request>,
+-		      job_request_compare> pending_jobs;
+-
+-  /** If \b true, the background thread should abort its execution. */
+-  bool background_thread_killed;
+-
+-  /** If \b true, the background thread is currently running. */
+-  bool background_thread_running;
+-
+-  /** If \b true, the resolver is \b NULL.  (this is used rather than
+-   *  checking the variable directly in order to make it painfully
+-   *  clear what the proper locking protocol is)
+-   */
+-  bool resolver_null;
+-
+-  /** The number of times the background thread has been suspended; it
+-   *  will only be allowed to run if this value is 0.
+-   */
+-  int background_thread_suspend_count;
+-
+-  /** If \b true, the background thread is currently running in the
+-   *  resolver; this indicates that foreground threads trying to
+-   *  suspend the background thread should wait on
+-   *  background_in_resolver_cond until this becomes \b false.
+-   */
+-  bool background_thread_in_resolver;
+-
+-  /** A lock around pending_jobs, background_thread_killed,
+-   *  background_thread_suspend_count, background_thread_in_resolver,
+-   *  and resolver_null.
+-   */
+-  threads::mutex background_control_mutex;
+-
+-  /** A condition signalled for pending_jobs,
+-   *  background_thread_killed, background_thread_suspend_count, and
+-   *  resolver_null.
+-   */
+-  threads::condition background_control_cond;
+-
+-  /** A condition signalled for background_thread_in_resolver.
+-   */
+-  threads::condition background_resolver_cond;
+-
+-  /** The thread in which a background resolver is running, or \b NULL
+-   *  if none is.
+-   */
+-  threads::thread *resolver_thread;
+-
+-  /** This lock is used to serialize all accesses to this object,
+-   *  except background_get_solution().
+-   */
+-  mutable threads::mutex mutex;
+-
+-  void discard_resolver();
+-  void create_resolver();
+-
+-  /** A class that bootstraps the routine below. */
+-  class background_thread_bootstrap;
+-  friend class background_thread_bootstrap;
+-
+-  /** A class that stops the background thread when it's created, and
+-   *  restarts it when it's destroyed.  If background_resolver_active
+-   *  is set to \b false in the meantime, the resolver won't be
+-   *  restarted.
+-   */
+-  class background_suspender;
+-  friend class background_suspender;
+-
+-  /** Low-level code to get a solution; it does not take the global
+-   *  lock, does not stop a background thread, and may run either in
+-   *  the foreground or in the background.  It is called by
+-   *  background_thread_execution and get_solution.
+-   */
+-  generic_solution<aptitude_universe> *do_get_solution(int max_steps, unsigned int solution_number);
+-
+-  /** The actual background thread. */
+-  void background_thread_execution();
+-
+-  /** Start a background thread if none exists. */
+-  void start_background_thread();
+-
+-  /** Destroy the background thread completely and reset its control
+-   *  parameters.  Waits until the thread has terminated to return.
+-   *
+-   *  If no thread exists, do nothing.
+-   *
+-   *  \warning This routine must only be invoked by the
+-   *  resolver_manager destructor; the resolver thread should survive
+-   *  until the resolver manager is destroyed.
+-   */
+-  void kill_background_thread();
+-
+-  /** Increments the suspend count of the background thread, and (if
+-   *  necessary) interrupts a running resolution and waits for the
+-   *  thread to leave the resolver.
+-   */
+-  void suspend_background_thread();
+-
+-  /** Decrements the suspend count of the background thread, and (if
+-   *  necessary) unsuspends it.
+-   */
+-  void unsuspend_background_thread();
+-
+-  /** Create a resolver if necessary. */
+-  void maybe_create_resolver();
+-
+-  /** Collects common code for the resolver manipulations such as
+-   *  reject_version, unreject_version, etc: locks this class,
+-   *  suspends the resolver, runs the manipulation and adds any undo
+-   *  that is generated to the undo list, and finally executes
+-   *  state_changed().
+-   */
+-  template<typename T>
+-  void resolver_manipulation(const T &t,
+-			     void (generic_problem_resolver<aptitude_universe>::*action)(const T &, undo_group *));
+-public:
+-  /** Create a new resolver manager for the given cache file. */
+-  resolver_manager(aptitudeDepCache *cache);
+-
+-  virtual ~resolver_manager();
+-
+-  /** If \b true, then a resolver has been created, indicating that
+-   *  problems may exist in the cache.
+-   */
+-  bool resolver_exists() const;
+-
+-
+-  /** Requires that resolver_exists() is \b true.
+-   *
+-   *  \param activate if \b true, enable debugging to cout.  Any
+-   *  change to the state of any package will reset this to the
+-   *  default (off).  \todo allow any ostream.
+-   */
+-  void set_debug(bool activate);
+-
+-  /** The number of solutions generated. */
+-  unsigned int generated_solution_count() const;
+-
+-  /** Get the selection location, which will be in the range
+-   *  [0,generated_solution_count()).  Note that this is meaningless
+-   *  if generated_solution_count==0.
+-   */
+-  unsigned int get_selected_solution() const {return selected_solution;}
+-
+-  /** Requires that resolver_exists() is \b true.  Return the solution
+-   *  in the given position, generating it if it is past the end of
+-   *  the list; will continue a search even if it ran out of time
+-   *  previously.
+-   *
+-   *  If solution_num refers to an already-generated solution, this
+-   *  routine returns immediately (without suspending the thread).
+-   *
+-   *  \throw NoMoreSolutions if the list of solutions is exhausted
+-   *  \throw NoMoreTime if time is exhausted while searching for
+-   *                    the solution (time here is counted separately
+-   *                    at each step).
+-   *  \throw ResolverManagerThreadClashException if a new solution
+-   *         would be generated and a background thread exists.
+-   */
+-  const generic_solution<aptitude_universe> &get_solution(unsigned int solution_num,
+-							  int max_steps);
+-
+-  /** As get_solution, but run in a background thread if necessary.
+-   *
+-   *  \param solution_num the solution to retrieve
+-   *
+-   *  \param max_steps the number of steps to allow the computation
+-   *
+-   *  \param k a background_continuation object; when the background
+-   *  computation is finished, a method corresponding to its result
+-   *  will be invoked on continuation in the background thread.  It is
+-   *  safe for this method to manipulate the resolver (for instance,
+-   *  to enqueue a new computation).
+-   *
+-   *  k is owned by this object and will be deleted at its discretion.
+-   *
+-   *  \throw ResolverManagerThreadClashException if a background
+-   *         resolver already exists.
+-   */
+-  void get_solution_background(unsigned int solution_num,
+-			       int max_steps,
+-			       background_continuation *k);
+-
+-  /** Like get_solution_background, but blocks until the background
+-   *  solver has \i either found a solution or examined at least
+-   *  block_count solutions.
+-   *
+-   *  \param solution_num the solution to retrieve
+-   *
+-   *  \param max_steps the number of steps to allow the computation
+-   *
+-   *  \param block_count the number of steps to wait before returning
+-   *
+-   *  \return \b true if the search terminated in block_count steps or
+-   *  less
+-   */
+-  bool get_solution_background_blocking(unsigned int solution_num,
+-					int max_steps,
+-					int block_count,
+-					background_continuation *k);
+-
+-  /** If \b true, all solutions have been generated.  This is equivalent
+-   *  to the solutions_exhausted member of the state snapshot.
+-   */
+-  bool solution_generation_complete() /*const*/;
+-
+-  /** If \b true, the solution pointer is set to the first
+-   *  solution.
+-   */
+-  bool solutions_at_start() const;
+-
+-  /** If \b true, the background thread is working on a job. */
+-  bool background_thread_active();
+-
+-  /** Get a snapshot of the current resolver state; contains the
+-   *  values that would be returned by get_selected_solution(),
+-   *  generated_solution_count(), and solutions_exhausted(); however,
+-   *  this snapshot is taken atomically.
+-   */
+-  state state_snapshot();
+-
+-
+-
+-  /** Requires that resolver_exists() is \b true.  Temporarily rejects
+-   *  any solutions generated by the currently active installer that
+-   *  involve installing the given version; the rejection will be
+-   *  discarded when the resolver is.
+-   */
+-  void reject_version(const aptitude_resolver_version &ver);
+-
+-  /** Requires that resolver_exists() is \b true.  Cancels a
+-   *  rejection created via resolver_reject_version().
+-   */
+-  void unreject_version(const aptitude_resolver_version &ver);
+-
+-  /** Requires the resolver_exists() is \b true.  Returns \b true if
+-   *  the given version is currently rejected.
+-   */
+-  bool is_rejected(const aptitude_resolver_version &ver);
+-
+-  /** Requires that resolver_exists() is \b true.  Like
+-   *  resolver_reject_version, but rejects any solution that does \b
+-   *  not install the given version.
+-   */
+-  void mandate_version(const aptitude_resolver_version &ver);
+-
+-  /** Cancels a resolver_mandate_version call. */
+-  void unmandate_version(const aptitude_resolver_version &ver);
+-
+-  /** \return \b true if the given version is mandatory. */
+-  bool is_mandatory(const aptitude_resolver_version &ver);
+-
+-  /** Requires that resolver_exists is \b true.  Force the resolver to
+-   *  treat the given soft dependency as a hard dependency; as above,
+-   *  you can always cancel this instruction later.
+-   */
+-  void harden_dep(const aptitude_resolver_dep &dep);
+-
+-  /** Cancels a resolver_harden_dep call. */
+-  void unharden_dep(const aptitude_resolver_dep &dep);
+-
+-  /** \return \b true if the given dep is hardened. */
+-  bool is_hardened(const aptitude_resolver_dep &dep);
+-
+-  /** Require the resolver to leave the given soft dependency broken
+-   *  whenever possible.
+-   */
+-  void approve_broken_dep(const aptitude_resolver_dep &dep);
+-
+-  /** Cancel an approval set up with approve_broken(). */
+-  void unapprove_broken_dep(const aptitude_resolver_dep &dep);
+-
+-  /** \return \b true if the given dependency is in the
+-   *  approved-broken set.
+-   */
+-  bool is_approved_broken(const aptitude_resolver_dep &dep);
+-
+-
+-
+-  /** \return \b true if undo items exist in this resolver manager. */
+-  bool has_undo_items();
+-
+-  /** If this resolver has any undo items, invoke the "topmost" one.
+-   *
+-   *  \return \b true if an undo item was invoked.
+-   */
+-  bool undo();
+-
+-
+-  /** Set the selection pointer to a particular solution. */
+-  void select_solution(unsigned int solnum);
+-
+-  /** Move the selection pointer to the next solution, without
+-   *  generating it.
+-   */
+-  void select_next_solution();
+-
+-  /** Move the selection pointer to the previous solution, without
+-   *  generating it.
+-   *
+-   *  \throws NoMoreSolutions if solutions_at_start()
+-   */
+-  void select_previous_solution();
+-
+-  /** Tweak the resolver score of a particular package/version.  This
+-   *  requires that resolver_exists() and that the resolver is "fresh"
+-   *  (i.e., that next_solution() and current_solution() have never
+-   *  been called)
+-   *
+-   *  \param pkg the package to adjust
+-   *  \param ver the version to adjust
+-   *  \param score an adjustment to be added to the score of pkg:ver
+-   */
+-  void tweak_score(const pkgCache::PkgIterator &pkg,
+-		   const pkgCache::VerIterator &ver,
+-		   int score);
+-
+-  /** If a resolver exists, write its state (including scores, etc)
+-   *  to the given stream.
+-   */
+-  void dump(std::ostream &out);
+-
+-  /** This signal is emitted when the selected solution changes, when
+-   *  the user takes an action that might change the number of
+-   *  available solutions (such as un-rejecting a package), and when a
+-   *  new resolver is created.
+-   *
+-   *  Note that this is NOT signalled when a new solution is added to
+-   *  the solution list by the background thread.  You are free to
+-   *  manually emit the signal, but of course be aware of threading
+-   *  considerations if you do so.
+-   */
+-  sigc::signal0<void> state_changed;
+-};
+-
+-#endif
+diff --git a/src/generic/apt/tags.cc b/src/generic/apt/tags.cc
+deleted file mode 100644
+index 52f6de1..0000000
+--- a/src/generic/apt/tags.cc
++++ /dev/null
+@@ -1,310 +0,0 @@
+-// tags.cc
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#include "tags.h"
+-
+-#include <aptitude.h>
+-
+-#include "apt.h"
+-#include "config_signal.h"
+-
+-#include <algorithm>
+-#include <map>
+-#include <utility>
+-
+-#include <ctype.h>
+-#include <string.h>
+-
+-#include <sigc++/functors/mem_fun.h>
+-
+-#include <apt-pkg/error.h>
+-#include <apt-pkg/pkgrecords.h>
+-#include <apt-pkg/tagfile.h>
+-
+-#include <generic/util/eassert.h>
+-
+-using namespace std;
+-
+-tag::tag(std::string::const_iterator start,
+-	 std::string::const_iterator finish)
+-{
+-  while(start != finish && isspace(*start))
+-    ++start;
+-
+-  while(start != finish && isspace(*(finish-1)))
+-    --finish;
+-
+-  s.assign(start, finish);
+-}
+-
+-tag::const_iterator &tag::const_iterator::operator++()
+-{
+-  start = finish;
+-  while(start != limit && (*start)==':')
+-    ++start;
+-
+-  if(start == limit)
+-    finish = limit;
+-  else
+-    {
+-      finish = start+1;
+-      while(finish != limit && (*finish) != ':')
+-	++finish;
+-    }
+-
+-  return *this;
+-}
+-
+-tag::const_iterator tag::begin() const
+-{
+-  tag::const_iterator rval(s.begin(), s.begin(), s.end());
+-
+-  ++rval;
+-
+-  return rval;
+-}
+-
+-int tag::cmp(const tag &other) const
+-{
+-  const_iterator myT=begin(), otherT=other.begin();
+-
+-  while(myT != end() && otherT != other.end())
+-    {
+-      // ew, rather slow
+-      if(lexicographical_compare(myT.start, myT.finish,
+-				 otherT.start, otherT.finish))
+-	return -1;
+-      else if(lexicographical_compare(otherT.start, otherT.finish,
+-				      myT.start, myT.finish))
+-	return 1;
+-
+-      ++myT;
+-      ++otherT;
+-    }
+-
+-  if(otherT != other.end())
+-    return -1;
+-  else if(myT != end())
+-    return 1;
+-  else
+-    return 0;
+-}
+-
+-tag_list::const_iterator &tag_list::const_iterator::operator++()
+-{
+-  start = finish;
+-
+-  while(start != limit && (*start) != ',')
+-    ++start;
+-
+-  if(start != limit) // Push past the comma.
+-    ++start;
+-
+-  if(start == limit)
+-    finish = limit;
+-  else
+-    {
+-      // Eat everything up to the next comma.
+-      finish = start+1;
+-      while(finish != limit && (*finish) != ',')
+-	++finish;
+-    }
+-
+-  return *this;
+-}
+-
+-tag_list::const_iterator tag_list::begin() const
+-{
+-  std::string::const_iterator endfirst=s.begin();
+-  while(endfirst != s.end() && (*endfirst) != ',')
+-    ++endfirst;
+-
+-  const_iterator rval(s.begin(), endfirst, s.end());
+-  return rval;
+-}
+-
+-typedef set<tag> db_entry;
+-
+-// The database is built eagerly, since the common use case is
+-// to scan everything in sight right away and this makes it easy
+-// to provide a progress bar to the user.
+-db_entry *tagDB;
+-
+-static void insert_tags(const pkgCache::VerIterator &ver,
+-			const pkgCache::VerFileIterator &vf)
+-{
+-  set<tag> *tags = tagDB + ver.ParentPkg()->ID;
+-
+-  const char *recstart=0, *recend=0;
+-  const char *tagstart, *tagend;
+-  pkgTagSection sec;
+-
+-  eassert(apt_package_records);
+-  eassert(tagDB);
+-
+-  apt_package_records->Lookup(vf).GetRec(recstart, recend);
+-  if(!recstart || !recend)
+-    return;
+-  if(!sec.Scan(recstart, recend-recstart+1))
+-    return;
+-
+-  if(!sec.Find("Tag", tagstart, tagend))
+-    return;
+-
+-  tag_list lst(tagstart, tagend);
+-
+-  for(tag_list::const_iterator t=lst.begin(); t!=lst.end(); ++t)
+-    tags->insert(*t);
+-}
+-
+-static void reset_tags()
+-{
+-  delete[] tagDB;
+-  tagDB = NULL;
+-}
+-
+-const set<tag> *get_tags(const pkgCache::PkgIterator &pkg)
+-{
+-  if(!apt_cache_file || !tagDB)
+-    return NULL;
+-
+-  return tagDB + pkg->ID;
+-}
+-
+-bool initialized_reset_signal;
+-void load_tags(OpProgress &progress)
+-{
+-  eassert(apt_cache_file && apt_package_records);
+-
+-  if(!initialized_reset_signal)
+-    {
+-      cache_closed.connect(sigc::ptr_fun(reset_tags));
+-      cache_reload_failed.connect(sigc::ptr_fun(reset_tags));
+-      initialized_reset_signal = true;
+-    }
+-
+-  tagDB = new db_entry[(*apt_cache_file)->Head().PackageCount];
+-
+-  std::vector<loc_pair> verfiles;
+-
+-  for(pkgCache::PkgIterator p = (*apt_cache_file)->PkgBegin();
+-      !p.end(); ++p)
+-    for(pkgCache::VerIterator v = p.VersionList(); !v.end(); ++v)
+-      for(pkgCache::VerFileIterator vf = v.FileList();
+-	  !vf.end(); ++vf)
+-	verfiles.push_back(loc_pair(v, vf));
+-
+-  sort(verfiles.begin(), verfiles.end(), location_compare());
+-
+-  progress.OverallProgress(0, verfiles.size(), 1,
+-			   _("Building tag database"));
+-  size_t n=0;
+-  for(std::vector<loc_pair>::iterator i=verfiles.begin();
+-      i!=verfiles.end(); ++i)
+-    {
+-      insert_tags(i->first, i->second);
+-      ++n;
+-      progress.OverallProgress(n, verfiles.size(), 1, _("Building tag database"));
+-    }
+-
+-  progress.Done();
+-}
+-
+-
+-
+-
+-// TAG VOCABULARY FILE
+-typedef map<string, string> facet_description_map;
+-typedef map<string, string> tag_description_map;
+-
+-facet_description_map *facet_descriptions;
+-tag_description_map *tag_descriptions;
+-
+-static void init_vocabulary()
+-{
+-  if(facet_descriptions != NULL)
+-    {
+-      eassert(tag_descriptions != NULL);
+-      return;
+-    }
+-
+-  facet_descriptions = new facet_description_map;
+-  tag_descriptions = new tag_description_map;
+-
+-  FileFd F(aptcfg->FindFile("DebTags::Vocabulary", "/var/lib/debtags/vocabulary"),
+-	   FileFd::ReadOnly);
+-
+-  if(!F.IsOpen())
+-    {
+-      _error->Warning(_("Unable to load debtags vocabulary, perhaps debtags is not installed?"));
+-      // Fail silently; debtags need not be installed.
+-      return;
+-    }
+-
+-  pkgTagFile tagfile(&F);
+-
+-  pkgTagSection sec;
+-
+-  while(tagfile.Step(sec))
+-    {
+-      string facet;
+-      const char *start, *end;
+-
+-      if(sec.Find("Facet", start, end))
+-	{
+-	  facet.assign(start, end-start);
+-
+-	  if(sec.Find("Description", start, end))
+-	    (*facet_descriptions)[facet] = string(start, end-start);
+-	}
+-      else if(sec.Find("Tag", start, end))
+-	{
+-	  string tag(start, end-start);
+-
+-	  if(sec.Find("Description", start, end))
+-	    (*tag_descriptions)[tag] = string(start, end-start);
+-	}
+-    }
+-}
+-
+-string facet_description(const std::string &facet)
+-{
+-  init_vocabulary();
+-
+-  facet_description_map::const_iterator found =
+-    facet_descriptions->find(facet);
+-
+-  if(found == facet_descriptions->end())
+-    return string();
+-  else
+-    return found->second;
+-}
+-
+-string tag_description(const std::string &tag)
+-{
+-  init_vocabulary();
+-
+-  tag_description_map::const_iterator found =
+-    tag_descriptions->find(tag);
+-
+-  if(found == tag_descriptions->end())
+-    return string();
+-  else
+-    return found->second;
+-}
+diff --git a/src/generic/apt/tags.h b/src/generic/apt/tags.h
+deleted file mode 100644
+index 9e18867..0000000
+--- a/src/generic/apt/tags.h
++++ /dev/null
+@@ -1,207 +0,0 @@
+-// tags.h                                            -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-//
+-// A parser for tags.
+-
+-#ifndef TAGS_H
+-#define TAGS_H
+-
+-#include <set>
+-#include <string>
+-
+-#include <apt-pkg/pkgcache.h>
+-
+-class OpProgress;
+-
+-class tag
+-{
+-  std::string s;
+-
+-  int cmp(const tag &other) const;
+-public:
+-  class const_iterator
+-  {
+-    std::string::const_iterator start, finish, limit;
+-
+-    friend class tag;
+-  public:
+-    const_iterator(const std::string::const_iterator &_start,
+-		   const std::string::const_iterator &_finish,
+-		   const std::string::const_iterator &_limit)
+-      :start(_start), finish(_finish), limit(_limit)
+-    {
+-    }
+-
+-    const_iterator &operator++();
+-
+-    const_iterator &operator=(const const_iterator &other)
+-    {
+-      start = other.start;
+-      finish = other.finish;
+-      limit = other.limit;
+-
+-      return *this;
+-    }
+-
+-    bool operator==(const const_iterator &other) const
+-    {
+-      return start == other.start && finish == other.finish && limit == other.limit;
+-    }
+-
+-    bool operator!=(const const_iterator &other) const
+-    {
+-      return start != other.start || finish != other.finish || limit != other.limit;
+-    }
+-
+-    std::string operator*() const
+-    {
+-      return std::string(start, finish);
+-    }
+-  };
+-
+-  tag(std::string::const_iterator _start,
+-      std::string::const_iterator _finish);
+-
+-  tag &operator=(const tag &other)
+-  {
+-    s = other.s;
+-
+-    return *this;
+-  }
+-
+-  bool operator<(const tag &other) const
+-  {
+-    return cmp(other) < 0;
+-  }
+-
+-  bool operator<=(const tag &other) const
+-  {
+-    return cmp(other) <= 0;
+-  }
+-
+-  bool operator==(const tag &other) const
+-  {
+-    return cmp(other) == 0;
+-  }
+-
+-  bool operator!=(const tag &other) const
+-  {
+-    return cmp(other) != 0;
+-  }
+-
+-  bool operator>(const tag &other) const
+-  {
+-    return cmp(other) > 0;
+-  }
+-
+-  bool operator>=(const tag &other) const
+-  {
+-    return cmp(other) >= 0;
+-  }
+-
+-  const_iterator begin() const;
+-  const_iterator end() const
+-  {
+-    return const_iterator(s.end(), s.end(), s.end());
+-  }
+-
+-  std::string str() const
+-  {
+-    return s;
+-  }
+-};
+-
+-class tag_list
+-{
+-  // The string to parse.
+-  std::string s;
+-public:
+-  class const_iterator
+-  {
+-    std::string::const_iterator start, finish, limit;
+-  public:
+-    const_iterator(const std::string::const_iterator &_start,
+-		   const std::string::const_iterator &_finish,
+-		   const std::string::const_iterator &_limit)
+-      :start(_start), finish(_finish), limit(_limit)
+-    {
+-    }
+-
+-    const_iterator operator=(const const_iterator &other)
+-    {
+-      start = other.start;
+-      finish = other.finish;
+-      limit = other.limit;
+-
+-      return *this;
+-    }
+-
+-    bool operator==(const const_iterator &other)
+-    {
+-      return other.start == start && other.finish == finish && other.limit == limit;
+-    }
+-
+-    bool operator!=(const const_iterator &other)
+-    {
+-      return other.start != start || other.finish != finish || other.limit != limit;
+-    }
+-
+-    const_iterator &operator++();
+-
+-    tag operator*()
+-    {
+-      return tag(start, finish);
+-    }
+-  };
+-
+-  tag_list(const char *start, const char *finish)
+-    :s(start, finish)
+-  {
+-  }
+-
+-  tag_list &operator=(const tag_list &other)
+-  {
+-    s=other.s;
+-
+-    return *this;
+-  }
+-
+-  const_iterator begin() const;
+-  const_iterator end() const
+-  {
+-    return const_iterator(s.end(), s.end(), s.end());
+-  }
+-};
+-
+-// Grab the tags for the given package:
+-const std::set<tag> *get_tags(const pkgCache::PkgIterator &pkg);
+-
+-// Load tags for all packages (call before get_tags)
+-void load_tags(OpProgress &progress);
+-
+-
+-
+-// Interface to the tag vocabulary file; tag vocabularies are assumed
+-// to not change over time.
+-std::string facet_description(const std::string &facet);
+-
+-// Here "Tag" is a fully qualified tag name.
+-std::string tag_description(const std::string &tag);
+-
+-#endif
+diff --git a/src/generic/apt/tasks.cc b/src/generic/apt/tasks.cc
+deleted file mode 100644
+index 3536eea..0000000
+--- a/src/generic/apt/tasks.cc
++++ /dev/null
+@@ -1,344 +0,0 @@
+-// tasks.cc
+-//
+-//  Copyright 2001 Daniel Burrows
+-
+-#include "tasks.h"
+-#include "apt.h"
+-
+-#include <aptitude.h>
+-
+-#include <apt-pkg/error.h>
+-#include <apt-pkg/pkgrecords.h>
+-#include <apt-pkg/tagfile.h>
+-
+-#include <generic/util/eassert.h>
+-#include <errno.h>
+-
+-#include <ctype.h>
+-
+-// Don't bother with hashing.
+-#include <map>
+-#include <vector>
+-#include <algorithm>
+-#include <sstream>
+-
+-using namespace std;
+-
+-map<string, task> *task_list=new map<string, task>;
+-
+-// This is an array indexed by package ID, managed by load_tasks.
+-// (as usual, it's initialized to NULL)
+-list<string> *tasks_by_package;
+-
+-// Now this is just a wrapper, as you can see..
+-std::list<std::string> *get_tasks(const pkgCache::PkgIterator &pkg)
+-{
+-  if(!tasks_by_package)
+-    return NULL;
+-
+-  return tasks_by_package+pkg->ID;
+-}
+-
+-// Thanks to Jason for pointing me to the methods that are necessary
+-// to do this.
+-static void update_tasks(const pkgCache::PkgIterator &pkg,
+-			 const pkgCache::VerFileIterator &verfile)
+-{
+-  // This should never be called before load_tasks has initialized the
+-  // tasks structure.
+-  eassert(tasks_by_package);
+-
+-  list<string> &lst=tasks_by_package[pkg->ID];
+-
+-  lst.clear();
+-
+-  if(apt_package_records)
+-    {
+-      const char *start,*stop;
+-      pkgTagSection sec;
+-
+-      // Pull out pointers to the underlying record.
+-      apt_package_records->Lookup(verfile).GetRec(start, stop);
+-
+-      // Parse it as a section.
+-      sec.Scan(start, stop-start+1);
+-
+-      string tasks=sec.FindS("Task");
+-
+-      string::size_type loc=0, firstcomma=0;
+-
+-      // Strip leading whitespace
+-      while(loc<tasks.size() && isspace(tasks[loc]))
+-	++loc;
+-
+-      while( (firstcomma=tasks.find(',', loc))!=tasks.npos)
+-	{
+-	  // Strip trailing whitespace
+-	  string::size_type loc2=firstcomma-1;
+-	  while(isspace(tasks[loc2]))
+-	    --loc2;
+-	  ++loc2;
+-
+-	  lst.push_back(string(tasks, loc, loc2-loc));
+-	  loc=firstcomma+1;
+-
+-	  // Strip leading whitespace
+-	  while(loc<tasks.size() && isspace(tasks[loc]))
+-	    ++loc;
+-	}
+-
+-      if(loc!=tasks.size())
+-	lst.push_back(string(tasks, loc));
+-    }
+-}
+-
+-bool task::keys_present()
+-{
+-  if(!keys_present_cache_stale)
+-    return keys_present_cache;
+-
+-  keys_present_cache_stale=false;
+-
+-  for(list<string>::const_iterator i=keys.begin(); i!=keys.end(); ++i)
+-    {
+-      pkgCache::PkgIterator pkg=(*apt_cache_file)->FindPkg(*i);
+-
+-      if(pkg.end())
+-	{
+-	  keys_present_cache=false;
+-	  return false;
+-	}
+-      else
+-	// Here it is assumed that all the tasks are loaded, because
+-	// we're going to look them up.
+-	{
+-	  list<string> *tasks=get_tasks(pkg);
+-
+-	  if(!tasks)
+-	    {
+-	      keys_present_cache=false;
+-	      return false;
+-	    }
+-
+-	  bool present=false;
+-
+-	  for(list<string>::const_iterator j=tasks->begin();
+-	      j!=tasks->end(); ++j)
+-	    if(*j==name)
+-	      {
+-		present=true;
+-		break;
+-	      }
+-
+-	  if(!present)
+-	    {
+-	      keys_present_cache=false;
+-	      return false;
+-	      break;
+-	    }
+-	}
+-    }
+-
+-  keys_present_cache=true;
+-  return true;
+-}
+-
+-static string rfc822_process_paragraph(const string &textdomain,
+-				       string par)
+-{
+-  if (par.empty())
+-    return par;
+-
+-  // Remove trailing whitespace
+-  string::size_type loc = par.size()-1;
+-  while(isspace(par[loc]))
+-    --loc;
+-  par.erase(loc+1, string::npos);
+-
+-  return dgettext(textdomain.c_str(), par.c_str());
+-}
+-
+-/** Returns msgid translated in the given text domain, with
+- *  appropriate munging: paragraphs are translated individually after
+- *  one leading and all trailing whitespace on each line is stripped.
+- *
+- *  \param textdomain the domain in which to translate
+- *  \param msgid the formatted description which should be translated
+- */
+-static string rfc822dgettext(string textdomain, string msgid)
+-{
+-  if (textdomain.empty())
+-    return msgid;
+-  string::size_type start=0, len=msgid.size(), nextnl=0;
+-
+-  string thispar = "";
+-  string msgstr = "";
+-
+-  // Remove leading whitespaces, i.e. replace "\n " by '\n'
+-  //
+-  // This assumes the trailing whitespace exists already.
+-  do
+-    {
+-      if (nextnl<len)
+-	nextnl=msgid.find('\n', start);
+-      if (nextnl==string::npos)
+-	nextnl=len-1;
+-      string thisline(msgid, start+1, nextnl-start);
+-      thispar+=thisline;
+-      start=nextnl+1;
+-    }
+-  while (start<len);
+-
+-  // Reformat text (replace '\n' by ' ') and translate individual
+-  // paragraphs
+-  bool verbatimline = (thispar[0] == ' ');
+-  string::size_type loc=0;
+-  start=0, len=thispar.size(), nextnl=0;
+-  while((nextnl=thispar.find('\n', loc))!=string::npos)
+-    {
+-      // Verbatim line case
+-      if (thispar[nextnl+1] == ' ')
+-	verbatimline = true;
+-      // End of the paragraph
+-      else if (thispar[nextnl+1] == '.' && thispar[nextnl+2] == '\n')
+-	{
+-	  /* Translate current paragraph */
+-	  msgstr+=rfc822_process_paragraph(textdomain, string(thispar, start, nextnl-start));
+-	  msgstr+="\n.\n";
+-	  start = nextnl + 3;
+-	  nextnl += 2;
+-	  verbatimline = false;
+-	}
+-      // Add to the paragraph
+-      else
+-	{
+-	  if (!verbatimline)
+-	    thispar[nextnl] = ' ';
+-	  verbatimline = false;
+-	}
+-      loc = nextnl + 1;
+-    }
+-  msgstr+=rfc822_process_paragraph(textdomain, string(thispar, start));
+-  // Remove trailing whitespace
+-  loc=msgstr.size()-1;
+-  while(isspace(msgstr[loc]))
+-    --loc;
+-  ++loc;
+-  msgstr[loc] = '\0';
+-  // Reformat text, i.e. replace '\n' by "\n "
+-  start = 0;
+-  while((nextnl=msgstr.find('\n', start))!=string::npos)
+-    {
+-      msgstr.insert(nextnl+1, " ");
+-      start = nextnl+2;
+-    }
+-  return msgstr;
+-}
+-
+-void load_tasks(OpProgress &progress)
+-{
+-  // Build a list for each package of the tasks that package belongs to.
+-  //
+-  // Sorting by location on disk is *critical* -- otherwise, this operation
+-  // will take ages.
+-
+-  // This is done prior to loading the task descriptions so that I can just
+-  // bail if that fails.
+-
+-  vector<loc_pair> versionfiles;
+-
+-  for(pkgCache::PkgIterator pkg=(*apt_cache_file)->PkgBegin();
+-      !pkg.end(); ++pkg)
+-    {
+-      const pkgCache::VerIterator v=pkg.VersionList();
+-
+-      if(!v.end() && !v.FileList().end())
+-	versionfiles.push_back(loc_pair(v,  v.FileList()));
+-    }
+-
+-  sort(versionfiles.begin(), versionfiles.end(), location_compare());
+-
+-  // Allocate and set up the table of task information.
+-  delete[] tasks_by_package;
+-  tasks_by_package=new list<string>[(*apt_cache_file)->Head().PackageCount];
+-
+-  for(vector<loc_pair>::iterator i=versionfiles.begin();
+-      i!=versionfiles.end();
+-      ++i)
+-    update_tasks(i->first.ParentPkg(), i->second);
+-
+-  FileFd task_file;
+-
+-  // Load the task descriptions:
+-  task_file.Open("/usr/share/tasksel/debian-tasks.desc", FileFd::ReadOnly);
+-
+-  if(!task_file.IsOpen())
+-    {
+-      _error->Discard();
+-
+-      // Allow the task file not to exist (eg, the user might not have
+-      // tasksel installed)
+-      if(errno!=ENOENT)
+-	_error->Errno("load_tasks",
+-		      _("Unable to open /usr/share/tasksel/debian-tasks.desc"));
+-
+-      return;
+-    }
+-
+-  int file_size=task_file.Size();
+-  int amt=0;
+-  progress.OverallProgress(0, file_size, 1, _("Reading task descriptions"));
+-
+-  pkgTagFile tagfile(&task_file);
+-  pkgTagSection section;
+-  string taskdomain="debian-tasks";
+-
+-  while(tagfile.Step(section))
+-    {
+-      task newtask;
+-      string desc;
+-      string taskname=section.FindS("Task");
+-
+-      if(!taskname.empty())
+-	{
+-	  istringstream keystr(section.FindS("Key"));
+-
+-	  keystr >> ws;
+-
+-	  while(!keystr.eof())
+-	    {
+-	      string s;
+-
+-	      keystr >> ws >> s >> ws;
+-
+-	      newtask.keys.push_back(s);
+-	    }
+-
+-	  newtask.name=taskname;
+-	  newtask.section=section.FindS("Section");
+-	  newtask.relevance=section.FindI("Relevance", 5);
+-
+-	  desc=section.FindS("Description");
+-
+-	  string::size_type newline=desc.find('\n');
+-	  newtask.shortdesc=dgettext(taskdomain.c_str(), string(desc, 0, newline).c_str());
+-	  newtask.longdesc=string("\n ");
+-	  newtask.longdesc+=rfc822dgettext(taskdomain, string(desc, newline+1));
+-
+-	  (*task_list)[taskname]=newtask;
+-	}
+-
+-      amt+=section.size();
+-      progress.OverallProgress(amt, file_size, 1, _("Reading task descriptions"));
+-    }
+-  progress.OverallProgress(file_size, file_size, 1, _("Reading task descriptions"));
+-
+-  progress.Done();
+-}
+-
+-void reset_tasks()
+-{
+-  task_list->clear();
+-  delete[] tasks_by_package;
+-  tasks_by_package=NULL;
+-}
+diff --git a/src/generic/apt/tasks.h b/src/generic/apt/tasks.h
+deleted file mode 100644
+index 46ce83e..0000000
+--- a/src/generic/apt/tasks.h
++++ /dev/null
+@@ -1,47 +0,0 @@
+-// tasks.h             -*-c++-*-
+-//
+-//  Copyright 2001 Daniel Burrows
+-//
+-//  Handles parsing the list of tasks and getting the task of a given
+-// package.
+-
+-#include <string>
+-#include <list>
+-#include <map>
+-#include <apt-pkg/pkgcache.h>
+-
+-class OpProgress;
+-
+-class task
+-{
+-private:
+-  bool keys_present_cache;
+-  bool keys_present_cache_stale;
+-public:
+-  task():keys_present_cache(false), keys_present_cache_stale(true) {}
+-
+-  std::string name;
+-  std::string section;
+-  std::string shortdesc;
+-  std::string longdesc;
+-  std::list<std::string> keys;
+-
+-  bool keys_present();
+-
+-  int relevance;
+-};
+-
+-// The caller should **NOT** delete the list.
+-std::list<std::string> *get_tasks(const pkgCache::PkgIterator &pkg);
+-
+-// Stores the various tasks.
+-extern std::map<std::string, task> *task_list;
+-
+-// (re)loads in the current list of available tasks.  Necessary after a
+-// cache reload, for obvious reasons.  apt_reload_cache will call this.
+-void load_tasks(OpProgress &progress);
+-
+-// Discards the current task list and readies a new one to be loaded.
+-// Since the task list contains package iterators, we have to do something
+-// in case they're still hanging around.
+-void reset_tasks();
+diff --git a/src/generic/problemresolver/Makefile.am b/src/generic/problemresolver/Makefile.am
+deleted file mode 100644
+index 26ecefd..0000000
+--- a/src/generic/problemresolver/Makefile.am
++++ /dev/null
+@@ -1,11 +0,0 @@
+-INCLUDES = -Wall @WERROR@ -I$(top_builddir) -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/src
+-
+-EXTRA_DIST=model.tex test1.txt test3.txt test4.txt resolver_undo.h
+-
+-noinst_PROGRAMS=test
+-
+-test_LDADD = $(top_builddir)/src/generic/util/libgeneric-util.a
+-
+-test_SOURCES=test.cc dump_universe.h \
+-	dummy_universe.cc dummy_universe.h \
+-	exceptions.h problemresolver.h solution.h
+diff --git a/src/generic/problemresolver/dummy_universe.cc b/src/generic/problemresolver/dummy_universe.cc
+deleted file mode 100644
+index 517919e..0000000
+--- a/src/generic/problemresolver/dummy_universe.cc
++++ /dev/null
+@@ -1,358 +0,0 @@
+-// dummy_universe.cc
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#include "dummy_universe.h"
+-
+-using namespace std;
+-
+-dummy_package::dummy_package(const string &_name, unsigned int id)
+-  :name(_name), ID(id)
+-{
+-}
+-
+-dummy_package::~dummy_package()
+-{
+-  for(version_iterator i=versions.begin(); i!=versions.end(); ++i)
+-    delete *i;
+-}
+-
+-dummy_version *dummy_package::version_from_name(const string &the_name) const
+-{
+-  for(version_iterator i=versions.begin(); i!=versions.end(); ++i)
+-    if((*i)->get_name()==the_name)
+-      return *i;
+-
+-  throw NoSuchNameError("version of package "+name, the_name);
+-}
+-
+-struct ver_ptr_name_lt
+-{
+-public:
+-  bool operator()(const dummy_version *v1,
+-		  const dummy_version *v2) const
+-  {
+-    int pncmp = v1->get_package().get_name().compare(v2->get_package().get_name());
+-
+-    if(pncmp != 0)
+-      return pncmp < 0;
+-    else
+-      return v1->get_name() < v2->get_name();
+-  }
+-};
+-
+-dummy_dep::dummy_dep(dummy_version *_source,
+-		     const std::vector<dummy_version *> &_target_set,
+-		     unsigned int _ID, bool _soft)
+-  :source(_source), target_set(_target_set), ID(_ID), soft(_soft)
+-{
+-
+-  sort(target_set.begin(), target_set.end(),
+-       ver_ptr_name_lt());
+-}
+-
+-bool dummy_dep::broken() const
+-{
+-  if(source->get_package().current_version() != *source)
+-    return false;
+-
+-  for(solver_iterator i=target_set.begin();
+-      i!=target_set.end(); ++i)
+-    if((*i)->get_package().current_version() == **i)
+-      return false;
+-
+-  return true;
+-}
+-
+-bool dummy_universe::dep::solved_by(const version &ver) const
+-{
+-  if(ver.get_package() == get_source().get_package() &&
+-     ver != get_source())
+-    return true;
+-
+-  for(dummy_dep::solver_iterator i = real_dep->solvers_begin();
+-      i != real_dep->solvers_end(); ++i)
+-    if(version(*i) == ver)
+-      return true;
+-
+-  return false;
+-}
+-
+-dummy_universe::~dummy_universe()
+-{
+-  for(vector<dummy_package *>::const_iterator i=packages.begin();
+-      i!=packages.end(); ++i)
+-    delete *i;
+-
+-  for(vector<dummy_dep *>::const_iterator i=deps.begin();
+-      i!=deps.end(); ++i)
+-    delete *i;
+-}
+-
+-
+-void dummy_universe::add_package(const string &name,
+-				 vector<string> the_versions,
+-				 const string &curname)
+-{
+-  eassert(!the_versions.empty());
+-
+-  packages.push_back(new dummy_package(name, packages.size()));
+-
+-  for(vector<string>::const_iterator i=the_versions.begin();
+-      i!=the_versions.end(); ++i)
+-    {
+-      versions.push_back(new dummy_version(*i, packages.back(), versions.size()));
+-      packages.back()->add_version(versions.back());
+-    }
+-
+-  packages.back()->set_current_version(packages.back()->version_from_name(curname));
+-
+-  packages_by_name[name]=packages.back();
+-}
+-
+-void dummy_universe::add_dep(const string &pkg_name, const string &pkg_ver,
+-			     const vector<pair<string, string> > &target_names,
+-			     bool is_conflict, bool is_soft)
+-{
+-  dummy_package *pkg=find_package_internal(pkg_name);
+-
+-  set<dummy_version *, compare_dummy_versions> targets;
+-  set<dummy_package *, compare_dummy_packages> packages;
+-
+-  for(vector<pair<string, string> >::const_iterator i=target_names.begin();
+-      i!=target_names.end(); ++i)
+-    {
+-      dummy_package *pkg=find_package_internal(i->first);
+-
+-      packages.insert(pkg);
+-      targets.insert(pkg->version_from_name(i->second));
+-    }
+-
+-  if(!is_conflict)
+-    deps.push_back(new dummy_dep(pkg->version_from_name(pkg_ver),
+-				 vector<dummy_version *>(targets.begin(), targets.end()),
+-				 deps.size(),
+-				 is_soft));
+-  else
+-    {
+-      set<dummy_version *> targets2;
+-
+-      for(set<dummy_package *>::const_iterator i=packages.begin();
+-	  i!=packages.end(); ++i)
+-	for(dummy_package::version_iterator j=(*i)->versions_begin();
+-	    j!=(*i)->versions_end(); ++j)
+-	  if(targets.find(*j)==targets.end())
+-	    targets2.insert(*j);
+-
+-      deps.push_back(new dummy_dep(pkg->version_from_name(pkg_ver),
+-				   vector<dummy_version *>(targets2.begin(), targets2.end()),
+-				   deps.size(),
+-				   is_soft));
+-    }
+-
+-  dummy_dep *newdep=deps.back();
+-
+-  newdep->get_source().add_dep(newdep);
+-
+-  for(dummy_dep::solver_iterator i=newdep->solvers_begin();
+-      i!=newdep->solvers_end(); ++i)
+-    (*i)->add_revdep(newdep);
+-}
+-
+-
+-ostream &operator<<(ostream &out, const dummy_universe::dep &d)
+-{
+-  out << d.get_source().get_package().get_name() << " " << d.get_source().get_name() << " -> {";
+-  for(dummy_universe::dep::solver_iterator i=d.solvers_begin();
+-      !i.end(); ++i)
+-    {
+-      if(i!=d.solvers_begin())
+-	out << " ";
+-      out << (*i).get_package().get_name() << " " << (*i).get_name();
+-    }
+-  out << "}";
+-
+-  return out;
+-}
+-
+-pair<string, string> read_pkgverpair(istream &in)
+-{
+-  in >> ws;
+-
+-  string pkgname,vername;
+-
+-  in >> pkgname >> ws;
+-
+-  if(in.eof())
+-    throw ParseError("Expected version name after package name "+pkgname+", got EOF");
+-
+-  in >> vername >> ws;
+-
+-  return pair<string, string>(pkgname, vername);
+-}
+-
+-dummy_universe_ref parse_universe(istream &in)
+-{
+-  string s;
+-
+-  in >> ws;
+-  if(in.eof())
+-    throw ParseError("Expected \"UNIVERSE\"; got EOF");
+-
+-  in >> s >> ws;
+-
+-  if(s != "UNIVERSE")
+-    throw ParseError("Expected \"UNIVERSE\"; got \"" + s + "\"");
+-
+-  if(in.eof())
+-    throw ParseError("Expected \"[\"; got EOF");
+-
+-  in >> s >> ws;
+-
+-  if(s != "[")
+-    throw ParseError("Expected \"[\" following UNIVERSE; got \"" + s + "\"");
+-
+-  if(in.eof())
+-    throw ParseError("Unexpected EOF after \"UNIVERSE [\"");
+-
+-  return parse_universe_tail(in);
+-}
+-
+-dummy_universe_ref parse_universe_tail(istream &in)
+-{
+-  dummy_universe_ref rval=new dummy_universe;
+-
+-  in >> ws;
+-  while(in)
+-    {
+-      string s;
+-
+-      if(in.eof())
+-	throw ParseError("Expected ']', 'PACKAGE', or 'DEP'; got EOF");
+-
+-      in >> s >> ws;
+-
+-      if(s == "]")
+-	break;
+-      else if(s == "PACKAGE")
+-	{
+-	  string pkgname;
+-
+-	  in >> pkgname >> ws;
+-
+-	  if(in.eof())
+-	    throw ParseError("Unexpected EOF after PACKAGE "+pkgname);
+-
+-	  in >> s >> ws;
+-
+-	  if(s != "<")
+-	    throw ParseError("Expected '<', got "+s);
+-
+-	  if(in.eof())
+-	    throw ParseError("Unexpected EOF after PACKAGE "+pkgname+" <");
+-
+-	  vector<string> vernames;
+-
+-	  while(in)
+-	    {
+-	      string vername;
+-
+-	      if(in.eof())
+-		throw ParseError("Expected version name or '>', got EOF");
+-
+-	      in >> vername >> ws;
+-
+-	      if(vername == ">")
+-		break;
+-
+-	      vernames.push_back(vername);
+-	    }
+-
+-	  if(in.eof())
+-	    throw ParseError("Expected a definition of the current version of "+pkgname+", got EOF");
+-
+-	  string curname;
+-
+-	  in >> curname >> ws;
+-
+-	  if(vernames.empty())
+-	    throw ParseError("Package "+pkgname+" has no versions");
+-
+-	  rval.add_package(pkgname, vernames, curname);
+-	}
+-      else if(s == "DEP" || s == "SOFTDEP")
+-	{
+-	  pair<string, string> source=read_pkgverpair(in);
+-	  bool is_conflict=false;
+-	  bool is_soft = (s == "SOFTDEP");
+-
+-	  in >> s >> ws;
+-
+-	  if(s == "!!")
+-	    is_conflict=true;
+-	  else if(s != "->")
+-	    throw ParseError("Expected '->' or '!!', got "+s);
+-
+-	  if(in.eof())
+-	    throw ParseError("Expected '<', got EOF");
+-
+-	  in >> s >> ws;
+-
+-	  if(s != "<")
+-	    throw ParseError("Expected '<', got "+s);
+-
+-	  if(in.eof())
+-	    throw ParseError("Expected package-version pair, got EOF");
+-
+-	  vector<pair<string, string> > targets;
+-
+-	  while(in)
+-	    {
+-	      string pkgname,vername;
+-
+-	      in >> pkgname >> ws;
+-
+-	      if(pkgname == ">")
+-		break;
+-
+-	      if(in.eof())
+-		throw ParseError("Expected version name after package name "+pkgname+", got EOF");
+-
+-	      in >> vername >> ws;
+-
+-	      if(vername == ">")
+-		throw ParseError("Expected version name after package name "+pkgname+", got end-of-list instead");
+-
+-	      targets.push_back(pair<string,string>(pkgname,vername));
+-
+-	      if(in.eof())
+-		throw ParseError("Unexpected EOF in dependency target list following package "+pkgname+" version "+vername);
+-	    }
+-
+-	  rval.add_dep(source.first, source.second, targets,
+-		       is_conflict, is_soft);
+-	}
+-      else
+-	throw ParseError("Expected PACKAGE, DEP, or SOFTDEP, got "+s);
+-
+-      if(in.eof())
+-	throw ParseError("Expected ']' following universe declaration, got EOF.");
+-    }
+-
+-  return rval;
+-}
+diff --git a/src/generic/problemresolver/dummy_universe.h b/src/generic/problemresolver/dummy_universe.h
+deleted file mode 100644
+index 670252d..0000000
+--- a/src/generic/problemresolver/dummy_universe.h
++++ /dev/null
+@@ -1,776 +0,0 @@
+-// dummy_universe.h                               -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-//
+-// A package dependency universe that's not terribly efficient, but
+-// easy to set up for testing.
+-
+-#ifndef DUMMY_UNIVERSE_H
+-#define DUMMY_UNIVERSE_H
+-
+-#include <iostream>
+-#include <map>
+-#include <set>
+-#include <string>
+-#include <vector>
+-
+-#include <generic/util/eassert.h>
+-#include <generic/util/exception.h>
+-
+-// An error type that's thrown when a name lookup fails.
+-class NoSuchNameError:public Exception
+-{
+-  std::string name;
+-  std::string type;
+-public:
+-  NoSuchNameError(const std::string &_type, const std::string &_name)
+-    :name(_name), type(_type) {}
+-
+-  std::string errmsg() const {return "No "+type+" named "+name;}
+-};
+-
+-template<class T1, class T2>
+-class wrap_ptr_iter
+-{
+-  typename std::vector<T1 *>::const_iterator realiter, realend;
+-public:
+-  wrap_ptr_iter(const std::vector<T1 *> &parent)
+-    :realiter(parent.begin()), realend(parent.end())
+-  {
+-  }
+-
+-  wrap_ptr_iter(const typename std::vector<T1 *>::const_iterator &begin,
+-		const typename std::vector<T1 *>::const_iterator &end)
+-    :realiter(begin), realend(end)
+-  {
+-  }
+-
+-  bool operator==(const wrap_ptr_iter &other) const
+-  {
+-    return realiter==other.realiter;
+-  }
+-
+-  bool operator!=(const wrap_ptr_iter &other) const
+-  {
+-    return realiter!=other.realiter;
+-  }
+-
+-  bool end() const
+-  {
+-    return realiter == realend;
+-  }
+-
+-  wrap_ptr_iter &operator++()
+-  {
+-    ++realiter;
+-    return *this;
+-  }
+-
+-  const T2 operator*() const
+-  {
+-    return T2(*realiter);
+-  }
+-};
+-
+-class dummy_universe;
+-class dummy_version;
+-
+-/** A dummy package type */
+-class dummy_package
+-{
+-  /** The name of the package is not used by the generic algorithm,
+-   *  but is used as helpful output from the test cases.
+-   */
+-  std::string name;
+-
+-  /** The versions of this package.  The first entry in this list is
+-   *  the current version.
+-   */
+-  std::vector<dummy_version *> versions;
+-
+-  /** The current version of this package; defaults to the first
+-   *  element of "versions".
+-   */
+-  dummy_version *cur;
+-
+-  /** The ID of this version. */
+-  unsigned int ID;
+-
+-  dummy_package(const dummy_package &other);
+-public:
+-  typedef std::vector<dummy_version *>::const_iterator version_iterator;
+-
+-  /** Creates a dummy package. */
+-  dummy_package(const std::string &_name, unsigned int id);
+-
+-  virtual ~dummy_package();
+-
+-  std::string get_name() const {return name;}
+-  unsigned int get_id() const {return ID;}
+-
+-  /** Dummy packages are equivalent iff they are the same object. */
+-  bool operator==(const dummy_package &other) const
+-  {
+-    return this == &other;
+-  }
+-
+-  bool operator!=(const dummy_package &other) const
+-  {
+-    return this != &other;
+-  }
+-
+-  bool operator<(const dummy_package &other) const
+-  {
+-    return ID < other.ID;
+-  }
+-
+-  void add_version(dummy_version *version)
+-  {
+-    if(versions.empty())
+-      cur=version;
+-    versions.push_back(version);
+-  }
+-
+-  const dummy_version &current_version() const {return *cur;}
+-  version_iterator versions_begin() const {return versions.begin();}
+-  version_iterator versions_end() const {return versions.end();}
+-
+-  /** Returns the version corresponding to the given name or aborts */
+-  dummy_version *version_from_name(const std::string &the_name) const;
+-
+-  /** Sets the current version to the given version. */
+-  void set_current_version(dummy_version *v)
+-  {
+-    cur=v;
+-  }
+-};
+-
+-class dummy_dep;
+-
+-/** A dummy version type */
+-class dummy_version
+-{
+-  std::string name;
+-
+-  const dummy_package *package;
+-
+-  std::vector<dummy_dep *> revdeps;
+-  std::vector<dummy_dep *> deps;
+-
+-  /** The numerical ID of this version. */
+-  int ID;
+-
+-  dummy_version(const dummy_version &other);
+-public:
+-  typedef std::vector<dummy_dep *>::const_iterator revdep_iterator;
+-  typedef std::vector<dummy_dep *>::const_iterator dep_iterator;
+-
+-  dummy_version(const std::string &_name, const dummy_package *_package,
+-		unsigned int id)
+-    :name(_name), package(_package), ID(id)
+-  {
+-  }
+-
+-  std::string get_name() const {return name;}
+-  unsigned int get_id() const {return ID;}
+-
+-  bool operator==(const dummy_version &other) const
+-  {
+-    return this == &other;
+-  }
+-
+-  bool operator!=(const dummy_version &other) const
+-  {
+-    return this != &other;
+-  }
+-
+-  bool operator<(const dummy_version &other) const
+-  {
+-    return ID < other.ID;
+-  }
+-
+-  void add_revdep(dummy_dep *dep)
+-  {
+-    revdeps.push_back(dep);
+-  }
+-
+-  void add_dep(dummy_dep *dep)
+-  {
+-    deps.push_back(dep);
+-  }
+-
+-  const dummy_package &get_package() const {return *package;}
+-
+-  revdep_iterator revdeps_begin() const {return revdeps.begin();}
+-  revdep_iterator revdeps_end() const {return revdeps.end();}
+-
+-  dep_iterator deps_begin() const {return deps.begin();}
+-  dep_iterator deps_end() const {return deps.end();}
+-};
+-
+-/** Indicates that either package_1 depends upon package_2 or
+- *  package_1 conflicts with package_2.
+- */
+-class dummy_dep
+-{
+-  dummy_version *source;
+-  std::vector<dummy_version *> target_set;
+-
+-  dummy_dep(const dummy_dep &other);
+-
+-  unsigned int ID;
+-
+-  bool soft;
+-public:
+-  typedef std::vector<dummy_version *>::const_iterator solver_iterator;
+-
+-  dummy_dep(dummy_version *_source,
+-	    const std::vector<dummy_version *> &_target_set,
+-	    unsigned int _ID, bool _soft);
+-
+-  bool is_soft() const
+-  {
+-    return soft;
+-  }
+-
+-  bool operator==(const dummy_dep &other) const
+-  {
+-    return this==&other;
+-  }
+-
+-  bool operator!=(const dummy_dep &other) const
+-  {
+-    return this!=&other;
+-  }
+-
+-  bool operator<(const dummy_dep &other) const
+-  {
+-    return ID<other.ID;
+-  }
+-
+-  dummy_version &get_source() const {return *source;}
+-
+-  solver_iterator solvers_begin() const
+-  {
+-    return target_set.begin();
+-  }
+-
+-  solver_iterator solvers_end() const
+-  {
+-    return target_set.end();
+-  }
+-
+-  /** Not part of the generic interface (although it could be);
+-   *  returns \b true if the dep is not satisfied in the global
+-   *  state (i.e., ignores any solution computation in progress).
+-   */
+-  bool broken() const;
+-};
+-
+-/** \brief Represents the world of all packages and dependencies.
+- *
+- *  This implements the abstract universe interface as described in
+- *  \ref abstract_universe.
+- *
+- *  \sa universe_universe
+- */
+-class dummy_universe
+-{
+-public:
+-  class version;
+-  class dep;
+-
+-  class package
+-  {
+-    const dummy_package *real_package;
+-  public:
+-    package():real_package(0) {}
+-    package(const dummy_package *_real_package)
+-      :real_package(_real_package)
+-    {
+-    }
+-
+-    typedef wrap_ptr_iter<dummy_version, version> version_iterator;
+-
+-    bool operator==(const package &other) const
+-    {
+-      return real_package==other.real_package;
+-    }
+-
+-    bool operator!=(const package &other) const
+-    {
+-      return real_package!=other.real_package;
+-    }
+-
+-    bool operator<(const package &other) const
+-    {
+-      return (*real_package)<(*other.real_package);
+-    }
+-
+-    std::string get_name() const
+-    {
+-      return real_package->get_name();
+-    }
+-
+-    unsigned int get_id() const
+-    {
+-      return real_package->get_id();
+-    }
+-
+-    version current_version() const
+-    {
+-      return version(&real_package->current_version());
+-    }
+-
+-    version version_from_name(const std::string &name) const
+-    {
+-      return version(real_package->version_from_name(name));
+-    }
+-
+-    wrap_ptr_iter<dummy_version, version> versions_begin() const
+-    {
+-      return wrap_ptr_iter<dummy_version, version>(real_package->versions_begin(), real_package->versions_end());
+-    }
+-  };
+-
+-  class version
+-  {
+-    const dummy_version *real_version;
+-  public:
+-    typedef wrap_ptr_iter<dummy_dep, dep> revdep_iterator;
+-    typedef wrap_ptr_iter<dummy_dep, dep> dep_iterator;
+-
+-    version():real_version(0) {}
+-    version(const dummy_version *_real_version)
+-      :real_version(_real_version)
+-    {
+-    }
+-
+-    bool operator==(const version &other) const
+-    {
+-      return real_version==other.real_version;
+-    }
+-
+-    bool operator!=(const version &other) const
+-    {
+-      return real_version!=other.real_version;
+-    }
+-
+-    bool operator<(const version &other) const
+-    {
+-      return (*real_version)<(*other.real_version);
+-    }
+-
+-    package get_package() const
+-    {
+-      return package(&real_version->get_package());
+-    }
+-
+-    std::string get_name() const
+-    {
+-      return real_version->get_name();
+-    }
+-
+-    unsigned int get_id() const
+-    {
+-      return real_version->get_id();
+-    }
+-
+-    wrap_ptr_iter<dummy_dep, dep> revdeps_begin() const
+-    {
+-      return wrap_ptr_iter<dummy_dep, dep>(real_version->revdeps_begin(),
+-					   real_version->revdeps_end());
+-    }
+-
+-    wrap_ptr_iter<dummy_dep, dep> deps_begin() const
+-    {
+-      return wrap_ptr_iter<dummy_dep, dep>(real_version->deps_begin(),
+-					   real_version->deps_end());
+-    }
+-  };
+-
+-
+-  class dep
+-  {
+-    const dummy_dep *real_dep;
+-  public:
+-    dep():real_dep(0) {}
+-    dep(const dummy_dep *_real_dep)
+-      :real_dep(_real_dep)
+-    {
+-    }
+-    dep(const dep &other)
+-      :real_dep(other.real_dep)
+-    {
+-    }
+-
+-    typedef wrap_ptr_iter<dummy_version, version> solver_iterator;
+-
+-    bool is_soft() const
+-    {
+-      return real_dep->is_soft();
+-    }
+-
+-    bool operator==(const dep &other) const
+-    {
+-      return real_dep==other.real_dep;
+-    }
+-
+-    bool operator!=(const dep &other) const
+-    {
+-      return real_dep!=other.real_dep;
+-    }
+-
+-    bool operator<(const dep &other) const
+-    {
+-      return (*real_dep)<(*other.real_dep);
+-    }
+-
+-    version get_source() const
+-    {
+-      return version(&real_dep->get_source());
+-    }
+-
+-    wrap_ptr_iter<dummy_version, version> solvers_begin() const
+-    {
+-      return wrap_ptr_iter<dummy_version, version>(real_dep->solvers_begin(),
+-						   real_dep->solvers_end());
+-    }
+-
+-    template<class Sol>
+-    bool broken_under(const Sol& s) const
+-    {
+-      if(s.version_of(get_source().get_package()) != get_source())
+-	return false;
+-
+-      for(dummy_dep::solver_iterator i=real_dep->solvers_begin();
+-	  i!=real_dep->solvers_end(); ++i)
+-	if(s.version_of(version(*i).get_package()) == version(*i))
+-	  return false;
+-
+-      return true;
+-    }
+-
+-    bool solved_by(const version &other) const;
+-  };
+-
+-
+-  typedef wrap_ptr_iter<dummy_package, package> package_iterator;
+-  typedef wrap_ptr_iter<dummy_dep, dep> dep_iterator;
+-
+-  /** Finds broken dependencies. */
+-  class broken_dep_iterator
+-  {
+-    std::vector<dummy_dep *>::const_iterator realiter;
+-    std::vector<dummy_dep *>::const_iterator realend;
+-  public:
+-    broken_dep_iterator(const std::vector<dummy_dep *>::const_iterator &_realiter,
+-			const std::vector<dummy_dep *>::const_iterator &_realend)
+-      :realiter(_realiter), realend(_realend)
+-    {
+-      while(realiter!=realend && !(*realiter)->broken())
+-	++realiter;
+-    }
+-
+-    bool operator==(const broken_dep_iterator &other) const
+-    {
+-      return realiter==other.realiter;
+-    }
+-
+-    bool operator!=(const broken_dep_iterator &other) const
+-    {
+-      return realiter!=other.realiter;
+-    }
+-
+-    bool end() const
+-    {
+-      return realiter == realend;
+-    }
+-
+-    const dep operator*() const
+-    {
+-      eassert(realiter!=realend);
+-      return *realiter;
+-    }
+-
+-    broken_dep_iterator &operator++()
+-    {
+-      if(realiter!=realend)
+-	++realiter;
+-
+-      while(realiter!=realend && !(*realiter)->broken())
+-	++realiter;
+-
+-      return *this;
+-    }
+-  };
+-
+-private:
+-  /** All the packages in the universe. */
+-  std::vector<dummy_package *> packages;
+-  /** All the dependencies in the universe. */
+-  std::vector<dummy_dep *> deps;
+-  /** All the versions in the universe. */
+-  std::vector<dummy_version *> versions;
+-
+-  /** Indexes packages by name. */
+-  std::map<std::string, dummy_package *> packages_by_name;
+-
+-  struct compare_dummy_packages
+-  {
+-    bool operator()(dummy_package *p1, dummy_package *p2)
+-    {
+-      return p1->get_id() < p2->get_id();
+-    }
+-  };
+-
+-  struct compare_dummy_versions
+-  {
+-    bool operator()(dummy_version *v1, dummy_version *v2)
+-    {
+-      return v1->get_id() < v2->get_id();
+-    }
+-  };
+-
+-  dummy_package *find_package_internal(const std::string &pkg_name)
+-  {
+-    std::map<std::string, dummy_package *>::const_iterator pfound=packages_by_name.find(pkg_name);
+-
+-    if(pfound==packages_by_name.end())
+-      throw NoSuchNameError("package", pkg_name);
+-
+-    return pfound->second;
+-  }
+-
+-public:
+-  virtual ~dummy_universe();
+-
+-  /** Lo, and it was a void, without form. */
+-  dummy_universe() {}
+-
+-  /** Add a package to the universe.
+-   *
+-   *  \param name the name of the new package.
+-   *  \param the_versions the names of the versions of that package.
+-   *         The first element of the list is the current version.
+-   */
+-  void add_package(const std::string &name,
+-		   std::vector<std::string> the_versions,
+-		   const std::string &curname);
+-
+-  /** Set the current version of the given package to the given version. */
+-  void set_current_version(const std::string &pkg_name,
+-			   const std::string &ver_name)
+-  {
+-    dummy_package *p = find_package_internal(pkg_name);
+-    p->set_current_version(p->version_from_name(ver_name));
+-  }
+-
+-  /** Find a package by name. */
+-  package find_package(const std::string &pkg_name)
+-  {
+-    return find_package_internal(pkg_name);
+-  }
+-
+-  /** Add a dependency to the universe.  For convenience
+-   *  this is std::string-based.
+-   */
+-  void add_dep(const std::string &pkg_name, const std::string &pkg_ver,
+-	       const std::vector<std::pair<std::string, std::string> > &target_names,
+-	       bool is_conflict, bool is_soft);
+-
+-  std::vector<package>::size_type get_package_count() const
+-  {
+-    return packages.size();
+-  }
+-
+-  std::vector<version>::size_type get_version_count() const
+-  {
+-    return versions.size();
+-  }
+-
+-  package_iterator packages_begin() const
+-  {
+-    return packages;
+-  }
+-
+-  dep_iterator deps_begin() const
+-  {
+-    return deps;
+-  }
+-
+-  broken_dep_iterator broken_begin() const
+-  {
+-    return broken_dep_iterator(deps.begin(), deps.end());
+-  }
+-};
+-
+-// A refcounting wrapper for a dummy_universe; used to sanitize memory
+-// management without copying all over (and because the resolver
+-// expects to be able to have a full copy of its argument type)
+-class dummy_universe_ref
+-{
+-  struct _rep
+-  {
+-    int refcount;
+-    dummy_universe *universe;
+-
+-    /** Start with 1 ref since our creator holds a ref. */
+-    _rep(dummy_universe *_universe)
+-      :refcount(1), universe(_universe)
+-    {
+-    }
+-
+-    void incref() {++refcount;}
+-    void decref() {--refcount; if(refcount==0) delete this;}
+-  };
+-
+-  _rep *rep;
+-public:
+-  typedef dummy_universe::package package;
+-  typedef dummy_universe::version version;
+-  typedef dummy_universe::dep dep;
+-  typedef dummy_universe::package_iterator package_iterator;
+-  typedef dummy_universe::dep_iterator dep_iterator;
+-  typedef dummy_universe::broken_dep_iterator broken_dep_iterator;
+-
+-  dummy_universe_ref()
+-    :rep(NULL)
+-  {
+-  }
+-
+-  dummy_universe_ref(const dummy_universe_ref &other)
+-    :rep(other.rep)
+-  {
+-    if(rep)
+-      rep->incref();
+-  }
+-
+-  /** Assumes this is the first reference to the universe. */
+-  dummy_universe_ref(dummy_universe *universe)
+-    :rep(new _rep(universe))
+-  {
+-  }
+-
+-  ~dummy_universe_ref()
+-  {
+-    if(rep)
+-      rep->decref();
+-  }
+-
+-  dummy_universe_ref &operator=(const dummy_universe_ref &other)
+-  {
+-    if(other.rep)
+-      other.rep->incref();
+-    if(rep)
+-      rep->decref();
+-    rep=other.rep;
+-
+-    return *this;
+-  }
+-
+-  operator void*() const
+-  {
+-    return (void *) (rep && rep->universe);
+-  }
+-
+-  void add_package(const std::string &name,
+-		   const std::vector<std::string> &the_versions,
+-		   const std::string &curname) const
+-  {
+-    rep->universe->add_package(name, the_versions, curname);
+-  }
+-
+-  void set_current_version(const std::string &pkg_name,
+-			   const std::string &ver_name)
+-  {
+-    rep->universe->set_current_version(pkg_name, ver_name);
+-  }
+-
+-  void add_dep(std::string pkg_name, std::string pkg_ver,
+-	       const std::vector<std::pair<std::string, std::string> > &target_names,
+-	       bool is_conflict, bool is_soft)
+-  {
+-    rep->universe->add_dep(pkg_name, pkg_ver,
+-			   target_names, is_conflict, is_soft);
+-  }
+-
+-  package find_package(const std::string &pkg_name) const
+-  {
+-    return rep->universe->find_package(pkg_name);
+-  }
+-
+-  std::vector<package>::size_type get_package_count() const
+-  {
+-    return rep->universe->get_package_count();
+-  }
+-
+-  std::vector<version>::size_type get_version_count() const
+-  {
+-    return rep->universe->get_version_count();
+-  }
+-
+-  package_iterator packages_begin() const
+-  {
+-    return rep->universe->packages_begin();
+-  }
+-
+-  dep_iterator deps_begin() const
+-  {
+-    return rep->universe->deps_begin();
+-  }
+-
+-  broken_dep_iterator broken_begin() const
+-  {
+-    return rep->universe->broken_begin();
+-  }
+-};
+-
+-template<class T>
+-class generic_problem_resolver;
+-typedef generic_problem_resolver<dummy_universe_ref> dummy_resolver;
+-
+-std::ostream &operator<<(std::ostream &out, const dummy_universe::dep &d);
+-
+-class ParseError : public Exception
+-{
+-  std::string msg;
+-public:
+-  ParseError(const std::string &_msg):msg(_msg) {}
+-
+-  std::string errmsg() const {return msg;}
+-};
+-
+-/** Read a (package, version) pair of strings from the given stream.
+- *
+- *  \throws ParseError
+- */
+-std::pair<std::string, std::string> read_pkgverpair(std::istream &in);
+-
+-
+-/** Parses a universe from the given stream. \throws ParseError */
+-dummy_universe_ref parse_universe(std::istream &in);
+-
+-/** Parses a universe to the closing ']'.  Meant for use as a subroutine
+- *  to be called after the opening "UNIVERSE [" has been stripped.
+- *
+- *  \throws ParseError
+- */
+-dummy_universe_ref parse_universe_tail(std::istream &in);
+-
+-#endif // DUMMY_UNIVERSE_H
+diff --git a/src/generic/problemresolver/dump_universe.h b/src/generic/problemresolver/dump_universe.h
+deleted file mode 100644
+index d0b8a4d..0000000
+--- a/src/generic/problemresolver/dump_universe.h
++++ /dev/null
+@@ -1,62 +0,0 @@
+-// dump_universe.h                                      -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#ifndef DUMP_UNIVERSE_H
+-#define DUMP_UNIVERSE_H
+-
+-#include <iostream>
+-
+-template<class PackageUniverse>
+-void dump_universe(const PackageUniverse &world, std::ostream &out)
+-{
+-  out << "UNIVERSE [";
+-  for(typename PackageUniverse::package_iterator p=world.packages_begin();
+-      !p.end(); ++p)
+-    {
+-      out << "  PACKAGE " << (*p).get_name() << " < ";
+-      for(typename PackageUniverse::package::version_iterator v=(*p).versions_begin();
+-	  !v.end(); ++v)
+-	out << (*v).get_name() << " ";
+-      out << ">" << " " << (*p).current_version().get_name() << std::endl;
+-    }
+-
+-  for(typename PackageUniverse::dep_iterator d=world.deps_begin();
+-      !d.end(); ++d)
+-    {
+-      const typename PackageUniverse::version &sv=(*d).get_source();
+-      const typename PackageUniverse::package &sp=sv.get_package();
+-
+-      if((*d).is_soft())
+-	out << "  SOFTDEP ";
+-      else
+-	out << "  DEP ";
+-
+-      out << sp.get_name() << " " << sv.get_name() << " -> < ";
+-
+-      for(typename PackageUniverse::dep::solver_iterator t=(*d).solvers_begin();
+-	  !t.end(); ++t)
+-	{
+-	  out << " " << (*t).get_package().get_name() << " " << (*t).get_name() << " ";
+-	}
+-      out << " > " << std::endl;
+-    }
+-  out << "]" << std::endl;
+-}
+-
+-#endif // DUMP_UNIVERSE_H
+diff --git a/src/generic/problemresolver/exceptions.h b/src/generic/problemresolver/exceptions.h
+deleted file mode 100644
+index 05719e6..0000000
+--- a/src/generic/problemresolver/exceptions.h
++++ /dev/null
+@@ -1,82 +0,0 @@
+-// exceptions.h                                     -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#ifndef EXCEPTIONS_H
+-#define EXCEPTIONS_H
+-
+-#include <generic/util/exception.h>
+-
+-/** Generic errors in the problem resolver. */
+-class ProblemResolverError : public Exception {
+-};
+-
+-/** An exception indicating that no more solutions are available. */
+-class NoMoreSolutions : public ProblemResolverError {
+-  std::string errmsg() const
+-  {
+-    return "No more solutions to this dependency problem.";
+-  }
+-};
+-
+-/** An exception indicating that the resolver ran out of time to
+- *  find a solution.
+- */
+-class NoMoreTime:public ProblemResolverError {
+-  std::string errmsg() const
+-  {
+-    return "No more time to solve this dependency problem.";
+-  }
+-};
+-
+-/** An exception indicating that the resolver was interrupted from
+- *  another thread.
+- */
+-class InterruptedException : public ProblemResolverError {
+-  std::string errmsg() const
+-  {
+-    return "Dependency solution was interrupted.";
+-  }
+-};
+-
+-/** An exception indicating that an internal error occurred. */
+-class ResolverInternalErrorException : public ProblemResolverError {
+-  std::string msg;
+-public:
+-  ResolverInternalErrorException(const std::string &_msg)
+-    : msg(_msg)
+-  {
+-  }
+-
+-  std::string errmsg() const
+-  {
+-    return msg;
+-  }
+-};
+-
+-/** An exception indicating that two threads tried to run the resolver
+- *  at once.
+- */
+-class DoubleRunException : public ProblemResolverError {
+-  std::string errmsg() const
+-  {
+-    return "Internal error: Multiple threads of execution tried to enter the resolver at once.";
+-  }
+-};
+-
+-#endif // EXCEPTIONS_H
+diff --git a/src/generic/problemresolver/model.tex b/src/generic/problemresolver/model.tex
+deleted file mode 100644
+index 614fba7..0000000
+--- a/src/generic/problemresolver/model.tex
++++ /dev/null
+@@ -1,1358 +0,0 @@
+-\documentclass[letterpaper]{article}
+-
+-\usepackage{fancyhdr}
+-\usepackage{url}
+-\usepackage{pgf}
+-\usepackage{amsmath}
+-\usepackage{amsthm}
+-\usepackage{amssymb}
+-\usepackage{semantic}
+-\usepackage{mathpartir}
+-\usepackage{varioref}
+-
+-\usepackage{algorithm}
+-% From algorithmicx
+-\usepackage{algpseudocode}
+-
+-\pagestyle{fancy}
+-
+-\newtheorem{theorem}{Theorem}
+-\newtheorem{lemma}[theorem]{Lemma}
+-
+-\theoremstyle{definition}
+-\newtheorem{definition}[theorem]{Definition}
+-
+-\theoremstyle{remark}
+-\newtheorem*{note}{Note}
+-\newtheorem*{remark}{Remark}
+-
+-\lhead{Modelling and Resolving Software Dependencies}
+-\rhead{Daniel Burrows}
+-
+-\author{Daniel Burrows \url{<dburrows at debian.org>}}
+-\title{Modelling and Resolving Software Dependencies}
+-
+-\newcommand{\pkg}[1]{\text{\url{#1}}}
+-
+-\renewcommand{\P}{\mathcal{P}}
+-\newcommand{\V}{\mathcal{V}}
+-\newcommand{\I}{\mathcal{I}}
+-\newcommand{\D}{\mathcal{D}}
+-\newcommand{\U}{\mathcal{U}}
+-\newcommand{\pkgof}[1]{PkgOf(#1)}
+-
+-\newcommand{\st}{\ |\ }
+-
+-\newcommand{\idist}[2]{\langle#1,#2\rangle}
+-\newcommand{\len}[1]{\lvert#1\rvert}
+-
+-\newcommand{\nsol}[2]{\overset{#1}{\underset{#2}{\Rightarrow}}}
+-\newcommand{\nsolmany}[1]{\overset{#1}{\underset{*}{\Rightarrow}}}
+-
+-\newcommand{\act}[2]{[#1 :: #2]}
+-
+-\newcommand{\installs}{\vartriangleright}
+-\newcommand{\satisfies}{\vdash}
+-\newcommand{\col}{\mathpunct{:}}
+-
+-\algrenewcommand{\algorithmicprocedure}{\textbf{function}}
+-
+-\mathlig{->}{\rightarrow}
+-\mathlig{=>*}{\overset{*}{=>}}
+-
+-\begin{document}
+-\maketitle
+-
+-\begin{abstract}
+-  Many Linux distributions and other modern operating systems feature
+-  the explicit declaration of (often complex) dependency relationships
+-  between the pieces of software that may be installed on a system.
+-  Resolving incompatibilities between different pieces of software is
+-  an NP-complete problem, and existing solutions require the user to
+-  manually resolve many ``simple'' dependency problems.
+-
+-  I present a simplified, abstract model of dependency relationships,
+-  and a restartable technique based on best-first-search to calculate
+-  resolutions.
+-\end{abstract}
+-
+-\begin{note}
+-  This is a work in progress; it sometimes lags behind or jumps ahead
+-  of the current state of the software it documents, and some of the
+-  details may be incomplete or unattended to.  However, I hope that it
+-  provides some more insight into the direction in which
+-  \pkg{aptitude}'s problem resolver is headed -- and in which I
+-  believe that other installation frontends should also consider
+-  heading.
+-\end{note}
+-
+-\section{Introduction}
+-
+-It is common nowadays for hundreds or thousands of software packages
+-to be installed on a single computer system, and for many of these
+-software packages to interact with one another.  Because some
+-combinations of software packages will not function properly -- for
+-instance, an application program might require a particular version of
+-a graphics library -- installing software manually while avoiding
+-unexpected breakage is an increasingly unpleasant chore.
+-
+-To address this problem, programs known as \emph{package systems} were
+-developed.  A package system typically manages \emph{packages} that
+-consist of the files of a program or library, along with metadata such
+-as the name and version of the package, a brief description of what it
+-contains, and (most importantly for our purposes) a list of which
+-other packages it requires or is incompatible with.  The package
+-installation software warns the user upon any attempt to install or
+-remove software that would violate these constraints.
+-
+-Unfortunately, the early versions of these tools replaced the chore of
+-manual software installation with the chore of dependency resolution:
+-for instance, installing a package of the popular game \pkg{wesnoth}
+-might produce an error indicating that the user should find, download,
+-and install a new version of the \pkg{SDL} graphics library.  A new
+-version of the \pkg{kmail} mail client might require the user to
+-upgrade his or her entire operating system, indicating this fact by a
+-slew of cascading error messages.
+-
+-As a result of this so-called ``dependency hell'', new and more
+-automated tools, such as \pkg{apt} and \pkg{up2date}, were developed.
+-These tools maintain a database of software installed on the user's
+-system, along with software available from any number of remote sites.
+-
+-To install or remove a piece of software, the user issues a request
+-to, for instance, ``install wesnoth'' or ``upgrade kmail''.  The
+-installation tool will proceed to find a set of package installations
+-or removals which leads to a consistent result.  Typically, it then
+-presents this list of actions to the user and prompts for
+-confirmation; the user can either accept the proposed solution, or
+-reject it and proceed to fix the problem in a fully manual way.  Once
+-the user is satisfied with the proposed changes, the tool will
+-download any new software packages and install them.
+-
+-This approach has two major drawbacks:
+-
+-\begin{enumerate}
+-\item The user interface for resolving dependencies is a ``take it or
+-  leave it'' proposition: there is no way for the user to ask the
+-  algorithm to find another solution.  This means that if the
+-  algorithm makes a poor or undesired choice (which, as I will argue
+-  below, will inevitably occur from time to time) the user is forced
+-  to fall back to fully manual operation.
+-
+-\item In at least some cases (particularly \pkg{apt}), the algorithm used
+-  in resolving dependency conflicts deals poorly -- which is a
+-  euphemism for ``not at all'' -- when there are more than two
+-  versions of a package to choose from\footnote{More precisely, if
+-    more than one version other than the currently installed version
+-    (if any) exists.}.  For instance, if versions 1, 2, and 3 of
+-  package \pkg{A} are available, with 2 being the default version of
+-  the package, and if package B requires version 3 of package A, when
+-  the user tries to install package B, he or she will receive an error
+-  message indicating that the dependency on A cannot be fulfilled.
+-\end{enumerate}
+-
+-Another general difficulty in solving dependencies in these systems is
+-that the package systems contain many features which, although they
+-are arguably ``syntactic sugar'', tend to cause algorithms that
+-operate on packages to become strewn with complex iteration constructs
+-and unpleasant corner cases.  Although some attempts have been made to
+-find general models of package dependencies (for instance, the
+-internal structures of \pkg{apt} can represent either Debian or Red
+-Hat packages), the models with which I am familiar work by taking a
+-``greatest upper bound'' of the systems that they cover, leading to a
+-generic framework that is, if anything, even more convoluted than the
+-individual package systems that it covers.
+-
+-\begin{note}
+-  I have not yet performed an extensive survey of package systems, and
+-  it may be that there already exist systems that fix one, two, or all
+-  of the drawbacks listed above.
+-\end{note}
+-
+-\section{Example: the Debian Package System}
+-
+-The Debian package system is implemented by a low-level tool known as
+-\pkg{dpkg}.  Debian packages are files with the extension \url{.deb};
+-\pkg{dpkg} can install a \url{.deb} file that has already been
+-retrieved, or remove a package that is currently installed on the
+-system.  If dependency constraints are violated, \pkg{dpkg} will print
+-errors messages and abort the installation after unpacking the
+-packages.
+-
+-The usual user interface to the package system is through one of the
+-programs in the \pkg{apt} suite.  \pkg{apt} is a high-level library
+-which allows C++ programs to examine the set of installed packages,
+-determine what actions are to be performed, and execute these actions
+-(by, for instance, downloading package files and calling \pkg{dpkg} to
+-install them).  \pkg{apt}-based installation tools typically refuse to
+-even begin any actions that will result in an inconsistent system
+-state, and all of them provide a basic algorithm that resolves
+-inconsistencies by adjusting package states until all dependencies are
+-fixed.
+-
+-In the Debian package system, each package may have one or more
+-versions, but at most one version of each package may be installed at
+-any given time.  The basic relationships between packages are
+-\emph{dependencies} and \emph{conflicts}.  For instance, version
+-6.14.00-1 of the \pkg{tcsh} command shell depends on version
+-2.3.2.ds-4 or greater of the \pkg{libc6} package and version 5.4-1 or
+-greater of the \pkg{libncurses5} package: it may not be installed
+-unless an appropriate version of each of these package is installed.
+-On the other hand, the same package conflicts with all versions of the
+-\pkg{tcsh-kanji} and \pkg{tcsh-i18n} packages: \pkg{tcsh} may not be
+-installed at the same time as either of these packages.
+-
+-A single dependency may name several packages, combined with and OR
+-operator (indicated by a vertical bar).  For instance, version
+-\pkg{1.4.48} of the \pkg{debconf} package depends upon
+-\verb!debconf-i18n | debconf-english!; in order to install debconf,
+-you must also install one of these two packages.
+-
+-Last but not least, dpkg supports what are known as ``virtual''
+-packages.  Each version of each package may \emph{provide} one or more
+-package names; each named package will become a virtual package.
+-Virtual packages can have the same name as a normal package, in which
+-case they are known as \emph{mixed} virtual, or they can exist only
+-through being provided by a normal package, in which case they are
+-known as \emph{pure} virtual.  An unversioned dependency on a virtual
+-package will be satisfied if any provider of the name is installed,
+-while an unversioned conflicts will require that all providers of the
+-name are removed -- but as a special case, direct or implicit
+-self-conflicts are ignored.  Versioned dependencies and conflicts do
+-not, as of this writing, follow provided package names.
+-
+-For instance, the virtual package \pkg{mail-transport-agent} is used
+-to identify packages containing mail transport agents.  Every such
+-package both provides and conflicts with the virtual package, and
+-packages that require a mail transport agent depend on
+-it.\footnote{Due to a quirk in how \pkg{apt} resolves dependencies,
+-  dependencies on a virtual package are required to include a real
+-  package as an alternative: for instance, \pkg{bugzilla} depends on
+-  \url{sendmail | mail-transport-agent}.}
+-
+-\section{An Abstract Model of Dependency Relationships}
+-
+-As can be seen in the previous section, real dependency systems are
+-complex.  This tends to complicate the business of reasoning about how
+-to find solutions to dependency problems, and to cause algorithms that
+-manipulate dependencies to become horribly messy.  In situations like
+-this, it is often a good idea to find a simpler, more mathematical
+-model of the problem being analyzed.  Of course, it is well-known that
+-package dependencies can be reduced to the satisfaction of Boolean
+-equations, but such a reduction is arguably \emph{too} extreme: it
+-certainly results in a mathematical model, but the model it produces
+-hides the structure of the original problem.  The following section
+-describes an alternate model which is sufficient to capture any
+-dependency problem (at least in Debian) and retains the structure of a
+-package system.
+-
+-\subsection{Basic Concepts}
+-
+-In this simplified model, the only objects in the world are packages,
+-versions of packages, and dependencies.  Packages will typically be
+-denoted by $p_1, \dots$; versions will typically be denoted by $v_1,
+-\dots$; and dependencies are of the form $v -> \{v_1', \dots\}$,
+-indicating that the version $v$ requires the versions $\{v_1',
+-\dots\}$.  The package associated with a version $v$ is denoted by
+-$\pkgof{v}$.
+-
+-To represent the state of the entire system, the following sets are
+-defined:
+-
+-\begin{itemize}
+-\item $\P$ is the set of all packages.
+-\item $\V$ is the set of all package versions.
+-\item $\D$ is the set of all dependencies.\footnote{Not the set of all
+-    \emph{potential} dependencies, but the set of all dependencies
+-    asserted in the current package system.}
+-\end{itemize}
+-
+-Throughout this paper, I will assume that $\P$ and $\V$ (and hence
+-$\D$) are finite.
+-
+-\subsection{Reduction of Debian Dependencies to the Model}
+-
+-As claimed above, it is possible to reduce a Debian dependency system
+-to this abstracted model.  The reduction proceeds in approximately the
+-following way:
+-
+-\begin{itemize}
+-\item $\P$ is the set of Debian packages.
+-\item $\V$ is the set of versions of those packages, plus one
+-  additional version for each package.  This version represents the
+-  state of the package when it is not installed.  Versions
+-  corresponding to versions of the Debian package are indicated by $p
+-  \col n$ where $n$ is the version number, while the ``uninstalled''
+-  version is indicated by $p_u$.
+-\item For each dependency of the version $v$ of a package on
+-  $\pkg{A}_1\ |\ \dots$, accumulate a set $S$ containing all the
+-  matching versions of each named package, combined with every package
+-  version that provides a named package (if the dependency is
+-  unversioned).
+-
+-  For instance, if $v$ declares a dependency on \verb!A (>= 3.2) | B!,
+-  versions $3.1$, $3.2$, and $3.3$ of package \pkg{A} are available,
+-  versions $1$, $2$, and $3$ of package \pkg{B} are available, and
+-  package \pkg{C} version $3.14$ provides \pkg{B}, then
+-  $S=\{\pkg{A} \col 3.2,\pkg{A} \col 3.3,\pkg{B} \col 1,\pkg{B} \col 2,B \col 3,\pkg{C} \col 3.14\}$.
+-
+-  $\D$ contains $v -> S$ for every such dependency.
+-\item For each conflict declared by a version $v$ on the package $p$,
+-  accumulate a set $S$ containing all the \emph{non}-matching versions
+-  of $p$, including the ``uninstalled'' version, and insert $v -> S$
+-  into $\D$.  Furthermore, if the conflict is not versioned, then for
+-  each package $p'$ and version $v'$ of $p'$ such that $v'$ provides
+-  $p$, let $S=\{v'' \st \pkgof{v''}=p' \land \text{$v''$ does not
+-    provide $p$}\}$ and insert $v -> S$ into $\D$.
+-
+-  For instance, if $v$ conflicts with \pkg{A}, of which versions 3.2
+-  and 3.3 are available, versions 2 and 3 of \pkg{B} provide \pkg{A},
+-  and no other versions of \pkg{B} are available, then
+-  $S=\{\pkg{A} \col 3.2,\pkg{A} \col 3.3,\pkg{A} \col \pkg{UNINST},\pkg{B} \col 2,\pkg{B} \col \pkg{UNINST}\}$.
+-
+-  \begin{note}
+-    In reality, extra care must be taken to screen out self-conflicts
+-    in this process, but the description above is complicated enough
+-    as it stands!
+-  \end{note}
+-\end{itemize}
+-
+-\begin{remark}
+-  Although the above reduction is complicated to describe, its major
+-  steps must be performed whenever any program is analyzing
+-  dependencies: for instance, when listing all the versions that can
+-  fulfill a dependency, it is necessary to iterate over all members of
+-  each OR and to search their providing packages as necessary.  Thus,
+-  an ``on-the-fly'' reduction in an algorithm written for the generic
+-  model is conceivably almost as efficient as an algorithm that works
+-  with the Debian package structure directly.
+-\end{remark}
+-
+-\subsection{Installations}
+-
+-An \emph{installation} represents a choice about which package
+-versions to install; it is a function that maps each package to a
+-version of that package.
+-
+-\begin{definition}
+-  An installation $I$ installs a version $v$, written $I \installs v$,
+-  if $I(\pkgof{v})=v$.
+-\end{definition}
+-
+-\begin{definition}
+-  An installation $I$ satisfies a dependency $d=v -> S$ if either $I
+-  \not \installs v$ or $I \installs v'$ for some $v' \in S$.
+-\end{definition}
+-
+-\begin{definition}
+-  An installation $I$ is \emph{consistent} if $I \satisfies d$ for all
+-  $d \in \D$.
+-\end{definition}
+-
+-\begin{definition}
+-  If $I$ is an installation, then $I;p \mapsto v$ is a new
+-  installation which installs the version $v$ of the package $p$ and
+-  leaves all other packages unchanged:
+-
+-  \begin{equation}
+-    (I;p \mapsto v)(p') = \begin{cases}
+-      I(p'), & p' \neq p \\
+-      v, & p' = p
+-    \end{cases}
+-  \end{equation}
+-
+-  As a shorthand, the following notation indicates that a particular
+-  version of a package is to be installed:
+-
+-  \begin{equation}
+-    I;v = I;\pkgof(v) \mapsto v
+-  \end{equation}
+-\end{definition}
+-
+-\section{The Dependency Resolution Problem}
+-
+-\subsection{Problem Definition}
+-
+-Let $I_0$ be an inconsistent installation.  We would like to find a
+-consistent installation that is ``similar to'' $I_0$.  This is the
+-dependency resolution problem.  In a real package manager, it
+-corresponds to a situation in which the user's requests have resulted
+-in an invalid state (with unsatisfied dependencies or conflicts); the
+-goal of the package manager in this situation is to find a ``small''
+-and ``good'' set of changes that result in a valid state.
+-
+-\begin{note}
+-  This problem is poorly defined: ``small'' and ``good'' are not
+-  precise terms.  The goal, from a UI point of view, is to not change
+-  too many packages, but to make reasonable decisions: for instance,
+-  if the user has requested that some packages be installed and these
+-  installations cause dependency clashes, ``solving'' the problem by
+-  cancelling the installations is probably not the desired result.
+-  However, while it might have obviously wrong solutions, \emph{this
+-    problem has no principled correct solution}, because it is
+-  possible that if several different users view a single dependency
+-  problem, each prefers a different solution from the others.  In
+-  other words, some of the information necessary to find the ``best''
+-  solution is inside the user's head.
+-
+-  Thus, the best we can do is to define some criteria for ``goodness''
+-  (to prioritize solutions that are more likely to interest the user)
+-  and allow the user to see alternatives to an undesired solution.
+-\end{note}
+-
+-\subsection{Dependency Resolution is NP-complete}
+-
+-In order to find a ``good'' solution, we must first find \emph{any}
+-solution to the existing set of dependencies.  Unfortunately, as shown
+-below, this is an NP-complete problem.
+-
+-\begin{theorem}
+-  Dependency resolution is NP-complete.
+-\end{theorem}
+-
+-\begin{proof}
+-  Proof is by reduction from CNF-SAT to the problem ``does a
+-  consistent installation $I$ exist?''
+-
+-  Create one package for each variable and for each clause in the SAT
+-  problem.  For each variable $x$, let the versions of the
+-  corresponding package be $x \col 0$ and $x \col 1$; for each clause,
+-  create exactly one version.  For each SAT clause let $v_c$ be the
+-  package corresponding to the clause, and insert $v_c -> S$ into
+-  $\D$, where for each literal of a variable $x$ appearing in the
+-  clause, $S$ contains $x \col 0$ if $x$ is a negative literal and $x
+-  \col 1$ if $x$ is a positive literal.  This reduction is clearly
+-  polynomial-time; I claim that a solution to this set of dependencies
+-  exists if and only if a solution to the corresponding SAT problem
+-  exists.
+-
+-  Suppose that there is an assignment that solves the SAT problem.
+-  Define an installation $I$ as follows: if $p$ corresponds to a
+-  clause, $I(p)$ is the single version of $p$; if $p$ corresponds to a
+-  variable $x$, $I(p)=x \col 0$ if $x$ is FALSE in the SAT solution
+-  and $I(p)=x \col 1$ if $x$ is TRUE in the SAT solution.  Now,
+-  consider any dependency $d=v -> S$.  From the construction above,
+-  $S$ and $v$ correspond to a clause of the SAT instance.  At least
+-  one literal in this clause must be assigned the value TRUE
+-  (otherwise the clause is not satisfied); let $x$ be the
+-  corresponding variable.  If the literal is positive, then (by
+-  construction) $S$ contains $x \col 1$; since $x$ must be assigned
+-  the value TRUE. $I \installs x \col 1$.  Hence, $I \satisfies d$.
+-  On the other hand, if the literal is negative, then $S$ contains $x
+-  \col 0$ and $I \installs x \col 0$, so $I \satisfies d$.  Thus, $I$
+-  is a consistent installation.
+-
+-  On the other hand, suppose that there is a consistent installation
+-  $I$.  For all variables $x$, let $p$ be the corresponding package;
+-  if $I(p)=x \col 0$, assign FALSE to $x$, and if $I(p)=x \col 1$,
+-  assign TRUE to $x$.  Now consider any clause in the SAT problem:
+-  from the construction above, $\D$ contains a dependency $v_c -> S$
+-  where $v_c$ is the single version of the package corresponding to
+-  the clause.  Since we must have $I \installs v_c$ and since $I$ is
+-  consistent, there must be a version $v' \in S$ such that $I
+-  \installs v'$.  But from the construction, there is some $x$ such
+-  that $v$ corresponds to either $x \col 1$, where $x$ appears as a
+-  positive literal in the clause or $x \col 0$, where $x$ appears as a
+-  negative literal in the clause.  Thus, the clause is satisfied, and
+-  so the assignment described above satisfies all clauses.
+-
+-  Therefore, dependency resolution is NP-complete.
+-\end{proof}
+-
+-\subsection{Don't Panic}
+-
+-Although the problem at hand is NP-complete in general, there is good
+-reason to think that the instances that arise in practice are
+-tractable.  It is well-known that many NP-complete problems have
+-``easy'' and ``hard'' instances: some instances of the problem can be
+-solved quickly by relatively naive algorithms, while others are
+-intractable even using the most sophisticated techniques available.
+-
+-In the particular case of package dependencies, the traditions that
+-have grown up around package tools seem to encourage the creation of
+-easy instances of the dependency problem; furthermore, the user's
+-desired installation is typically consistent or ``almost consistent''
+-(meaning that few dependencies are violated).  It is usually
+-straightforward, when solving problems in an ad hoc way, to isolate a
+-small part of the dependency graph in which the problem occurs; for
+-instance, by informally applying a constraint such as ``don't solve
+-dependencies by removing core library packages''.  Once this is done,
+-the problem can be declared either solvable or unsolvable on the basis
+-of a quick analysis of that region of the graph.
+-
+-In fact, when even relatively basic search techniques are applied to
+-many typical dependency problems, the difficulties that arise are
+-related not to a paucity of solutions, but rather to an excess of
+-them.  That is, finding \emph{a} solution is easy, but finding the
+-\emph{right} solution is more problematic.  Indeed, in the Debian
+-framework there is always at least one solution: removing every
+-package on the system will satisfy all the dependencies.  However, for
+-obvious reasons, this is not a solution that we want to produce!
+-
+-\subsection{Solving Dependencies Through Best-First Search}
+-
+-This problem statement suggests the use of a relatively simple
+-algorithm -- best-first search -- to resolve dependencies.  To briefly
+-review, best-first search works by keeping a priority queue, known as
+-the ``open'' queue, of potential (or partial) solutions.  The priority
+-queue is sorted according to some heuristic function that quantifies
+-the ``goodness'' of each node (often in terms of nearness to a full
+-solution).  In each iteration of the algorithm, the ``best'' partial
+-solution is removed from the queue.  If it is a full solution, the
+-algorithm terminates; otherwise, each ``successor'' node is generated
+-and placed in the queue.
+-
+-There are two main issues to resolve:
+-
+-\begin{itemize}
+-\item How should successors be generated?
+-\item What heuristic should be used?
+-\end{itemize}
+-
+-To generate successors, we could simply enqueue all possible changes
+-to a single package.  However, this would result in a gigantic
+-branching factor (over 1500 branches at each step in the current
+-Debian archive), and it would cause the algorithm to consider
+-adjusting packages that were utterly irrelevant to the problem at
+-hand, as well as changing a package multiple times (which can lead to
+-choices being made for reasons that are obscure to the user).  A more
+-focussed approach is needed.
+-
+-Similarly, we could simply use the number of currently unsatisfied
+-dependencies as our heuristic, but this does not provide any guidance
+-as to how dependencies should be resolved.  If \pkg{A} depends on
+-\pkg{B}, \pkg{A} is installed, and \pkg{B} is not installed, it is
+-usually better to install \pkg{B} than to remove \pkg{A}; however, a
+-straight count of broken dependencies would consider both solutions to
+-be equally ``good''.
+-
+-\subsubsection{Generating Successors to a Partial Solution}
+-
+-An obvious way of generating the successors of a given solution is to
+-do it on the basis of unsatisfied dependencies.  If the installation
+-$I$ does not satisfy the dependency $v -> S$, we know that $v$ is
+-installed but no member of $S$ is.  To resolve this dependency, we can
+-either install a different version of $\pkgof{v}$ or install any
+-element of $S$.  Applying this rule to each ``broken'' dependency in
+-turn will produce a set of successors that each solve at least one
+-dependency (although they may break others in the process).
+-
+-However, this approach still has the potential to ``run in circles''
+-by installing one version of a package, encountering broken
+-dependencies, and then moving to a different version (possibly after
+-resolving some dependencies of the intermediate version).  The problem
+-resolver of \pkg{apt}, for instance, sometimes confuses users by
+-exhibiting this behavior.  To fix this, I enforce a simple rule in
+-generating solutions: a solution should never modify a package twice.
+-
+-\begin{definition}
+-  If the original installation was $I_0$, then for any $I$ and any $d
+-  \in \D$ such that $I \not \satisfies d$, the installation $I'=I;v$
+-  is a successor of $I$ for $d$ if $v \neq I_0(\pkgof{v})$ and
+-  $I(\pkgof{v})=I_0(\pkgof{v})$.
+-\end{definition}
+-
+-One might wonder whether this approach risks overlooking solutions:
+-for instance, maybe it really is necessary to ``go in circles'' in
+-order to find a particular solution.  However, as shown below, if a
+-solution cannot be generated through the application of the successor
+-rule defined above, then there is a ``simpler'' version of that
+-solution (one which modifies the states of fewer packages) that can be
+-generated.  To prove this, I first will introduce some definitions and
+-notation.
+-
+-\begin{definition}
+-  Let $I_1$, $I_2$ be installations.  The following notation is used
+-  to denote the ``distance'' from $I_1$ to $I_2$ (defined as the
+-  number of packages whose mappings differ between $I_1$ and $I_2$).
+-
+-  \begin{equation}
+-    \idist{I_1}{I_2}=\len{\{p \st I_1(p) \neq I_2(p)\}}
+-  \end{equation}
+-\end{definition}
+-
+-\begin{definition}
+-  Let $I_1$, $I_2$ be installations.  An installation $I'$ is a
+-  \emph{hybrid} of $I_1$ and $I_2$ if for all $p$, either
+-  $I'(p)=I_1(p)$ or $I'(p)=I_2(p)$.
+-\end{definition}
+-
+-\begin{note}
+-  An alternative phrasing is that if $I'$ is a hybrid of $I_1$ and
+-  $I_2$, then for all $v$ such that $I' \installs v$, either $I_1
+-  \installs v$ or $I_2 \installs v$.
+-\end{note}
+-
+-\begin{definition}
+-  If $I'$ is a successor of $I$ with respect to $I_0$ for the
+-  dependency $d$, then $I \nsol{I_0}{d} I'$.  If there exist $I_1,
+-  \dots, I_n$ and $d_1, \dots, d_n$ such that $I_1 \nsol{I_0}{d_1} I_2
+-  \nsol{I_0}{d_2} \dots \nsol{I_0}{d_{n-1}} I_n$, then $I_1
+-  \nsolmany{I_0} I_n$.
+-\end{definition}
+-
+-\begin{lemma}
+-  Let $I_c$ be any consistent installation (if one exists) and $I_0$
+-  be any installation.  For all hybrids $I$ of $I_0$ and $I_c$ and all
+-  dependencies $d \in \D$ such that $I \not \satisfies d$, there
+-  exists an $I'$ such that $I \nsol{I_0}{d} I'$, $I'$ is a hybrid of
+-  $I_0$ and $I_c$, and $\idist{I'}{I_c} < \idist{I}{I_c}$.
+-\end{lemma}
+-
+-\begin{proof}
+-  Consider any hybrid $I$ of $I_0$ and $I_c$ such that $I$ is not a
+-  solution and any $d=v -> S \in \D$ such that $I \not \satisfies d$.
+-
+-  Suppose that $I_c \not \installs v$.  Since $I$ is a hybrid of $I_0$
+-  and $I_c$, $I_0 \installs v$.  Thus, $I \nsol{I_0}{d} I'$, where
+-
+-  \begin{equation}
+-    I'=I;I_c(\pkgof{v})
+-  \end{equation}
+-
+-  On the other hand, if $I_c \installs v'$ for some $v' \in S$, then
+-  $I_0 \not \installs v'$.  Therefore, $I \nsol{I_0}{d} I'$, where
+-
+-  \begin{equation}
+-    I'=I;v'
+-  \end{equation}
+-
+-  In either case, clearly $I'$ is a hybrid of $I_0$ and $I_c$ and
+-  $\idist{I'}{I_c}<\idist{I}{I_c}$, proving the lemma.
+-\end{proof}
+-
+-\begin{theorem}
+-  For any consistent installation $I_c$ and any inconsistent
+-  installation $I_0$, there exists a consistent installation $I_c'$
+-  such that $I_c'$ is a hybrid of $I_0$ and $I_c$, and $I_0
+-  \nsolmany{I_0} I_c'$.
+-  \label{thm:succ-sufficient}
+-\end{theorem}
+-
+-\begin{proof}
+-  Proof is by repeated application of the previous lemma.  Consider
+-  any inconsistent hybrid $I$ of $I_0$ and $I_c$.  Let $I^{+}$ be the
+-  $I'$ shown to exist in the previous lemma for an arbitrary $d$ such
+-  that $I \not \satisfies d$, and define a sequence $I_1, \dots$ as
+-  follows:
+-
+-  \begin{equation}
+-    I_k = \begin{cases}
+-      I_{k-1} & \text{if $I_{k-1}$ is consistent} \\
+-      I_k^{+} & \text{otherwise}
+-    \end{cases}
+-  \end{equation}
+-
+-  I claim that this sequence converges; i.e., that for some finite $n$
+-  and all $m>n$, $I_n=I_m$.  Proof: let $D_k=\idist{I_k}{I_c}$ and
+-  $n=\idist{I_0}{I_c}$.  By the previous lemma, $D_k \geq D_{k+1}$ for
+-  all $k$, and $D_k=D_{k+1}$ if and only if $I_k$ is a solution.
+-  Thus, if $I_k$ is not a solution, we have $D_k \leq n-k$.  But by
+-  definition, $D_k \geq 0$ for all $k$, so clearly $I_{n+1}$ is a
+-  solution (else we have $0 \leq D_{n+1} \leq -1$).
+-
+-  Therefore, the theorem holds with $I_c'=D_{n+1}$.
+-\end{proof}
+-
+-\subsubsection{Scoring}
+-
+-The second key ingredient of a best-first search is a scheme for
+-ordering search nodes, typically by assigning a numerical value to
+-each prospective solution.  In doing so, we must balance two
+-priorities: the desire to find a solution quickly, and the desire to
+-find a \emph{good} solution.
+-
+-The most obvious way to guide the search towards a solution is to
+-``reward'' avenues of inquiry that decrease the number of unsatisfied
+-dependencies.  This is not, of course, guaranteed to produce a
+-solution quickly; however, in practice, it seems to be a sufficient
+-hint for the algorithm to reach a goal node in a reasonable number of
+-steps\footnote{Most searches seem to converge in under 5000 steps.}.
+-Finding ``good'' solutions is somewhat more difficult, not least
+-because of the fact that ``good'' is an ill-defined property.  The
+-experimental implementation of this algorithm in \pkg{aptitude} uses
+-the following general criteria to assign scores to nodes:
+-
+-\begin{itemize}
+-\item Each version of each package is assigned a separate score.  By
+-  default, removing any package is heavily penalized, altering
+-  packages which were automatically installed recieves a smaller
+-  penalty, maintaining the state of an automatic package makes no
+-  contribution to the score, and maintaining the state of a manually
+-  installed package receives a bonus.\footnote{In actuality, all that
+-    is calculated is the difference between the initial total version
+-    score and the final total version score.}
+-
+-\item A penalty is applied to each search node based on its distance
+-  from the root of the search.  This works to favor ``simpler''
+-  solutions and penalize more complex ones.
+-
+-\item Nodes that resolve all dependencies are given an additional
+-  bonus -- usually a relatively minor one.  Goal nodes are moved
+-  through the priority queue in the normal manner, rather than being
+-  floated directly to its head, in order to ensure that solutions that
+-  are particularly ``bad'' are not produced unless it is absolutely
+-  necessary to do so.
+-\end{itemize}
+-
+-Thus, letting $B(I)$ be the set of dependencies that are ``broken''
+-(not satisfied) by $I$ and letting $h(v)$ be the score of the version
+-$v$, the total score of an installation is
+-
+-\begin{equation}
+-  h(I) = \alpha_B|B(I)| + \alpha_L \idist{I}{I_0} + \alpha_G \delta(0,|B(I)|) + \sum_{p \in \P} h(I(p))
+-\end{equation}
+-
+-where $\alpha_B$, $\alpha_L$, and $\alpha_G$ are weighting factors and
+-$\delta$ is the Kronacker delta function (i.e., $\delta(i,j)$ is $1$
+-if $i=j$ and $0$ otherwise).  In the current implementation,
+-$\alpha_B=-100$, $\alpha_L=-10$, and $\alpha_G=50$.
+-
+-\section{Reducing the Branching Factor}
+-
+-\subsection{One Dependency at a Time}
+-
+-The algorithm laid out above is sufficient to solve many of the
+-dependency problems that are encountered in practice.  However, some
+-problems still cause the search to take an unacceptable amount of time
+-to reach a solution.  The problems observed fall into two main
+-categories:
+-
+-\begin{enumerate}
+-\item Too many reverse dependencies.
+-
+-  In order to calculate the score of a successor of an installation
+-  (and of course to analyze that solution later on) it is necessary to
+-  generate the set of dependencies which are not satisfied by that
+-  successor.  However, there are some one hundred thousand
+-  dependencies in the Debian archive; so that it completes in a
+-  reasonable amount of time, the current implementation uses the
+-  obvious optimization of only testing those dependencies which either
+-  were previously broken, which impinge on the package version being
+-  removed, or which impinge on the package version being
+-  installed.\footnote{Recall that a successor to $I$ will install
+-    version $v$ of $p$, removing $I(p)$ in the process.}
+-
+-  Unfortunately, some packages have very many reverse dependencies.
+-  For instance, if $I$ removes the system C library, over a thousand
+-  dependencies will be unsatisfied -- and simply generating the
+-  successors of this node will require time at least \emph{quadratic}
+-  in the number of reverse dependencies of \pkg{libc}.  This can
+-  impose a significant performance penalty on the process of successor
+-  generation.
+-
+-\item Removing the bottom of a dependency chain.
+-
+-  When an important library such as GTK is removed, it is necessary to
+-  propagate the removal ``up the dependency tree''.  However, the
+-  search technique outlined above will search exponentially many
+-  installations before settling on this solution.  Aside from the goal
+-  node of ``keep the library on the system'', the first step of the
+-  search will enqueue one node for each package depending on GTK; each
+-  node will remove its corresponding package.  As these nodes are
+-  processed, pairs of packages will be removed from the system; then
+-  triples, and so on, until the full power set of all packages
+-  depending (directly or indirectly) on GTK is generated.  Worse, at
+-  each step, solutions that suggest installing GTK (and removing many
+-  packages) will be generated.
+-\end{enumerate}
+-
+-There is a simple solution to both of these problems.  Instead of
+-generating successors for every dependency, it is sufficient to
+-generate successors for a single, arbitrary dependency (as shown in
+-Theorem~\ref{thm:succ-sufficient}).  In theory, this could lead to
+-somewhat less optimal ordering of generated solutions, but this
+-doesn't seem to be a major problem in practice and the decrease in the
+-problem's branching factor is well worth it.
+-
+-\subsection{Exclude Supersets of Solutions}
+-
+-One simple way to trim the search tree is to drop any search node $I$
+-that is a ``superset'' of a full solution $I_c$ -- meaning that $I_c$
+-is a hybrid of $I$ and $I_0$.  This has the additional beneficial
+-effect of preventing obviously redundant solutions from being offered
+-to the user.
+-
+-a previously-displayed solution with some extra, redundant
+-actions added to it.
+-
+-\subsection{Forbidden versions}
+-
+-If we have a choice between removing \pkg{p} and installing \pkg{q},
+-and we choose to remove \pkg{p}, why should we ever install \pkg{q}?
+-This question leads to yet another way of reducing the problem's
+-branching factor.
+-
+-To each solution node $I$, attach a set $F$ of \emph{forbidden}
+-versions; the successors of $I$ are restricted to those which do not
+-install any version in $F$.  For all successors $I'$ of $I$, let $F'
+-\subseteq F$; furthermore, if a successor $I'$ of $I$ is generated by
+-removing the source version of a dependency, then all of the targets
+-of that dependency are members of $I'_F$.  This new successor
+-relationship is formally defined in Figure~\vref{fig:excludever}.
+-
+-\begin{figure}
+-  \begin{gather*}
+-    \inferrule{I \not \satisfies d \\ d = v -> S \\
+-      I(v')=I_0(v') \\ \pkgof{v'}=\pkgof{v} \\ v' \notin F}
+-    {(I,F) \nsol{I_0}{d} (I;v',F \cup S)} \\
+-    \inferrule{I \not \satisfies d \\ d = v -> S \\ v' \in S \\
+-      I(v')=I_0(v') \\ v' \notin F}
+-    {(I,F) \nsol{I_0}{d} (I;v', F)}
+-  \end{gather*}
+-
+-  \caption{Successor generation with forbidden versions}
+-  \label{fig:excludever}
+-\end{figure}
+-
+-This has the effect of forcing the algorithm to ``stick with'' a
+-decision to forgo installing the targets of a dependency in favor of
+-shifting the source.  Of course, it is important to verify that
+-cutting off wide swathes of the search space in this manner does not
+-impede our ability to generate solutions:
+-
+-\begin{theorem}
+-  Let $I_c$ be any consistent installation (if one exists) and $I_0$
+-  be any installation.  There exists an $I_c'$ such that $I_c'$ is a
+-  hybrid of $I_0$ and $I_0 \nsolmany{I_0} I_C'$.
+-\end{theorem}
+-
+-\begin{proof}
+-  Let $F_0=\emptyset$.  I claim that there exists a sequence
+-  $(I_1,F_1),\dots$ such that for all $k \geq 0$,
+-
+-  \begin{itemize}
+-  \item For all $v \in F_k$, $I_c \not \installs v$.
+-  \item $I_0 \nsolmany{I_0} I_k$
+-  \item Either $k=0$, $I_{k-1}$ is consistent and $I_k=I_{k-1}$, or
+-    $\idist{I_k}{I_c}<\idist{I_{k-1}}{I_c}$.
+-  \end{itemize}
+-
+-  Proof is by induction on $k$.  Suppose that a sequence
+-  $(I_1,F_1),\dots,(I_k,F_k)$ exists satisfying the above condition.
+-  If $I_k$ is consistent, then let $I_{k+1}=I_k$ and $F_{k+1}=F_k$;
+-  the inductive hypothesis is satisfied immediately.
+-
+-  Otherwise, consider any $d=v -> S \in \D$ such that $I_k \not
+-  \satisfies d$ (since $I_k$ is inconsistent, at least one such $d$
+-  exists).  If there is a $v' \in S$ such that $I_c \installs v'$,
+-  then let $I_{k+1}=I_k;v'$ and $F_{k+1}=F_k$.  Clearly $I_c \not
+-  \installs v''$ for all $v'' \in F_{k+1}$ and
+-  $\idist{I_{k+1}}{I_c}<\idist{I_k}{I_c}$; since we additionally have
+-  $(I_k,F_k) \nsol{I_0}{d} (I_{k+1},F_k)$, the inductive hypothesis
+-  holds.
+-
+-  If instead $I_c \not \installs v'$ for all $v' \in S$, then since
+-  $I_c$ is consistent, $I_c(\pkgof{v}) \neq v$.  Let
+-  $I_{k+1}=I_k;I_c(\pkgof{v})$ and $F_{k+1}=F_k \cup S$. $I_c \not
+-  \installs v''$ for all $v'' \in S$ by definition and clearly
+-  $\idist{I_{k+1}}{I_c}<\idist{I_k}{I_c}$.  In addition, $I_k
+-  \nsol{I_0}{d} I_{k+1}$ by Figure~\ref{fig:excludever}; therefore,
+-  the inductive hypothesis holds.
+-
+-  Thus, the claim is established: such a sequence exists.  Following
+-  the logic of Theorem~\ref{thm:succ-sufficient}, we can see that for
+-  $n=\idist{I_0}{I_c}$, $I_n$ is a consistent installation.
+-  Furthermore, from the construction above, $I_n$ is a hybrid of $I_0$
+-  and $I_c$.  Thus, the theorem is established with $I_c'=I_n$.
+-\end{proof}
+-
+-\subsection{Use Logical Necessity}
+-
+-In combination with the tracking of forbidden versions, it is also
+-possible to detect \emph{forced installations} and \emph{essential
+-  conflicts}.  A forced installation is one which is logically
+-necessary given $I$ and $F$: for instance, if we have $d=v -> \{v'_1,
+-v'_2\}$, $I$ has touched $v$ (i.e., $I(v) \neq I_0$), $v'_1 \in F$,
+-and $v'_2 \notin I_F$, then the only permissible successor given $d$
+-is $(I;v'_1)$.  An essential conflict is a dependency for which
+-\emph{no} successors can be generated: for instance, if in the
+-previous example we instead had $v'_2 \in F$, then $d$ would be an
+-essential conflict.
+-
+-If any essential conflicts exist in an installation $I$, it is
+-discarded immediately (rather than, for instance, generating
+-successors for all the solvable dependencies).  If any forced
+-installations exist, they are accumulated and a successor formed by
+-adding these installations to $I$ is placed into the open queue.
+-
+-\section{Eliminating ``Stupidity''}
+-
+-\emph{Note: } the material in this section is somewhat speculative and
+-is known to contain errors.
+-
+-\subsection{Overview}
+-
+-The technique described in the previous section will eliminate some
+-obviously redundant solutions.  But can we do better?  In general, an
+-obvious redundancy exists whenever we install $v_1$ to resolve $d_1$
+-and $v_2$ to resolve $d_2$, where $v_1$ solves $d_2$ or $v_2$ solves
+-$d_1$.  Aside from anything else, it is frustrating from a user's
+-perspective to see a dependency resolver that produces ``obviously
+-stupid'' answers.
+-
+-It turns out that there is, in fact, a polynomial-time algorithm which
+-will eliminate all such pairs from a solution.  This algorithm
+-represents a solution (or partial solution) as a \emph{resolution
+-  sequence}:
+-
+-\begin{definition}
+-  A resolution sequence for $I_0 \nsolmany{I_0} I_n$ is a sequence
+-  $\act{v_1}{d_1},\dots,\act{v_n}{d_n}$ where for all $1 \leq k \leq
+-  n$, $I_k=I_{k-1};v_k$ and $I_{k-1} \nsol{I_0}{d_k} I_k$.
+-
+-  A version-dependency pair $\act{v}{d}$ is called an \emph{action};
+-  it indicates that the version $v$ was installed to satisfy the
+-  dependency $d$.
+-\end{definition}
+-
+-This is, of course, just a different way of looking at the problem: it
+-focuses on the series of versions that will be installed, and
+-eliminates the intermediate installations.  However, viewing the
+-problem from this perspective immediately suggests a new way of
+-approaching it.  The basic goal, as stated above, is to eliminate
+-what I will henceforth refer to as \emph{stupid pairs}:
+-
+-\begin{definition}
+-  A stupid pair is a pair of actions
+-  $\left(\act{v_1}{d_1},\act{v_2}{d_2}\right)$ where $v_1$
+-  solves\footnote{$v$ solves $d$ if $v$ appears on the right-hand side
+-    of $d$, or if the left-hand side of $d$ is $v' \neq v$ where
+-    $\pkgof{v} = \pkgof{v'}$.}  $d_2$ or $v_2$ solves $d_1$.
+-\end{definition}
+-
+-\subsection{The Elimination Algorithm}
+-
+-Is there a way to manipulate the resolution sequence itself by
+-interchanging and/or dropping elements from the sequence so as to
+-eliminate all stupid pairs?  The answer is ``yes''!
+-Algorithm~\vref{alg:eliminate-stupid} takes a starting installation
+-$I_0$ and a resolution sequence $R$, and produces a new resolution
+-sequence $R'$ such that $R' \subseteq R$.  To express the algorithms
+-concisely, the following (ab)uses of notation are introduced:
+-
+-\begin{enumerate}
+-\item If $I$ is an installation and $R$ is a resolution sequence,
+-  $I;R$ indicates the application of $R$ to $I$: i.e., $I;R=I;\{v \st
+-  \exists d . \act{v}{d} \in R\}$.
+-
+-\item If $I$ is an installation, then $Broken(I)$ is the set of broken
+-  dependencies in $I$.
+-
+-\item If $R$ is a resolution sequence, I use $R$ in several places as
+-  a set to indicate either the set of versions contained in $R$ or the
+-  set of actions contained in $R$ (the usage will be clear from
+-  context).
+-
+-\item ``Take any'' means that the program should arbitrarily choose a
+-  single element of the specified set.
+-
+-\item On Line \ref{line:unpack-stupid-pair}, read the ``let'' as an
+-  unpacking command: the sequence $R$ is divided into three
+-  subsequences based on the first-occuring stupid pair.
+-
+-\item A set $S$ of versions is \emph{package-unique} if each package
+-  is represented at most once in $S$: i.e., for all $v,v' \in S$, if
+-  $\pkgof{v}=\pkgof{v'}$ then $v=v'$.
+-\end{enumerate}
+-
+-\begin{algorithm}[p]
+-\begin{algorithmic}[1]
+-\Procedure{EliminateStupid}{$I_0$, $R$}
+-  \Require{$R$ is a resolution sequence for $I_0$ and $Broken(I_0;R) = \emptyset$}
+-  \If{$R$ contains no stupid pairs}
+-    \State \textbf{return} $R$
+-  \Else
+-    \State Let $R_1',\act{v_i}{d_i},R_2',\act{v_j}{d_j},R_3' = R$
+-           where $\left(\act{v_i}{d_i},\act{v_j}{d_j}\right)$ is
+-           a stupid pair and where $(a_1,a_2)$ is not a stupid pair for
+-           all $a_1 \in R_1'$ and $a_2 \in R$. \label{line:unpack-stupid-pair}
+-
+-    \State Let $I' = I_0;R_1';v_j;R_2';R_3'$
+-    \If{$Broken(I') = \emptyset$}
+-      \State Let $R' = R_1',\act{v_j}{d_i},\Call{ResolveFrom}{I_0;R_1';v_j,R_2' \cup R_3'}$
+-      \State \textbf{return} \Call{EliminateStupid}{$I_0$, $R'$} \label{line:eliminate-stupid-recur-1}
+-    \Else
+-      \State Take any dependency $d_k$ such that $I' \not \satisfies d_k$ and $v_i \satisfies d_k$.
+-      \State Let $R' = R_1',\act{v_i}{d_k},R_2',\act{v_j}{d_j},R_3'$.
+-      \State \textbf{return} \Call{EliminateStupid}{$I_0$, $R'$} \label{line:eliminate-stupid-recur-2}
+-    \EndIf
+-  \EndIf
+-\EndProcedure
+-\end{algorithmic}
+-\label{alg:eliminate-stupid}
+-\caption{Algorithm to eliminate stupid pairs}
+-\end{algorithm}
+-
+-\begin{algorithm}[p]
+-\begin{algorithmic}[1]
+-\Procedure{ResolveFrom}{$I$, $S$}
+-  \Require{$Broken(I;S)=\emptyset$, $S$ is package-unique, and $v \notin I$ for all $v \in S$}
+-  \If{$Broken(I)=\emptyset$}
+-    \State \textbf{return} $()$
+-  \Else
+-    \State Take any $d \in Broken(I)$ \label{line:resolve-from-take-broken}
+-    \State Take any $v \in S$ such that $v$ solves $d$ \label{line:resolve-from-take-solver}
+-    \State \textbf{return} $\left(\act{v}{d}, \Call{ResolveFrom}{I;v, S \backslash v}\right)$ \label{line:resolve-from-recur}
+-  \EndIf
+-\EndProcedure
+-\end{algorithmic}
+-\caption{Algorithm to resolve all dependencies from $S$}
+-\label{alg:resolve-from}
+-\end{algorithm}
+-
+-Informally, \textsc{ResolveFrom} is a routine which takes an
+-installation and a set from which to draw versions, and generates an
+-arbitrary resolution sequence by resolving all broken dependencies
+-using the supplied versions.  The \textsc{EliminateStupid} routine
+-works by eliminating the first stupid pair in the resolution sequence.
+-This pair must consist of $\left(\act{v_1}{d_1},\act{v_2}{d_2}\right)$
+-where $v_2$ solves $d_1$; intuitively, the idea is that we could just
+-as well have installed $v_2$ instead of $v_1$.  Unfortunately, it is
+-possible that simply cancelling the installation of $v_1$ will break
+-some packages that were never explicitly fixed.  In this case, we know
+-that there are packages that are not fixed by anything in the sequence
+-except $v_1$, so we can justify the installation of $v_1$ by reference
+-to them.
+-
+-After deciding upon the content of an eventual solution,
+-\textsc{EliminateStupid} invokes \textsc{ResolveFrom} to generate a
+-``sensible'' ordering of the solution and to drop unneeded versions
+-from the solution.
+-
+-\subsection{Correctness of \textsc{EliminateStupid}}
+-
+-\begin{lemma}[Correctness of \textsc{ResolveFrom}]
+-  If $Broken(I;S)=\emptyset$, $S$ is package-unique, and $v \notin I$
+-  for all $v \in S$, then \textsc{ResolveFrom}
+-  (Algorithm~\vref{alg:resolve-from}) terminates and returns a
+-  resolution sequence $R$ for $I \nsolmany I;R$ such that
+-  $Broken(I;R)=\emptyset$ and each element of $R$ is $\act{v}{d}$ for
+-  some $v \in S$.
+-  \label{lem:resolve-from-correct}
+-\end{lemma}
+-
+-\begin{proof}
+-  Proof is by induction on $S$.
+-
+-  If $S=\emptyset$, then $I;S=S$ and hence $Broken(I)=\emptyset$.
+-  Thus, the algorithm terminates immediately.
+-
+-  Suppose instead that $S \neq \emptyset$ and that the lemma holds for
+-  all $S'$ such that $S' \subset S$.  If $Broken(I)=\emptyset$ then
+-  the algorithm again terminates immediately; otherwise, at least one
+-  broken dependency exists for
+-  Line~\ref{line:resolve-from-take-broken} to assign to $d$.  Since
+-  $Broken(I;S)=\emptyset$, there must exist a $v \in S$ such that $v
+-  \satisfies d$; Line~\ref{line:resolve-from-take-solver} will take an
+-  arbitrary such $v$.
+-
+-  Finally, note that on Line~\ref{line:resolve-from-recur},
+-  \textsc{ResolveFrom} is applied to a set $S \backslash v$; since $v
+-  \in S$, we have $S \backslash v \subset S$ (i.e., $S \backslash v$
+-  is strictly smaller than $S$) and hence the inductive hypothesis
+-  holds.  Therefore, the recursive invocation $\Call{ResolveFrom}{I;v,
+-    S \backslash v}$ terminates and returns a resolution sequence $R$
+-  for $I;v$ such that $Broken(I;v;R)=\emptyset$ and each element of
+-  $R$ is $\act{v'}{d'}$ for some $v' \in S$.
+-
+-  Clearly, the sequence $R'=\act{v}{d},R$ is returned by
+-  \textsc{ResolveFrom}.  I claim that this sequence satisfies the
+-  lemma requirements.
+-
+-  \begin{itemize}
+-  \item Clearly $I \nsol{I}{d} I;v$.  Let $v_0 = v$, $I_0 = I;v_0$,
+-    and $\act{v_1}{d_1}, \dots, \act{v_n}{d_n} = R$.  Let
+-    $I_1,\dots,I_n$ be the sequence of installations associated with
+-    $R$: the sequence such that $I_{k-1}=I_k;v_k$ and $I_{k-1}
+-    \nsol{I_0}{d_k} I_k$.
+-
+-    For $1 \leq k \leq n$, note that by the lemma statement, we have
+-    $\pkgof{v_k} \neq \pkgof{v_0}$, so $I(\pkgof{v_k}) =
+-    I_0(\pkgof{v_k})$.  By the inductive hypothesis, $I_0(\pkgof{v_k})
+-    \neq v_k$ and hence $I(\pkgof{v_k}) \neq v_k$.  Finally, since
+-    $I_{k-1} \nsol{I_0}{d_k} I_k$, we have $I_{k-1} \not \satisfies
+-    d_k$.
+-
+-    Therefore, $I_{k-1} \nsol{I}{d_k} I_k$ for $1 \leq k \leq n$, and
+-    hence $R'$ is a resolution sequence.
+-
+-  \item Each element of $R$ is $\act{v}{d}$ for some $v \in S$, and
+-    each
+-  \end{itemize}
+-\end{proof}
+-
+-\begin{lemma}[Correctness of \textsc{EliminateStupid}]
+-  If $R$ is a resolution sequence for $I_0$ and
+-  $Broken(I_0;R)=\emptyset$, then $\Call{EliminateStupid}{I_0, R}$ is
+-  a resolution sequence $R'$ for $I_0$ such that $Broken(I_0;R') =
+-  \emptyset$ and $R'$ contains no stupid pairs.
+-  \label{lem:eliminate-stupid-correct}
+-\end{lemma}
+-
+-\begin{proof}
+-  Proof is by induction on the pair $(l,n)$ where $l$ is the length of
+-  $R$ and $n$ is the number of stupid pairs in $R$; these pairs are
+-  ordered lexicographically, so, for instance, $(1,1) < (1,100) <
+-  (2,10) < (5,20)$.
+-
+-  If $n = 0$, then the algorithm terminates immediately.  In this
+-  case, $R$ is a resolution sequence from the lemma prerequisite, and
+-  $R$ contains no stupid pairs by definition.  Thus, the lemma holds.
+-  If $l < 2$, then clearly $n = 0$ and the above reasoning holds.
+-
+-  Suppose instead that $n > 0$ and $l \geq 2$; i.e., there is at least
+-  one stupid pair in $R$; and suppose further that for all $(n',l') <
+-  (n,l)$, the lemma holds.  As in the algorithm, suppose that
+-  $R_1',\act{v_i}{d_i},R_2',\act{v_j}{d_j},R_3'=R$, where
+-  $\left(\act{v_i}{d_i},\act{v_j}{d_j}\right)$ is a stupid pair and no
+-  element of $R_1'$ is implicated in a stupid pair; i.e.,
+-  $\left(\act{v_i}{d_i},\act{v_j}{d_j}\right)$ is the ``first'' stupid
+-  pair in $R$.\footnote{The astute reader will note that
+-    $\act{v_i}{d_i}$ may be implicated in several distinct stupid
+-    pairs.  Assume for the time being that an arbitrary stupid pair
+-    involving $\act{v_i}{d_i}$ is chosen.}
+-
+-  Let $I' = I_0;R_1';v_j;R_2';R_3'$.
+-
+-  If $I'$ is consistent -- i.e., $Broken(I')=\emptyset$, let $R' =
+-  R_1',\act{v_j}{d_i},\Call{ResolveFrom}{I_0;R_1';v_j,R_2' \cup
+-    R_3'}$. By Lemma~\ref{lem:resolve-from-correct},
+-  $\Call{ResolveFrom}{I_0;R_1';v_j,R_2' \cup R_3'}$ is a resolution
+-  sequence for $I_0;R_1';v_j$ such that $Broken(I_0;R')=\emptyset$.
+-  In addition, since each element of
+-  $\Call{ResolveFrom}{I_0;R_1';v_j,R_2' \cup R_3'}$ is a member of
+-  $R_2' \cup R_3'$, the maximum length of $R'$ is
+-  $\len{R_1'}+\len{\{v_j\}}+\len{R_2'}+\len{R_3'}=\len{R}-1$.  Thus,
+-  by the inductive hypothesis, $\Call{EliminateStupid}{I_0,R'}$ is a
+-  resolution sequence for $I_0$ containing no stupid pairs, and hence
+-  so is $\Call{EliminateStupid}{I_0,R}$.
+-
+-  On the other hand, if $I'$ is not consistent, consider any
+-  dependency $d_k$ such that $I' \not \satisfies d_k$.  Since
+-  $I';v_i=I \satisfies d_k$, we must have $v_i \satisfies d_k$ and
+-  hence $R'=R_1',\act{v_i}{d_k},R_2',\act{v_j}{d_j},R_3'$ is a
+-  resolution sequence ($R'$ differs from $R$ only in that the
+-  installation of $v_i$ is justified by reference to $d_k$ rather than
+-  $d_i$); of course, since $I_0;R'=I_0;R$, $Broken(I_0;R')=\emptyset$.
+-
+-  I claim now that there are strictly fewer stupid pairs in $R'$ than
+-  in $R$.  First, note that $\act{v_i}{d_k}$ cannot be implicated in a
+-  stupid pair: if it were, that would imply the existence of some
+-  $\act{v_x}{d_x} \in R'$ such that $v_x \neq v_i$ and $v_x \satisfies
+-  d_k$ -- but then $\act{v_x}{d_x} \in R$ and so we would have $I'
+-  \satisfies d_k$, contradicting the choice of $d_k$.  On the other
+-  hand, as all other elements of $R'$ occur in $R$, the only stupid
+-  pairs occuring among them also occur in $R$.  Thus, $R'$ contains
+-  exactly one less stupid pair than $R$; since $\len{R'}=\len{R}$, we
+-  can apply the lemma inductively to conclude that
+-  $\Call{EliminateStupid}{I_0,R'}$ is a resolution sequence $R''$ such
+-  that $Broken(I_0;R'')=\emptyset$ and $R''$ contains no stupid pairs.
+-\end{proof}
+-
+-\subsection{Efficiency of \textsc{EliminateStupid}}
+-
+-Of course, \textsc{EliminateStupid} is a fairly complex algorithm, and
+-it would be nice to know how much we're paying for it.  A full and
+-careful analysis of the algorithm is beyond the scope of this paper,
+-but this section gives a rough estimate of its worst case running
+-time.  As hinted at below, though, this really is just an estimate:
+-the efficiency of the algorithm depends heavily on the operations used
+-to implement its high-level directives.
+-
+-In the worst case, every single element of the incoming list is
+-implicated in a stupid pair and the last stupid pair decreases the
+-list length by one and creates a list full of stupid pairs; thus, we
+-would expect $O(\len{R}^2)$ recursions of \textsc{EliminateStupid}.
+-Each call to \textsc{ResolveFrom} clearly takes $O(\len{S})$ time, so
+-even if all operations mentioned in these routines are $O(1)$, the
+-worst-case running time of \textsc{EliminateStupid} is about
+-$O(\len{R}^3)$.  In fact, however, these operations are not $O(1)$.
+-Each recursion of \textsc{ResolveFrom} invokes the following
+-operations:
+-
+-\begin{itemize}
+-\item $Broken(I)$ to test whether broken packages exist and to fetch
+-  an arbitrary broken package.  This operation is $O(n)$ in the number
+-  of package versions, or $O(\len{I})$.
+-
+-\item Finding a solution of $d$ in $S$.  A reasonable approach is to
+-  iterate over the possible solutions of $d$, testing each to see if
+-  it is in $S$.  If $S$ is represented by a hash table, the expected
+-  efficiency of this step will be $O(\len{d})$; the current
+-  implementation uses balanced trees, giving a worst-case efficiency
+-  of $O(\len{d}\log \len{S})$ where $\len{d}$ is the number of possible
+-  solutions $d$\footnote{This is not quite an accurate count of the
+-    complexity of testing whether $d$ is satisfied, but it is
+-    reasonably close to correct; in practice, $\len{d}$ is usually
+-    very small.}.
+-
+-\item Some number of ``uninteresting'' constant-time operations.
+-\end{itemize}
+-
+-Thus, the expected running time of $\Call{ResolveFrom}{I,S}$ is
+-$O(\len{S}(\len{I}+\len{d})$ where $\len{d}$ represents the largest
+-degree of any dependency.  Similarly, the following atomic operations
+-are performed in \textsc{EliminateStupid}:
+-
+-\begin{itemize}
+-\item Checking for stupid pairs.
+-
+-  This might appear to be an $O(n^2)$ operation.  Luckily, by using an
+-  associative data structure (i.e., a hash table), the time complexity
+-  of this step can be reduced to $O(n\len{d})$.  The procedure is to
+-  create a structure mapping versions to sets of versions, then scan
+-  through the input sequence.  For each entry $\act{v}{d}$, scan
+-  through the list of versions that can ``solve'' $d$; for all such
+-  $v'$ other than $v$, add $v$ to the set associated with $v'$.  When
+-  this step is complete, each mapping $v'' \mapsto S$ describes a set
+-  of stupid pairs $\{(v'',v''') \st v''' \in S\}$.
+-
+-  It is probably possible to accelerate this step further in the
+-  recursive computation by re-using the computations from the previous
+-  step.  I have not yet done this, as the current algorithm is simpler
+-  and is fast enough in practice.
+-
+-\item Constructing $I'$ and $R'$, both of which require $O(\len{R})$
+-  steps.
+-
+-\item Testing whether $I'$ has broken dependencies; as before, this
+-  requires $O(\len{I'})=O(\len{I_0})$ time.
+-
+-\item Calls to \textsc{ResolveFrom}; as noted above, these require
+-  about $O(\len{I_0}+\len{R})$ time.
+-
+-\item Recursive calls to \textsc{ElminateStupid}, requiring about
+-  $O(\len{R}^2(\len{R}+\len{I_0}))$ time.
+-\end{itemize}
+-
+-
+-
+-\section{Non-mandatory Dependencies}
+-
+-In addition to the standard Depends metadata, Debian also has a class
+-of dependencies known as ``recommendations''.  In the words of section
+-7.2 of Debian's technical policy:
+-
+-\begin{quote}
+-  Recommends: This declares a strong, but not absolute dependency.
+-
+-  The Recommends field should list packages that would be found
+-  together with [the recommending package] in all but unusual
+-  installations.
+-\end{quote}
+-
+-Package management frontends adopt a variety of strategies to deal
+-with recommendations, ranging from completely ignoring them to
+-treating them nearly as strictly as dependencies.  The current best
+-practice seems to be the rule ``install recommendations when a package
+-is first installed; ignore them otherwise''.
+-
+-In this section, I will propose one way in which the above theory and
+-algorithm can be extended to accomodate these non-mandatory
+-relationships.
+-
+-\subsection{``Hard'' and ``Soft''}
+-
+-The information content of a recommendation is equivalent to that of a
+-dependency, and so it makes sense to represent a recommendation in our
+-formal model as a special type of dependency.  I will divide
+-dependencies into two classes: ``hard'' dependencies and ``soft''
+-dependencies.  ``soft'' dependencies, of course, represent
+-recommendations\footnote{Or, to be more precise, recommendations of
+-  packages that are not presently installed, in accordance with the
+-  abovementioned rule.}.
+-
+-Now, although ``soft'' dependencies need not be satisfied in an
+-eventual solution, we would like the algorithm to at least \emph{try}
+-to satisfy them, and in fact it should to make a reasonably
+-significant effort to satisfy them.  In order to ensure that this is
+-done, I suggest the following techniques:
+-
+-\begin{figure}
+-  \begin{gather*}
+-    \inferrule{d \notin C \\
+-      I \not \satisfies d \\ d = v -> S \\
+-      I(v)=I_0(v) \\ \pkgof{v'}=\pkgof{v} \\ v' \not \in F}
+-    {(I,F,C) \nsol{I_0}{d} (I;v',F \cup S,C)} \\
+-    \inferrule{d \notin C \\
+-      I \not \satisfies d \\ d = v -> S \\ v' \in S \\
+-      I(v')=I_0(v') \\ v' \not \in F}
+-    {(I,F,C) \nsol{I_0}{d} (I;v', F,C)} \\
+-    \inferrule{I \not \satisfies d \\ d \text{ is soft}}
+-    {(I,F,C) \nsol{I_0}{d} (I,F,C \cup \{d\})}
+-  \end{gather*}
+-
+-  \caption{Successor generation with soft dependencies}
+-  \label{fig:softdep}
+-\end{figure}
+-
+-\begin{itemize}
+-\item Extend the state of search nodes with an additional set $C$,
+-  representing the dependencies that have been ``closed'' by being
+-  examined at least once.  As shown in Figure~\vref{fig:excludever},
+-  extend successor generation to permit the algorithm to ``give up''
+-  on any open soft dependency: in addition to generating successors
+-  for the various way of solving that dependency, it will also
+-  generate a successor in which no package states are changed, but the
+-  dependency is closed anyway.
+-\item Penalize broken soft dependencies, to reward solutions that
+-  fulfill soft dependencies.
+-\end{itemize}
+-
+-This has not yet been tested, but will likely require some rebalancing
+-of the various weighting factors previously discussed in order to
+-produce reasonable results.
+-
+-\section{Implementation}
+-
+-A prototype implementation of this resolver algorithm exists in the
+-experimental branch of \pkg{aptitude}.  The implementation is composed
+-of two pieces, which are assembled via C++ templates: a search
+-algorithm for a generic dependency problem, and a runtime translation
+-of APT dependencies to the generic form outlined above.  It does not
+-implement ``soft'' dependencies, although their future inclusion is
+-planned.
+-
+-The current implementation seems to perform reasonably well: in the
+-cases that I have tested, solutions are generated quickly enough for
+-interactive use.  However, the order in which solutions are offered is
+-sometimes surprising: for instance, if the installation of a package
+-causes problems, it is common for the first generated solution to be
+-``cancel this installation''.  While, as noted above, there is no
+-perfect solution even in principle and any static weighting is likely
+-to occasionally produce odd results, I expect that some of these
+-problems can be fixed through adjustments of the score function.
+-
+-\section{Future Work}
+-
+-As noted above, the score function needs to be adjusted and soft
+-dependencies need to be supported.  In addition, some consideration of
+-the following questions seems worthwhile to me:
+-
+-\begin{enumerate}
+-\item Is it ever possible to ``divide and conquer'' a dependency
+-  problem?
+-
+-  Rationale: as noted towards the beginning of this paper, informal
+-  analyses of dependency problems often seem to adopt a ``divide and
+-  conquer'' approach.  Moreover, such an approach would have several
+-  important user interface benefits: for instance, it would avoid the
+-  tendency of the algorithm to produce the Cartesian product of all
+-  the different ways to solve each isolated group of dependency
+-  problems.
+-
+-  I do not, however, see an obvious simple way of performing such a
+-  division.
+-
+-\item Can and should ``overly similar'' solutions be detected and
+-  dropped?
+-
+-  When a solution implicates a large number of packages, the current
+-  algorithm tends to produce many solutions which differ only slightly
+-  from one another.  From a user-interface perspective, it might be
+-  desirable to drop some of these solutions.  What metric, if any,
+-  should be used to perform this dropping?
+-\end{enumerate}
+-
+-\end{document}
+diff --git a/src/generic/problemresolver/problemresolver.h b/src/generic/problemresolver/problemresolver.h
+deleted file mode 100644
+index 2cf74fc..0000000
+--- a/src/generic/problemresolver/problemresolver.h
++++ /dev/null
+@@ -1,2825 +0,0 @@
+-// problemresolver.h                  -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.  You should have
+-//   received a copy of the GNU General Public License along with this
+-//   program; see the file COPYING.  If not, write to the Free
+-//   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+-//   MA 02111-1307, USA.
+-
+-//  This program is free software; you can redistribute it and/or
+-//  modify it under the terms of the GNU General Public License as
+-//  published by the Free Software Foundation; either version 2 of the
+-//  License, or (at your option) any later version.
+-//
+-//  This program is distributed in the hope that it will be useful,
+-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//  General Public License for more details.
+-//
+-//  You should have received a copy of the GNU General Public License
+-//  along with this program; see the file COPYING.  If not, write to
+-//  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//  Boston, MA 02111-1307, USA.
+-//
+-//
+-// Generic problem resolver (generic because I want to be able to do
+-// regression-testing for once, if I can figure out how, and Packages
+-// files make lousy regression-tests).
+-
+-#ifndef PROBLEMRESOLVER_H
+-#define PROBLEMRESOLVER_H
+-
+-#include <generic/util/eassert.h>
+-
+-#include <algorithm>
+-#include <map>
+-#include <queue>
+-#include <set>
+-#include <vector>
+-
+-#include <iostream>
+-#include <sstream>
+-
+-#include "dump_universe.h"
+-#include "exceptions.h"
+-#include "solution.h"
+-#include "resolver_undo.h"
+-
+-#include <generic/util/dense_setset.h>
+-#include <generic/util/threads.h>
+-
+-/** A dummy iterator that's always an "end" iterator. */
+-template<class V>
+-struct dummy_end_iterator
+-{
+-public:
+-  /** \return \b true */
+-  static bool end() {return true;}
+-};
+-
+-/** Aborts: this iterator is always invalid. */
+-template<class V>
+-static inline const V &operator*(const dummy_end_iterator<V>&)
+-{
+-  abort();
+-}
+-
+-/** Aborts. */
+-template<class V>
+-static inline dummy_end_iterator<V> operator++(dummy_end_iterator<V>&)
+-{
+-  abort();
+-}
+-
+-/** \defgroup problemresolver Aptitude's problem resolver
+- *
+- *  \section Overview
+- *
+- *  This is a replacement for the standard apt problem resolver.  It
+- *  uses a different algorithm which, while it is less efficient,
+- *  allows the program to have more direct control over the results,
+- *  allows the user to pick and choose from multiple solutions, and
+- *  can produce a more user-friendly explanation of its actions.
+- *
+- *  The problem resolver class is templated on abstract packages.
+- *  Normally this will be the system of apt packages described by
+- *  aptitude_universe, but for the purpose of testing the algorithm a
+- *  simpler package system, the dummy_universe, is used.
+- *
+- *  Each package version has an associated "score" which indicates,
+- *  essentially, how hard the problem resolver will try to keep it on
+- *  the system (or, for negative scores, to remove it from the
+- *  system).  The sum of all installed package's scores is used as a
+- *  heuristic in a directed search of the solution space.
+- *
+- *  \sa \subpage abstract_universe, generic_problem_resolver
+- *
+- *  \page abstract_universe The abstract package universe interface
+- *
+- *  The package universe interface consists of the following
+- *  interrelated Concepts (see the <A
+- *  HREF="http://www.sgi.com/tech/stl/stl_introduction.html">STL
+- *  documentation</A> for a definition of what a Concept is):
+- *
+- *  - \subpage universe_universe
+- *  - \subpage universe_package
+- *  - \subpage universe_version
+- *  - \subpage universe_dep
+- *  - \subpage universe_installation
+- *
+- *  Note that in order to allow APT structures to be wrapped with
+- *  minimal overhead, all iterators in this section are "APT-style"
+- *  iterators: instead of calculating container bounds by invoking an
+- *  "end" method on the container, each iterator has a predicate
+- *  method end() which returns \b true if the iterator is an "end"
+- *  iterator.
+- *
+- *  \sa \ref problemresolver
+- *
+- *  \page universe_universe Universe concept
+- *
+- *  The package universe is the base type representing a domain of
+- *  package relationships.  It contains classes representing the
+- *  various objects in the domain, along with methods to retrieve
+- *  information about the number of entities in the universe and to
+- *  iterate over global lists of entities.
+- *
+- *  aptitude_universe and dummy_universe are models of the generic
+- *  universe concept.
+- *
+- *  \sa \ref universe_package, \ref universe_version, \ref universe_dep
+- *
+- *  A class modelling the Universe concept should provide the
+- *  following members:
+- *
+- *  - <b>package</b>: a model of \ref universe_package "the Package concept".
+- *
+- *  - <b>version</b>: a model of \ref universe_version "the Version concept".
+- *
+- *  - <b>dep</b>: a model of \ref universe_dep "the Dependency concept".
+- *
+- *  - <b>package_iterator</b>: an iterator over the list of all the
+- *  \ref universe_package "package"s in this universe.
+- *
+- *  - <b>dep_iterator</b>: an iterator over the list of all the \ref
+- *  universe_dep "dependencies" in this universe.
+- *
+- *  - <b>broken_dep_iterator</b>: an iterator over the list of all
+- *  "currently broken" \ref universe_dep "dependencies" in this
+- *  universe (i.e., all dependencies that are broken if the "current"
+- *  \ref universe_version "version" of each \ref universe_package
+- *  "package", as given by \ref universe_package "package"::\ref
+- *  universe_package_current_version "current_version()", is
+- *  installed).
+- *
+- *  - <b>get_package_count()</b>: returns the number of \ref
+- *  universe_package "package"s in the universe.
+- *
+- *  - <b>get_version_count()</b>: returns the number of \ref
+- *  universe_version "version"s in the universe.
+- *
+- *  - <b>packages_begin()</b>: returns a <b>package_iterator</b>
+- *  pointing at the first \ref universe_package "package" (in an
+- *  arbitrary ordering) in the universe.
+- *
+- *  - <b>deps_begin()</b>: returns a \b dep_iterator pointing at the
+- *  first \ref universe_dep "dependency" (in an arbitrary ordering) in
+- *  the universe.
+- *
+- *  - <b>broken_begin()</b>: returns a \b broken_dep_iterator pointing
+- *  at the first broken \ref universe_dep "dependency" (in an
+- *  arbitrary ordering) in the universe.
+- *
+- *  \page universe_package Package concept
+- *
+- *  A package is simply a unique collection of \ref universe_version
+- *  "versions".  No two packages in the same universe may share
+- *  versions, and \e exactly one version of a package is installed at
+- *  any given time.  A package has a "currently installed version",
+- *  which is the version that should be included in the starting point
+- *  of a solution search.
+- *
+- *  \sa \ref universe_universe, \ref universe_version, \ref universe_dep
+- *
+- *  A class modelling the Package concept should provide the following
+- *  members:
+- *
+- *  - <b>version_iterator</b>: an iterator over the list of \ref
+- *  universe_version "versions" of a package.
+- *
+- *  - <b>get_name()</b>: returns a string that uniquely names this
+- *  package.  This may be used for debugging output or when dumping a
+- *  portable representation of a dependency problem.
+- *
+- *  - <b>get_id()</b>: returns an integer between 0 and
+- *  U.get_package_count()-1 (where U is the \ref universe_universe
+- *  "universe" to which the package belongs) that uniquely identifies
+- *  this package in U.
+- *
+- *  - <b>bool operator==(package)</b>, <b>operator!=(package)</b>:
+- *  compare packages by identity.  Two package objects compare equal
+- *  if and only if they represent the same package.
+- *
+- *  - <b>bool operator<(package)</b>: an arbitrary total ordering on
+- *  packages.  This should be appropriate for, eg, placing packages
+- *  into a balanced tree structure.
+- *
+- *  - \anchor universe_package_current_version
+- *  <b>current_version()</b>: returns the "currently installed \ref
+- *  universe_version "version"" of the package.  For instance, the
+- *  apt_universe class considers the InstVersion of a package to be
+- *  its "current version".
+- *
+- *  - <b>versions_begin()</b>: returns a version_iterator pointing to
+- *  the head of the list of versions of this package, provided in an
+- *  arbitrary order.
+- *
+- *  \page universe_version Version concept
+- *
+- *  A version is simply a particular variant of a package that may be
+- *  installed.  When the abstract package system is modelling a
+- *  concrete universe (such as the APT universe), versions typically
+- *  correspond either to a real version of the package, or to the
+- *  package's removal.
+- *
+- *  Each version contains a link to its parent package, as well as
+- *  lists of forward and reverse dependencies.
+- *
+- *  \sa \ref universe_universe, \ref universe_package, \ref universe_dep
+- *
+- *  A class modelling the Version concept should provide the following
+- *  members:
+- *
+- *  - <b>dep_iterator</b>: an iterator class for forward dependencies.
+- *
+- *  - <b>revdep_iterator</b>: an iterator class for reverse dependencies.
+- *
+- *  - <b>get_name()</b>: returns a string that uniquely identifies
+- *  this version among all the versions of the same package.
+- *
+- *  - <b>get_id()</b>: returns a number between 0 and
+- *  U.get_version_count()-1 (where U is the \ref universe_universe
+- *  "universe" to which this version belongs) uniquely identifying
+- *  this version.
+- *
+- *  - <b>package get_package()</b>: returns the \ref universe_package
+- *  "package" of which this is a version.
+- *
+- *  - <b>dep_iterator deps_begin()</b>: returns a \b dep_iterator
+- *  pointing to the first \ref universe_dep "dependency" in the list
+- *  of forward dependencies.
+- *
+- *  - <b>revdep_iterator revdeps_begin()</b>: returns a \b
+- *  revdep_iterator pointing to the first \ref universe_dep
+- *  "dependency" in the list of reverse dependencies.
+- *
+- *    \note Although it would be straightforward to define the reverse
+- *    dependencies of a version as the set of dependencies that
+- *    impinge on that version, they are \e not defined in this manner.
+- *    For technical reasons and in order to keep the wrapper to the
+- *    APT package system thin, the reverse dependencies are only
+- *    required to obey the following rule: if \e v1 and \e v2 are
+- *    versions of the same \ref universe_package "package", then for
+- *    any \ref universe_dep "dependency" \e d such that \e v1 is a
+- *    target of \e d and \e v2 is not, or vice versa, \e d appears in
+- *    \e either the reverse dependency list of \e v1 or the reverse
+- *    dependency list of \e v2.
+- *
+- *  - <b>operator==(version)</b>, <b>operator!=(version)</b>:
+- *  compare versions by identity.  Two version objects compare equal
+- *  if and only if they represent the same version of the same
+- *  package.
+- *
+- *  - <b>operator<(version)</b>: an arbitrary total ordering on
+- *  versions.  This should be appropriate for, eg, placing versions
+- *  into a balanced tree structure.
+- *
+- *  \page universe_dep Dependency concept
+- *
+- *  A dependency indicates that if a particular \ref universe_version
+- *  "version" is installed, at least one member of a set of \ref
+- *  universe_version "version"s must also be installed.  The first
+- *  \ref universe_version "version" is the "source" of the dependency,
+- *  while the remaining versions are "solvers" of the dependency.  A
+- *  dependency may be "soft", indicating that it is legal (but
+- *  undesirable) for the dependency to remain broken at the end of a
+- *  solution search.
+- *
+- *  \todo "solvers" should be renamed to "targets", as a dependency
+- *  can also be resolved by removing its source.
+- *
+- *  \sa \ref universe_universe, \ref universe_package, \ref
+- *  universe_version, \ref universe_installation
+- *
+- *  A class modelling the Dependency concept should provide the
+- *  following members:
+- *
+- *  - <b>solver_iterator</b>: an iterator over the versions that are
+- *  targets of this dependency.
+- *
+- *  - <b>version get_source()</b>: returns the source \ref
+- *  universe_version "version" of this dependency.
+- *
+- *  - <b>solver_iterator solvers_begin()</b>: returns a
+- *  solver_iterator pointing to the first target of this dependency.
+- *
+- *  - <b>bool is_soft()</b>: returns \b true if the dependency is "soft".
+- *  For instance, in the Debian package system, a Recommends
+- *  relationship is considered to be a soft dependency.
+- *
+- *  - <b>bool solved_by(version)</b>: return \b true if the given \ref
+- *  universe_version "version" solves this dependency, either by
+- *  removing the source of the dependency or by installing one of its
+- *  targets.
+- *
+- *  - <b>template &lt;typename Installation&gt; bool broken_under(Installation)</b>: return \b true if this dependency
+- *  is broken by the given \ref universe_installation "installation";
+- *  a solution breaks a dependency if and only if it installs the
+- *  dependency's source and none of its targets.
+- *
+- *  - <b>operator==(dependency)</b>, <b>operator!=(dependency)</b>:
+- *  compare dependencies by identity.  Two dependency objects compare
+- *  equal if and only if they represent the same dependency.
+- *  Duplicated dependencies may compare as distinct entities.
+- *
+- *  - <b>operator<(dependency)</b>: an arbitrary total ordering on
+- *  dependencies.  This should be appropriate for, eg, placing
+- *  dependencies into a balanced tree structure.
+- *
+- *  \page universe_installation Installation concept
+- *
+- *  An Installation represents a potential state of an abstract
+- *  dependency system; that is, a set of installed versions (or
+- *  rather, a total function from packages to versions).
+- *
+- *  The generic_solution class is a model of the Installation concept.
+- *
+- *  \sa \ref abstract_universe
+- *
+- *  A class modelling the Installation concept should provide the
+- *  following members:
+- *
+- *  - <b>version version_of(package)</b>: look up the currently
+- *  installed \ref universe_version "version" of the given \ref
+- *  universe_package "package" according to this installation.
+- */
+-
+-/** \brief A generic package problem resolver.
+- *
+- *  \param PackageUniverse A model of the \ref universe_universe
+- *  Universe concept.
+- *
+- *  Searches from the starting node on a best-first basis; i.e., it
+- *  repeatedly pulls the "best" node off its work queue, returns it if
+- *  it is a solution, and enqueues its successors if not.  The
+- *  successor nodes to a given search node are generated by selecting
+- *  a single dependency that is broken at that node and enqueuing all
+- *  possibly ways of fixing it.  The score of a node is affected by:
+- *
+- *  - A penalty/bonus applied to each package version.
+- *
+- *  - A bonus for each step of the solution (used to discourage the
+- *  resolver from "backing up" unnecessarily).
+- *
+- *  - A penalty is added for each broken dependency that has not yet
+- *  been processed.  This aims at directing the search towards "less
+- *  broken" situations.
+- *
+- *  - A penalty for soft dependencies (i.e., Recommends) which were
+- *  processed and left broken.
+- *
+- *  - A bonus for nodes that have no unprocessed broken dependencies.
+- *
+- *  Note that these are simply the default biases set by aptitude; any
+- *  of these scores may be changed at will (including changing a
+- *  penalty to a bonus or vice versa!).
+- *
+- *  \sa \ref problemresolver, \ref universe_universe
+- */
+-template<class PackageUniverse>
+-class generic_problem_resolver
+-{
+-public:
+-  friend class ResolverTest;
+-
+-  typedef typename PackageUniverse::package package;
+-  typedef typename PackageUniverse::version version;
+-  typedef typename PackageUniverse::dep dep;
+-
+-  typedef generic_solution<PackageUniverse> solution;
+-
+-  typedef typename solution::action action;
+-
+-  /** Information about the sizes of the various resolver queues. */
+-  struct queue_counts
+-  {
+-    size_t open;
+-    size_t closed;
+-    size_t deferred;
+-    size_t conflicts;
+-
+-    /** \b true if the resolver has finished searching for solutions.
+-     *  If open is empty, this member distinguishes between the start
+-     *  and the end of a search.
+-     */
+-    bool finished;
+-
+-    queue_counts()
+-      : open(0), closed(0), deferred(0), conflicts(0), finished(false)
+-    {
+-    }
+-  };
+-
+-private:
+-  /** Hash function for packages: */
+-  struct ExtractPackageId
+-  {
+-  public:
+-    size_t operator()(const package &p) const
+-    {
+-      return p.get_id();
+-    }
+-  };
+-
+-  typedef ExtractPackageId PackageHash;
+-
+-  /** Compares solutions according to their "goodness". */
+-  struct solution_goodness_compare
+-  {
+-    bool operator()(const solution &s1, const solution &s2) const
+-    {
+-      return s1.get_score() < s2.get_score();
+-    }
+-  };
+-
+-  /** Compares solutions according to their contents; used to
+-   *  manage "closed".
+-   */
+-  struct solution_contents_compare
+-  {
+-    bool operator()(const solution &s1, const solution &s2) const
+-    {
+-      // Variation on lexicographical comparison.
+-      //
+-      // S1 < S2 if
+-      //   - S1(p)=S2(p) for all p<p' and S1(p')<S2(p'), where
+-      //     p,p' \in \dom(S1) \cup dom(S2)
+-
+-
+-      // NB: the correctness of this code depends implicitly on the
+-      // invariant that the score is a function of the contents of the
+-      // solution.  Essentially we're using the score as a sort of
+-      // hash value on solutions!
+-      if(s1.get_score() < s2.get_score())
+-	return true;
+-      else if(s2.get_score() < s1.get_score())
+-	return false;
+-      else if(s1.get_action_score() < s2.get_action_score())
+-	return true;
+-      else if(s2.get_action_score() < s1.get_action_score())
+-	return false;
+-
+-      const imm::map<package,action>
+-	&a1=s1.get_actions(), &a2=s2.get_actions();
+-      const imm::set<dep>
+-	&us1=s1.get_unresolved_soft_deps(), &us2=s2.get_unresolved_soft_deps();
+-
+-
+-      // Speed hack: order by size first to avoid traversing the whole
+-      // tree.
+-      if(a1.size() < a2.size())
+-	return true;
+-      else if(a2.size() < a1.size())
+-	return false;
+-      else if(us1.size() < us2.size())
+-	return true;
+-      else if(us2.size() < us1.size())
+-	return false;
+-      else
+-	return a1 < a2 || (a2 == a1 && us1 < us2);
+-    }
+-  };
+-
+-  class instance_tracker;
+-  friend class instance_tracker;
+-  class instance_tracker
+-  {
+-    generic_problem_resolver &r;
+-  public:
+-    instance_tracker(generic_problem_resolver &_r)
+-      :r(_r)
+-    {
+-      threads::mutex::lock l(r.execution_mutex);
+-      if(r.solver_executing)
+-	throw DoubleRunException();
+-      else
+-	r.solver_executing = true;
+-    }
+-
+-    ~instance_tracker()
+-    {
+-      threads::mutex::lock l(r.execution_mutex);
+-      eassert(r.solver_executing);
+-
+-      r.solver_executing = false;
+-      r.solver_cancelled = false;
+-    }
+-  };
+-
+-  // Information regarding the weight given to various parameters;
+-  // packaged up in a struct so it can be easily used by the solution
+-  // constructors.
+-  solution_weights weights;
+-
+-  /** Solutions whose score is smaller than this value will be
+-   *  discarded rather than being enqueued.
+-   */
+-  int minimum_score;
+-
+-  /** The "maximum" number of successors to generate for any given
+-   *  node.  Note, however, that a full set of successors will always
+-   *  be generated for each broken dependency, so this is not exact.
+-   *
+-   *  The theoretical justification is that in order to cover all
+-   *  solutions, it's sufficient to generate all successors for a
+-   *  single broken dependency.  This avoids the problem that when a
+-   *  large number of packages are broken, or when a single package
+-   *  version with a large number of reverse dependencies is broken,
+-   *  you can end up searching way too many successor nodes, even if
+-   *  all the successors are discarded outright.
+-   *
+-   *  Unfortunately, only generating one successor has its own
+-   *  problem: solutions might be generated out-of-order (i.e., worse
+-   *  solutions before better).  This variable allows you to seek a
+-   *  "happy medium" by generating a reasonable number of successors,
+-   *  but not too many.  If a single package breaks a large number of
+-   *  other packages, then any attempt to fix those packages should
+-   *  generate the correct successor (which will then pop to the top
+-   *  of the queue and likely stay there), while if a large number of
+-   *  unrelated packages are broken, it doesn't matter which successor
+-   *  goes first.
+-   *
+-   *  Note that in practice, turning this up is very likely to result
+-   *  in dreadful performance; the option to do so may very well be
+-   *  removed in the future.
+-   */
+-  unsigned int max_successors;
+-
+-  /** The universe in which we are solving problems. */
+-  const PackageUniverse universe;
+-
+-  /** If \b true, we have exhausted the list of solutions. */
+-  bool finished:1;
+-
+-  /** If \b true, it is possible that some deferred solutions are
+-   *  no longer "forbidden".
+-   */
+-  bool deferred_dirty:1;
+-
+-  /** If \b true, debugging messages will be sent to stdout. */
+-  bool debug:1;
+-
+-  /** If \b true, so-called "stupid" pairs of actions will be
+-   *  eliminated from solutions. (see paper)
+-   */
+-  bool remove_stupid:1;
+-
+-
+-  // Multithreading support variables.
+-  //
+-  //  These variables ensure (as a sanity-check) that only one thread
+-  //  executes the solver function at once, and allow the executing
+-  //  instance to be cleanly terminated.  They are managed by the
+-  //  instance_tracker class (see above).
+-
+-  /** If \b true, a thread is currently executing in the solver. */
+-  bool solver_executing : 1;
+-
+-  /** If \b true, the currently executing thread should stop at the
+-   *  next opportunity.
+-   */
+-  bool solver_cancelled : 1;
+-
+-  /** Mutex guarding the solver_executing and stop_solver variables.
+-   *
+-   *  If a routine wants to execute some code conditionally based on
+-   *  whether the resolver is currently executing, it should grab this
+-   *  mutex, test solver_executing, and run the code if
+-   *  solver_executing is \b false.
+-   */
+-  threads::mutex execution_mutex;
+-
+-
+-
+-  queue_counts counts;
+-
+-  /** Mutex guarding the cache of resolver status information. */
+-  threads::mutex counts_mutex;
+-
+-
+-
+-  /** The working queue: */
+-  std::priority_queue<solution, std::vector<solution>, solution_goodness_compare> open;
+-
+-  /** Stores already-seen solutions: */
+-  std::set<solution, solution_contents_compare> closed;
+-
+-  /** Stores solutions that were ignored because of user constraints
+-   *  (but could be reinstated later).  Disjoint with closed.
+-   */
+-  std::set<solution, solution_contents_compare> deferred;
+-
+-  typedef dense_mapset<package, action, ExtractPackageId> conflictset;
+-
+-  /** Stores conflicts: sets of installations that have been
+-   *  determined to be mutually incompatible.
+-   */
+-  conflictset conflicts;
+-
+-  /** The initial set of broken dependencies.  Kept here for use in
+-   *  the stupid-elimination algorithm.
+-   */
+-  imm::set<dep> initial_broken;
+-
+-  /** Stores versions that have been rejected by the user; distinct
+-   *  from the per-solution reject sets that track changes on a single
+-   *  inference path.
+-   */
+-  std::set<version> user_rejected;
+-
+-  /** Stores versions that have been mandated by the user; we should
+-   *  always pick these versions if the chance arises.
+-   */
+-  std::set<version> user_mandated;
+-
+-  /** Stores dependencies that have been "hardened" by the user (that
+-   *  aren't allowed to default).
+-   */
+-  std::set<dep> user_hardened;
+-
+-  /** Stores dependencies that the user has said should be broken if
+-   *  they come up.
+-   */
+-  std::set<dep> user_approved_broken;
+-
+-  /** Stores solutions that were already generated and that have
+-   *  broken soft dependencies.
+-   *
+-   *  \todo Merge this with conflicts so we can accumulate information
+-   *  about it?  Crazy idea: can we model breaking a soft dependency
+-   *  as a special package version with a very low weight in the
+-   *  model, and use that to unify the two?  Think about that.
+-   */
+-  std::vector<solution> generated_solutions;
+-
+-
+-  typedef std::set<std::pair<version, version> > stupid_table;
+-
+-  std::ostream &dump_conflict(std::ostream &out, const imm::map<package, action> &conflict) const;
+-  std::ostream &dump_conflict(std::ostream &out, const action &act) const;
+-
+-
+-  /** \param conflictorpair a (package, action) pair contained in a conflict.
+-   *  \param apair a (package, action) pair from a solution or a conflict.
+-   *
+-   *  \return \b true if the given conflictor matches a.  This relation
+-   *          is transitive, so if c1 matches c2 and c2 matches a,
+-   *          then c1 matches a.
+-   */
+-  static bool conflictor_matches(const std::pair<package, action> &conflictorpair,
+-				 const std::pair<package, action> &apair)
+-  {
+-    const action &conflictor = conflictorpair.second;
+-    const action &a = apair.second;
+-
+-    if(a.ver != conflictor.ver)
+-      return false;
+-
+-    if(!conflictor.from_dep_source)
+-      return true;
+-    else
+-      return a.from_dep_source && a.d == conflictor.d;
+-  }
+-
+-  /** \return \b true if each element of pc2 is matched by an element
+-   *  in pc1.
+-   */
+-  static bool conflict_matches(const typename imm::map<package, action> &c,
+-			       const typename imm::map<package, action> &acts)
+-  {
+-    typename imm::map<package, action>::const_iterator ci = c.begin();
+-    typename imm::map<package, action>::const_iterator ai = acts.begin();
+-
+-    while(ci != c.end() &&
+-	  ai != acts.end())
+-      {
+-	if(ai->first < ci->first)
+-	  ++ai;
+-	else if(ci->first < ai->first)
+-	  return false;
+-	else if(!(conflictor_matches(ci->second, ai->second)))
+-	  return false;
+-	else
+-	  {
+-	    ++ci;
+-	    ++ai;
+-	  }
+-      }
+-
+-    return (ci == c.end());
+-  }
+-
+-  /** Test whether the given partial conflict subsumes an existing
+-   *  conflict.
+-   *
+-   *  \param m the conflict or action to match
+-   *
+-   *  \return a conflict matched by m, or conflicts.end() if no such
+-   *  conflict exists.
+-   */
+-  typename conflictset::const_iterator
+-  find_matching_conflict(const imm::map<package, action> &m) const
+-  {
+-    return conflicts.find_submap(m, &conflictor_matches);
+-  }
+-
+-  /** Test whether the given partial conflict subsumes an existing
+-   *  conflict.
+-   *
+-   *  \param m the conflict or action to match
+-   *  \param actpair a single element that should be present in the
+-   *                 returned conflict.  For instance, if you have a
+-   *                 solution that you know is conflict-free and you
+-   *                 perform a single action, passing this action
+-   *                 as actpair may speed up the search for a
+-   *                 conflict.
+-   *
+-   *  \return a conflict matched by m, or conflicts.end() if no such
+-   *  conflict exists.
+-   */
+-  typename conflictset::const_iterator
+-  find_matching_conflict(const imm::map<package, action> &m,
+-			 const std::pair<package, action> &actpair) const
+-  {
+-    return conflicts.find_submap_containing(m, actpair, &conflictor_matches);
+-  }
+-
+-  /** Test whether the given solution contains a conflict. */
+-  bool contains_conflict(const solution &s) const
+-  {
+-    typename conflictset::const_iterator
+-      found = find_matching_conflict(s.get_actions());
+-    bool rval = (found != conflicts.end());
+-
+-    if(debug && rval)
+-      {
+-	std::cout << "The conflict ";
+-	dump_conflict(std::cout, *found);
+-	std::cout << " is triggered by the solution ";
+-	s.dump(std::cout);
+-	std::cout << std::endl;
+-      }
+-
+-    return rval;
+-  }
+-
+-#if 0
+-  /** Test whether the given solution contains a conflict when the
+-   *  given action is taken.
+-   *
+-   *  \return such a conflict if it exists; otherwise conflicts.end().
+-   */
+-  typename std::set<std::map<package, act_conflict> >::const_iterator
+-  will_conflict(const solution &s,
+-		const act_conflict &a) const
+-  {
+-    // For now I'm being lazy and actually generating a full mapping.
+-    // However, this could be done much more efficiently if optimizing
+-    // this code is important.
+-    std::map<package, act_conflict> m;
+-
+-    populate_partial_conflict(s, m);
+-
+-    package p = a.ver.get_package();
+-
+-    m[p] = a;
+-
+-    typename std::set<std::map<package, act_conflict> >::const_iterator
+-      result = subsumes_any_conflict(m);
+-
+-    if(debug && result != conflicts.end())
+-      {
+-	std::cout << "Adding " << p.get_name() << " "
+-		  << a.ver.get_name();
+-
+-	if(a.from_dep_source)
+-	  std::cout << " due to " << a.d;
+-
+-	std::cout << " will trigger conflict ";
+-	dump(std::cout, *result);
+-	std::cout << std::endl;
+-      }
+-
+-    return result;
+-  }
+-
+-  /** Generate a table listing the "stupid" pairs of actions in a
+-   *  solution.  If (a,b) is in the table, then b solves the
+-   *  dependency that triggered a's installation.
+-   */
+-  void initialize_stupid_pairs(const solution &s,
+-			       stupid_table &table)
+-  {
+-    for(typename std::map<package, action>::const_iterator i = s.get_actions().begin();
+-	i != s.get_actions().end(); ++i)
+-      {
+-	const dep &d = i->second.d;
+-
+-	for(typename dep::solver_iterator j = d.solvers_begin();
+-	    !j.end(); ++j)
+-	  {
+-	    // Don't claim that (v,v) is a stupid pair.
+-	    if(*j == i->second.ver)
+-	      continue;
+-
+-	    typename std::map<package, action>::const_iterator found
+-	      = s.get_actions().find((*j).get_package());
+-
+-	    // Check whether j will be installed; if so, insert it.
+-	    if(found != s.get_actions().end() &&
+-	       found->second.ver == *j)
+-	      table.insert(std::pair<version, version>(i->second.ver, *j));
+-	  }
+-      }
+-  }
+-
+-  /** A solution wrapper suitable for use with broken_under() that
+-   *  drops one mapping from the solution.
+-   */
+-  class drop_package
+-  {
+-    solution s;
+-    package drop;
+-  public:
+-    drop_package(const solution &_s, const package &_drop)
+-      :s(_s), drop(_drop)
+-    {
+-    }
+-
+-    version version_of(const package &p) const
+-    {
+-      if(p == drop)
+-	return p.current_version();
+-      else
+-	return s.version_of(p);
+-    }
+-  };
+-
+-  /** An action iterator wrapper that replaces the action on a given
+-   *  package with the given action.
+-   */
+-  class swap_action
+-  {
+-    typename std::map<package, action>::const_iterator i;
+-    package replace;
+-    action with;
+-  public:
+-    swap_action(const typename std::map<package, action>::const_iterator &_i,
+-		const package &_replace, const action &_with)
+-      : i(_i), replace(_replace), with(_with)
+-    {
+-    }
+-
+-    bool operator==(const swap_action &other) const
+-    {
+-      return i == other.i && replace == other.replace && with.ver == other.with.ver;
+-    }
+-
+-    bool operator!=(const swap_action &other) const
+-    {
+-      return i != other.i || replace != other.replace || with.ver != other.with.ver;
+-    }
+-
+-    swap_action &operator++()
+-    {
+-      ++i;
+-      return *this;
+-    }
+-
+-    const action &operator*() const
+-    {
+-      if(i->first == replace)
+-	return with;
+-      else
+-	return i->second;
+-    }
+-
+-    const action *operator->() const
+-    {
+-      if(i->first == replace)
+-	return &with;
+-      else
+-	return &i->second;
+-    }
+-  };
+-
+-  /** Check whether dropping a version from a solution breaks
+-   *  dependencies.
+-   *
+-   *  \param s the "starting" solution; should not have broken deps
+-   *  \param v the version to drop
+-   *  \param d output parameter; if there is a broken dependency,
+-   *         it will be placed in this location.
+-   *
+-   *  \return \b true if a broken dependency exists.
+-   */
+-  bool broken_by_drop(const solution &s,
+-		      const version &v,
+-		      dep &d)
+-  {
+-    // Don't flag an error if a dep that's SUPPOSED to be unresolved
+-    // gets broken.
+-    const std::set<dep> &ignore_deps = s.get_unresolved_soft_deps();
+-
+-    drop_package dropped(s, v.get_package());
+-
+-    version curr = v.get_package().current_version();
+-    for(typename version::revdep_iterator i = curr.revdeps_begin();
+-	!i.end(); ++i)
+-      if(ignore_deps.find(*i) == ignore_deps.end() &&
+-	 (*i).broken_under(dropped))
+-	{
+-	  d = *i;
+-	  return true;
+-	}
+-
+-    for(typename version::revdep_iterator i = curr.revdeps_begin();
+-	!i.end(); ++i)
+-      if(ignore_deps.find(*i) == ignore_deps.end() &&
+-	 (*i).broken_under(dropped))
+-	{
+-	  d = *i;
+-	  return true;
+-	}
+-
+-    for(typename version::dep_iterator i = curr.deps_begin();
+-	!i.end(); ++i)
+-      if(ignore_deps.find(*i) == ignore_deps.end() &&
+-	 (*i).broken_under(dropped))
+-	{
+-	  d = *i;
+-	  return true;
+-	}
+-
+-    return false;
+-  }
+-
+-  /** Represents an empty solution. */
+-  class null_solution
+-  {
+-  public:
+-    version version_of(const package &p) const
+-    {
+-      return p.current_version();
+-    }
+-  };
+-
+-  /** Represents a partial solution based directly (by reference) on a
+-   *  reference to a map.
+-   */
+-  class map_solution
+-  {
+-    const std::map<package, action> &actions;
+-  public:
+-    map_solution(const std::map<package, action> &_actions)
+-      : actions(_actions)
+-    {
+-    }
+-
+-    version version_of(const package &p) const
+-    {
+-      typename std::map<package, action>::const_iterator found = actions.find(p);
+-
+-      if(found == actions.end())
+-	return p.current_version();
+-      else
+-	return found->second.ver;
+-    }
+-  };
+-
+-  /** Represents a possible successor to the given solution, created
+-   *  by installing a single 'new' version.
+-   */
+-  template<typename SolutionType>
+-  class partial_solution
+-  {
+-    /** The solution this is based on. */
+-    const SolutionType &s;
+-    /** More stuff to install */
+-    std::map<package, version> installations;
+-  public:
+-    /** Initialize a new solution.
+-     */
+-    partial_solution (const SolutionType &_s)
+-      :s(_s)
+-    {
+-    }
+-
+-    /** Takes a range of versions and installs them in order. */
+-    template<typename InputIterator>
+-    void install(const InputIterator &begin, const InputIterator &end)
+-    {
+-      for(InputIterator i = begin; i != end; ++i)
+-	install(i->get_package(), *i);
+-    }
+-
+-    void install(const package &p, const version &v)
+-    {
+-      eassert(installations.find(p) == installations.end());
+-
+-      installations[p]=v;
+-    }
+-
+-    /** \return the currently installed version of the given
+-     *	package.
+-     */
+-    version version_of(const package &pkg) const
+-    {
+-      typename std::map<package, version>::const_iterator found=installations.find(pkg);
+-
+-      if(found!=installations.end())
+-	return found->second;
+-      else
+-	return s.version_of(pkg);
+-    }
+-
+-    /** Test whether the given version is installed in this solution.
+-     */
+-    bool ver_installed(const version &test_ver) const
+-    {
+-      return version_of(test_ver.get_package()) == test_ver;
+-    }
+-  };
+-
+-  /** Wrap a solver list by generating pairs where the second value
+-   *  is a bound constant value.
+-   */
+-  class forbid_iter_builder
+-  {
+-    typename dep::solver_iterator i;
+-    dep d;
+-  public:
+-    forbid_iter_builder(const typename dep::solver_iterator &_i,
+-			const dep &_d)
+-      :i(_i), d(_d)
+-    {
+-    }
+-
+-    typename std::pair<version, dep> operator*() const
+-    {
+-      return std::pair<version, dep>(*i, d);
+-    }
+-
+-    forbid_iter_builder &operator++()
+-    {
+-      ++i;
+-      return *this;
+-    }
+-
+-    bool end() const
+-    {
+-      return i.end();
+-    }
+-  };
+-
+-  /** Wrap an iterator over pairs to an iterator over the second
+-   *  element of the pair.
+-   */
+-  template<typename Iter>
+-  class project_iter_2nd_impl
+-  {
+-    Iter i;
+-  public:
+-    project_iter_2nd_impl(const Iter &_i)
+-      :i(_i)
+-    {
+-    }
+-
+-    typename Iter::value_type::second_type &operator*() const
+-    {
+-      return i->second;
+-    }
+-
+-    typename Iter::value_type::second_type *operator->() const
+-    {
+-      return &i->second;
+-    }
+-
+-    project_iter_2nd_impl &operator++()
+-    {
+-      ++i;
+-      return *this;
+-    }
+-
+-    bool operator==(const project_iter_2nd_impl &other) const
+-    {
+-      return i == other.i;
+-    }
+-
+-    bool operator!=(const project_iter_2nd_impl &other) const
+-    {
+-      return i != other.i;
+-    }
+-  };
+-
+-  template<typename Iter>
+-  project_iter_2nd_impl<Iter> project_iter_2nd(const Iter &i)
+-  {
+-    return project_iter_2nd_impl<Iter>(i);
+-  }
+-
+-  /** Wrap an action iterator to select its version element. */
+-  template<class Iter>
+-  class project_ver_impl
+-  {
+-    Iter i;
+-  public:
+-    project_ver_impl(const Iter &_i)
+-      :i(_i)
+-    {
+-    }
+-
+-    bool operator==(const project_ver_impl &other)
+-    {
+-      return i == other.i;
+-    }
+-
+-    bool operator!=(const project_ver_impl &other)
+-    {
+-      return i != other.i;
+-    }
+-
+-    project_ver_impl &operator++()
+-    {
+-      ++i;
+-      return *this;
+-    }
+-
+-    const version &operator*() const
+-    {
+-      return i->ver;
+-    }
+-
+-    const version *operator->() const
+-    {
+-      return &i->ver;
+-    }
+-  };
+-
+-  template<typename Iter>
+-  project_ver_impl<Iter> project_ver(const Iter &i)
+-  {
+-    return project_ver_impl<Iter>(i);
+-  }
+-
+-
+-  /** Convert a [begin,end) pair to a single APT-style iterator.
+-   */
+-  template<class iter>
+-  class apt_iter_wrapper_impl
+-  {
+-    iter curr, the_end;
+-  public:
+-    apt_iter_wrapper_impl(const iter &_begin, const iter &_end)
+-      :curr(_begin), the_end(_end)
+-    {
+-    }
+-
+-    bool end() const
+-    {
+-      return curr==the_end;
+-    }
+-
+-    apt_iter_wrapper_impl &operator++()
+-    {
+-      ++curr;
+-      return *this;
+-    }
+-
+-    const typename std::iterator_traits<iter>::reference operator*() const
+-    {
+-      return *curr;
+-    }
+-
+-    const typename std::iterator_traits<iter>::reference operator->() const
+-    {
+-      return &*curr;
+-    }
+-  };
+-
+-  template<class Iter>
+-  apt_iter_wrapper_impl<Iter> apt_iter_wrapper(const Iter &begin,
+-					       const Iter &end)
+-  {
+-    return apt_iter_wrapper_impl<Iter>(begin, end);
+-  }
+-
+-
+-  /** Given a list of actions, remove "obviously" unnecessary actions;
+-   *  that is, actions which are not inspired by any broken
+-   *  dependency.  Corresponds to ResolveFrom, but is a bit more
+-   *  extreme in its approach.  As usual, no effort is made to avoid
+-   *  stupid pairs.
+-   *
+-   *  \param actions the set of actions to apply
+-   *
+-   *  \param unresolved_soft_deps a set of broken dependencies which
+-   *                             are permitted (indeed, required?)
+-   *                             to be broken at the end of the process.
+-   *
+-   *  \param forbidden_iter an iterator over the list of versions that
+-   *  should be forbidden in the new solution.
+-   *
+-   *  \return a solution containing only the actions which appear to
+-   *  be necessary.
+-   */
+-  template<typename forbid_iter>
+-  solution filter_unnecessary_actions(const std::vector<action> &actions,
+-				      const std::set<dep> &unresolved_soft_deps,
+-				      const forbid_iter &forbidden_iter)
+-  {
+-    // Versions from which to choose.
+-    std::set<version> avail_versions(project_ver(actions.begin()),
+-				     project_ver(actions.end()));
+-
+-    // Currently broken deps.
+-    std::set<dep> broken_deps = initial_broken;
+-
+-    // The solution being built.
+-    std::map<package, action> output_actions;
+-
+-    // Score of this solution
+-    int action_score = 0;
+-
+-    while(!broken_deps.empty())
+-      {
+-	eassert(!avail_versions.empty());
+-
+-	// Pick an "arbitrary" broken dependency.
+-	dep d = *broken_deps.begin();
+-	broken_deps.erase(broken_deps.begin());
+-
+-	// If it's to be ignored, just drop it on the floor.
+-	if(unresolved_soft_deps.find(d) != unresolved_soft_deps.end())
+-	  continue;
+-
+-	// Now, pick an "arbitrary" resolver of this dep.
+-	//
+-	// (maybe pick the best-scored one that's available instead?)
+-	bool found_one = false;
+-	version solver;
+-	for(typename dep::solver_iterator si = d.solvers_begin();
+-	    !si.end(); ++si)
+-	  {
+-	    typename std::set<version>::const_iterator found
+-	      = avail_versions.find(*si);
+-
+-	    if(found != avail_versions.end())
+-	      {
+-		found_one = true;
+-		solver = *si;
+-		break;
+-	      }
+-	  }
+-
+-	// I have a proof that a solver should exist, but that doesn't
+-	// mean it does ;-)
+-	eassert(found_one);
+-	eassert(output_actions.find(solver.get_package()) == output_actions.end());
+-	eassert(solver != solver.get_package().current_version());
+-
+-	if(debug)
+-	  std::cout << "Filter: resolving " << d << " with "
+-		    << solver.get_package().get_name() << ":"
+-		    << solver.get_name() << std::endl; 
+-
+-	action act(solver, d, output_actions.size());
+-
+-	// Update the set of broken dependencies.  FIXME: it should be
+-	// possible to do this in-place, maybe using immutable sets?
+-	std::set<dep> new_broken;
+-	update_broken(partial_solution<map_solution>(output_actions),
+-		      project_ver(&act),
+-		      project_ver((&act)+1),
+-		      unresolved_soft_deps,
+-		      broken_deps,
+-		      new_broken);
+-
+-	// Expensive copy.
+-	broken_deps = new_broken;
+-
+-	// Finally, update the old solution with the new action.
+-	output_actions[solver.get_package()] = act;
+-	action_score += step_score;
+-	action_score += version_scores[solver.get_id()];
+-	action_score -= version_scores[solver.get_package().current_version().get_id()];
+-      }
+-
+-    // By definition we have a solution now.
+-    int score = action_score + full_solution_score + unfixed_soft_score * unresolved_soft_deps.size();
+-
+-    return solution(project_iter_2nd(output_actions.begin()),
+-		    project_iter_2nd(output_actions.end()),
+-		    unresolved_soft_deps,
+-		    broken_deps,
+-		    forbidden_iter,
+-		    score,
+-		    action_score);
+-  }
+-
+-  /** Eliminate stupid pairs from the given solution.
+-   *
+-   *  \param s the solution from which stupid pairs should be removed.
+-   *
+-   *  \return the new solution
+-   */
+-  solution eliminate_stupid(const solution &s)
+-  {
+-    eassert(s.get_broken().empty());
+-
+-    stupid_table stupid_pairs;
+-
+-    initialize_stupid_pairs(s, stupid_pairs);
+-
+-    solution rval = s;
+-
+-    bool contained_stupid = !stupid_pairs.empty();
+-
+-    while(!stupid_pairs.empty())
+-      {
+-	if(debug)
+-	  {
+-	    std::cout << "Eliminating stupid pairs from ";
+-	    rval.dump(std::cout);
+-	    std::cout << std::endl;
+-	  }
+-
+-	// The pair to eliminate; picked (sorta) arbitrarily.
+-	const typename std::pair<version, version> &victim = *stupid_pairs.begin();
+-	stupid_pairs.erase(stupid_pairs.begin());
+-
+-	// This is where we discard pairs that are no longer relevant
+-	// because one of the elements of the pair has been dropped.
+-	if(rval.get_actions().find(victim.first.get_package()) == rval.get_actions().end() ||
+-	   rval.get_actions().find(victim.second.get_package()) == rval.get_actions().end())
+-	  {
+-	    if(debug)
+-	      std::cout << "Dropping invalidated stupid pair("
+-			<< victim.first.get_package().get_name()
+-			<< ":" << victim.first.get_name() << ","
+-			<< victim.second.get_package().get_name()
+-			<< ":" << victim.second.get_name() << ")"
+-			<< std::endl;
+-
+-	    continue;
+-	  }
+-
+-	if(debug)
+-	  std::cout << "Examining stupid pair ("
+-		    << victim.first.get_package().get_name()
+-		    << ":" << victim.first.get_name() << ","
+-		    << victim.second.get_package().get_name()
+-		    << ":" << victim.second.get_name() << ")" << std::endl;
+-
+-	// Suppose we drop the second element in favor of the first.
+-	// Will that produce a valid solution?
+-	dep first_broken;
+-
+-	// If something was broken, then we need to use the fallback
+-	// position: just change the dependency given as the "reason"
+-	// for the first action.
+-	if(broken_by_drop(rval, victim.first, first_broken))
+-	  {
+-	    if(debug)
+-	      std::cout << "Unable to drop "
+-			<< victim.first.get_package().get_name()
+-			<< ":" << victim.first.get_name()
+-			<< ", changing justification to "
+-			<< first_broken << std::endl;
+-
+-	    typename std::map<package, action>::const_iterator found = rval.get_actions().find(victim.first.get_package());
+-	    eassert(found != rval.get_actions().end());
+-
+-	    action repl_action(victim.first, first_broken,
+-			       found->second.id);
+-
+-	    // Note that the score is perfectly correct, as it depends
+-	    // only on the set of versions in rval (which doesn't
+-	    // change).  The set of forbidden versions is in some
+-	    // sense "wrong", but if we have a final solution this
+-	    // shouldn't be a problem.
+-
+-	    swap_action swbegin(rval.get_actions().begin(),
+-				victim.first.get_package(),
+-				repl_action);
+-	    swap_action swend(rval.get_actions().end(),
+-			      victim.first.get_package(),
+-			      repl_action);
+-
+-	    rval = solution(swbegin, swend,
+-			    rval.get_unresolved_soft_deps(),
+-			    rval.get_broken(),
+-			    apt_iter_wrapper(rval.get_forbidden_versions().begin(),
+-					     rval.get_forbidden_versions().end()),
+-			    rval.get_score(), rval.get_action_score());
+-	  }
+-	else
+-	  {
+-	    if(debug)
+-	      std::cout << "Dropping "
+-			<< victim.first.get_package().get_name()
+-			<< ":" << victim.first.get_name()
+-			<< " and filtering unnecessary installations."
+-			<< std::endl;
+-	    // Ok, it's safe.
+-	    //
+-	    // Generate a node by dropping the second element and
+-	    // changing the version of the first:
+-	    std::vector<action> actions;
+-
+-	    for(typename std::map<package, action>::const_iterator i =
+-		  s.get_actions().begin(); i != s.get_actions().end(); ++i)
+-	      {
+-		if(i->second.ver == victim.first)
+-		  actions.push_back(action(victim.second, i->second.d,
+-					   i->second.id));
+-		else if(i->second.ver != victim.second)
+-		  actions.push_back(i->second);
+-	      }
+-
+-	    rval = filter_unnecessary_actions(actions,
+-					      rval.get_unresolved_soft_deps(),
+-					      apt_iter_wrapper(rval.get_forbidden_versions().begin(),
+-							       rval.get_forbidden_versions().end()));
+-	  }
+-      }
+-
+-    if(debug)
+-      {
+-	if(contained_stupid)
+-	  {
+-	    std::cout << "Done eliminating stupid pairs, result is ";
+-	    rval.dump(std::cout);
+-	    std::cout << std::endl;
+-	  }
+-	else
+-	  {
+-	    std::cout << "No stupid pairs in ";
+-	    rval.dump(std::cout);
+-	    std::cout << std::endl;
+-	  }
+-      }
+-
+-    eassert(rval.get_broken().empty());
+-
+-    return rval;
+-  }
+-#endif
+-
+-  solution eliminate_stupid(const solution &s) const
+-  {
+-    if(debug)
+-      std::cout << "Would eliminate stupid, but stupid elimination is disabled." << std::endl;
+-
+-    return s;
+-  }
+-
+-  /** Calculate whether the solution is rejected based on
+-   *  user_rejected by testing whether the intersection of the
+-   *  solution domain and the rejected set is nonempty.
+-   */
+-  bool contains_rejected(const solution &s) const
+-  {
+-    for(typename std::set<version>::const_iterator uri
+-	  = user_rejected.begin(); uri != user_rejected.end(); ++uri)
+-      {
+-	typename imm::map<package, action>::node found = s.get_actions().lookup(uri->get_package());
+-
+-	if(found.isValid() && found.getVal().second.ver == *uri)
+-	  {
+-	    if(debug)
+-	      std::cout << "Rejected version " << found.getVal().first.get_name()
+-			<< " " << found.getVal().second.ver.get_name()
+-			<< " detected." << std::endl;
+-
+-	    return true;
+-	  }
+-      }
+-
+-    return false;
+-  }
+-
+-  bool breaks_hardened(const solution &s) const
+-  {
+-    typename std::set<dep>::const_iterator uh_iter
+-      = user_hardened.begin();
+-
+-    if(uh_iter == user_hardened.end())
+-      return false;
+-
+-    typename imm::set<dep>::const_iterator su_iter
+-      = s.get_unresolved_soft_deps().begin();
+-
+-    while(uh_iter != user_hardened.end() &&
+-	  su_iter != s.get_unresolved_soft_deps().end())
+-      {
+-	if(*uh_iter == *su_iter)
+-	  {
+-	    if(debug)
+-	      std::cout << "Broken hardened dependency " << *uh_iter
+-			<< " detected." << std::endl;
+-
+-	    return true;
+-	  }
+-	else if(*uh_iter < *su_iter)
+-	  ++uh_iter;
+-	else
+-	  ++su_iter;
+-      }
+-
+-    return false;
+-  }
+-
+-  bool solves_approved_broken(const solution &s) const
+-  {
+-    const imm::map<package, action> &actions = s.get_actions();
+-
+-    for(typename imm::map<package, action>::const_iterator
+-	  ai = actions.begin(); ai != actions.end(); ++ai)
+-      if(user_approved_broken.find(ai->second.d) != user_approved_broken.end())
+-	return true;
+-
+-    return false;
+-  }
+-
+-  /** \return \b true if the given solution passed up an opportunity
+-   *          to include an 'mandated' version.
+-   */
+-  bool avoids_mandated(const solution &s) const
+-  {
+-    // NB: The current algorithm is not terribly efficient.
+-    for(typename std::set<version>::const_iterator ai = user_mandated.begin();
+-	ai != user_mandated.end(); ++ai)
+-      {
+-	version v = s.version_of(ai->get_package());
+-	// If it's already being installed, then we're fine.
+-	if(v == *ai)
+-	  continue;
+-
+-	// Check (very slowly) whether we made a decision where we had
+-	// the opportunity to use this version (and of course didn't).
+-	for(typename imm::map<package, action>::const_iterator si = s.get_actions().begin();
+-	    si != s.get_actions().end(); ++si)
+-	  if(si->second.d.solved_by(*ai) &&
+-	     user_mandated.find(si->second.ver) == user_mandated.end())
+-	    {
+-	      if(debug)
+-		{
+-		  std::cout << ai->get_package().get_name() << " version " << ai->get_name() << " is avoided (when resolving " << si->second.d << ") by the solution:" << std::endl;
+-		  s.dump(std::cout);
+-		  std::cout << std::endl;
+-		}
+-
+-	      return true;
+-	    }
+-      }
+-
+-    return false;
+-  }
+-
+-  /** \return \b true if the resolution of the given dependency might
+-   *                  be affected by a user constraint.
+-   */
+-  bool impinges_user_constraint(const dep &d) const
+-  {
+-    if(user_hardened.find(d) != user_hardened.end() ||
+-       user_approved_broken.find(d) != user_approved_broken.end())
+-      return true;
+-
+-    for(typename dep::solver_iterator si = d.solvers_begin();
+-	!si.end(); ++si)
+-      {
+-	if(user_rejected.find(*si) != user_rejected.end())
+-	  return true;
+-
+-	for(typename std::set<version>::iterator mi = user_mandated.begin();
+-	    mi != user_mandated.end(); ++mi)
+-	  {
+-	    if(mi->get_package() == (*si).get_package())
+-	      return true;
+-	  }
+-      }
+-
+-    return false;
+-  }
+-
+-
+-  /** \return \b true if the given solution should be deferred. */
+-  bool should_defer(const solution &s) const
+-  {
+-    return contains_rejected(s) || breaks_hardened(s) ||
+-      avoids_mandated(s) || solves_approved_broken(s);
+-  }
+-
+-  /** Place any solutions that were deferred and are no longer
+-   *  rejected back on the open queue.
+-   */
+-  void reexamine_deferred()
+-  {
+-    // NB: the STL guarantees that erasing elements from a set does
+-    // not invalidate existing iterators.  Hence this very careful
+-    // iteration:
+-
+-    typename std::set<solution, solution_contents_compare>::const_iterator
+-      i = deferred.begin(), j = i;
+-
+-    while(i != deferred.end())
+-      {
+-	++j;
+-
+-	if(!should_defer(*i))
+-	  {
+-	    open.push(*i);
+-	    deferred.erase(i);
+-	  }
+-
+-	i = j;
+-      }
+-
+-    // Note that we might have to rescind the "finished" state: the
+-    // actions above can actually cause new solutions to be available
+-    // for processing!
+-    if(finished && !open.empty())
+-      finished = false;
+-
+-    deferred_dirty = false;
+-  }
+-
+-  /** \return \b true if the given solution is "irrelevant": that is,
+-   *  either it was already generated and placed in the closed queue,
+-   *  or it includes an already-generated solution as a proper subset.
+-   */
+-  bool irrelevant(const solution &s)
+-  {
+-    if(closed.find(s) != closed.end())
+-      return true;
+-
+-    if(contains_conflict(s))
+-      return true;
+-
+-    // The efficiency of this step hinges on the *assumption* that the
+-    // number of solutions that will be generated is small relative to
+-    // the number of potential solutions.
+-    for(typename std::vector<solution>::const_iterator i=generated_solutions.begin();
+-	i!=generated_solutions.end(); ++i)
+-      if(std::includes(s.get_actions().begin(), s.get_actions().end(),
+-		       i->get_actions().begin(), i->get_actions().end()) &&
+-	 std::includes(s.get_unresolved_soft_deps().begin(), s.get_unresolved_soft_deps().end(),
+-		       i->get_unresolved_soft_deps().begin(), i->get_unresolved_soft_deps().end()))
+-	return true;
+-
+-    if(s.get_score() < minimum_score)
+-      {
+-	if(debug)
+-	  std::cout << "Not generating solution (infinite badness " << s.get_score() << "<" << minimum_score << ")" << std::endl;
+-	return true;
+-      }
+-
+-    return false;
+-  }
+-
+-  /** Tries to enqueue the given package.
+-   *
+-   *  \return \b true if the solution was not irrelevant.
+-   */
+-  bool try_enqueue(const solution &s)
+-  {
+-    if(irrelevant(s))
+-      {
+-	if(debug)
+-	  {
+-	    std::cout << "Dropping irrelevant solution ";
+-	    s.dump(std::cout);
+-	    std::cout << std::endl;
+-	  }
+-
+-	return false;
+-      }
+-    else if(should_defer(s))
+-      {
+-	if(debug)
+-	  {
+-	    std::cout << "Deferring rejected solution ";
+-	    s.dump(std::cout);
+-	    std::cout << std::endl;
+-	  }
+-
+-	deferred.insert(s);
+-	return false;
+-      }
+-    else
+-      {
+-	if(debug)
+-	  {
+-	    std::cout << "Enqueuing ";
+-	    s.dump(std::cout);
+-	    std::cout << std::endl;
+-	  }
+-
+-	open.push(s);
+-
+-	return true;
+-      }
+-  }
+-
+-  /** Try to enqueue the given collection of packages. */
+-  void try_enqueue(const std::vector<solution> &sols)
+-  {
+-    for(typename std::vector<solution>::const_iterator
+-	  succi = sols.begin();	succi != sols.end(); ++succi)
+-      try_enqueue(*succi);
+-  }
+-
+-  /** Internal routine to check for the legality of a 'move' and
+-   *  generate a conflictor if it's not legal.
+-   */
+-  bool is_legal(const solution &s,
+-		const version &v,
+-		action &out_act) const
+-  {
+-    package p = v.get_package();
+-    version cur = p.current_version();
+-    version inst = s.version_of(p);
+-
+-    if(inst != cur)
+-      {
+-	if(debug)
+-	  std::cout << "Discarding " << p.get_name() << " "
+-		    << v.get_name() << ": monotonicity violation"
+-		    << std::endl;
+-
+-	out_act.ver = inst;
+-	out_act.from_dep_source = false;
+-	return false;
+-      }
+-    else
+-      {
+-	eassert(v != cur);
+-
+-	typename imm::map<version, dep>::node found
+-	  = s.get_forbidden_versions().lookup(v);
+-
+-	if(!found.isValid())
+-	  return true;
+-	else
+-	  {
+-	    const dep &found_d = found.getVal().second;
+-
+-	    if(debug)
+-	      std::cout << "Discarding " << p.get_name() << " "
+-			<< v.get_name() << ": forbidden by the resolution of "
+-			<< found_d << std::endl;
+-
+-	    out_act.ver = s.version_of(found_d.get_source().get_package());
+-	    out_act.d   = found_d;
+-	    out_act.from_dep_source = true;
+-
+-	    return false;
+-	  }
+-      }
+-  }
+-
+-  /** Internal routine to insert a new conflictor into a conflict set.
+-   *  Handles the case in which the conflictor subsumes an existing
+-   *  element of the set.
+-   */
+-  void insert_conflictor(imm::map<package, action> &conflict,
+-			 const action &act) const
+-  {
+-    package p = act.ver.get_package();
+-    typename imm::map<package, action>::node found
+-      = conflict.lookup(p);
+-
+-    if(!found.isValid())
+-      conflict.put(p, act);
+-    else
+-      {
+-	const action &found_act = found.getVal().second;
+-
+-	action a2 = act;
+-
+-	eassert(found_act.ver == act.ver);
+-	if(a2.from_dep_source)
+-	  {
+-	    if(found_act.from_dep_source)
+-	      eassert(a2.d == found_act.d);
+-
+-	    else
+-	      a2.from_dep_source = false;
+-	  }
+-	conflict.put(p, a2);
+-      }
+-  }
+-
+-  /** Generate a solution and push it onto an encapsulated vector of
+-   *  solutions.
+-   */
+-  class real_generator
+-  {
+-    std::vector<solution> &target;
+-  public:
+-    real_generator(std::vector<solution> &_target)
+-      :target(_target)
+-    {
+-    }
+-
+-    template<typename a_iter, class u_iter>
+-    void make_successor(const solution &s,
+-			const a_iter &abegin, const a_iter &aend,
+-			const u_iter &ubegin, const u_iter &uend,
+-			const PackageUniverse &universe,
+-			const solution_weights &weights) const
+-    {
+-      target.push_back(solution::successor(s,
+-					   abegin, aend,
+-					   ubegin, uend,
+-					   universe, weights));
+-    }
+-  };
+-
+-  /** Don't actually generate solutions; instead, just count how many
+-   *  *would* be generated.  Each time a solution would be generated,
+-   *  the integer referenced by this object is incremented (it is
+-   *  never set to 0; if you need it to be initialized to 0, do that
+-   *  yourself).
+-   */
+-  class null_generator
+-  {
+-    int &count;
+-  public:
+-    null_generator(int &_count)
+-      :count(_count)
+-    {
+-    }
+-
+-    template<typename a_iter, class u_iter>
+-    void make_successor(const solution &s,
+-			const a_iter &abegin, const a_iter &aend,
+-			const u_iter &ubegin, const u_iter &uend,
+-			const PackageUniverse &universe,
+-			const solution_weights &weights) const
+-    {
+-      ++count;
+-    }
+-
+-    int get_count() const
+-    {
+-      return count;
+-    }
+-  };
+-
+-  /** Convenience routine for the below: try to generate a successor
+-   *  by installing a single package version.  NB: assumes that the
+-   *  solution's actions have dense identifiers (i.e., less than
+-   *  s.get_actions().size()).
+-   *
+-   *  \param s the solution for which a successor should be generated
+-   *  \param v the version to install
+-   *  \param d the dependency for which the successor is being generated.
+-   *  \param from_dep_source if \b true, this successor is the result
+-   *                         of an action on the source of a dependency
+-   *  \param conflict a map to which conflictors for this version, if
+-   *                  any, will be added.
+-   *
+-   *  \param generator an object supporting the make_successor() routine,
+-   *                   as real_generator and null_generator above.
+-   */
+-  template<typename SolutionGenerator>
+-  void generate_single_successor(const solution &s,
+-				 const dep &d,
+-				 const version &v,
+-				 bool from_dep_source,
+-				 imm::map<package, action> &conflict,
+-				 const SolutionGenerator &generator) const
+-  {
+-    action conflictor;
+-
+-    if(debug)
+-      {
+-	std::cout << "Trying to resolve " << d << " by installing "
+-		  << v.get_package().get_name() << " "
+-		  << v.get_name();
+-	if(from_dep_source)
+-	  std::cout << " from the dependency source";
+-
+-	std::cout << std::endl;
+-      }
+-
+-    const int newid = s.get_actions().size();
+-
+-    if(!is_legal(s, v, conflictor))
+-      insert_conflictor(conflict, conflictor);
+-    else
+-      {
+-	action act(v, d, from_dep_source, newid);
+-
+-	// Speculatively form the new set of actions; doing this
+-	// rather than forming the whole solution allows us to avoid
+-	// several rather expensive steps in the successor routine
+-	// (most notably the formation of the new broken packages
+-	// set).
+-	imm::map<package, action> new_acts = s.get_actions();
+-	new_acts.put(v.get_package(), act);
+-
+-	typename conflictset::const_iterator
+-	  found = find_matching_conflict(new_acts,
+-					 std::pair<package, action>(v.get_package(), act));
+-
+-	if(found == conflicts.end())
+-	  generator.make_successor(s, &act, &act+1,
+-				   (dep *) 0, (dep *) 0,
+-				   universe, weights);
+-	else
+-	  {
+-	    if(debug)
+-	      {
+-		std::cout << "Discarding " << v.get_package().get_name()
+-			  << " " << v.get_name() << " due to conflict ";
+-		dump_conflict(std::cout, *found);
+-		std::cout << std::endl;
+-	      }
+-
+-	    imm::map<package, action> m = *found;
+-
+-	    for(typename imm::map<package, action>::const_iterator ci
+-		  = m.begin(); ci != m.end(); ++ci)
+-	      {
+-		// Discard the version that we were trying to install,
+-		// so that the caller can use this to form a more
+-		// general conflict if all its resolutions fail.
+-		if(ci->first != v.get_package())
+-		  insert_conflictor(conflict, ci->second);
+-		else
+-		  eassert(ci->second.ver == v);
+-	      }
+-	  }
+-      }
+-  }
+-
+-  /** Build the successors of a solution node for a particular
+-   *  dependency.
+-   *
+-   *  \param conflict a map which will be initialized with a conflict
+-   *  explaining the non-appearance of some solvers (if there are no
+-   *  solvers, this will be a full conflict explaining the lack of
+-   *  solvers).
+-   *
+-   *  \param out a vector onto which the successors should be pushed.
+-   */
+-  template<typename SolutionGenerator>
+-  void generate_successors(const solution &s,
+-			   const dep &d,
+-			   imm::map<package, action> &conflict,
+-			   const SolutionGenerator &generator) const
+-  {
+-    version source = d.get_source();
+-    typename imm::map<package, action>::node
+-      source_found = s.get_actions().lookup(source.get_package());
+-
+-    // Try moving the source, if it is legal to do so
+-    if(source_found.isValid())
+-      insert_conflictor(conflict, action(source, d, false, -1));
+-    else
+-      {
+-	eassert(source == source.get_package().current_version());
+-
+-	for(typename package::version_iterator vi = source.get_package().versions_begin();
+-	    !vi.end(); ++vi)
+-	  if(*vi != source)
+-	    generate_single_successor(s, d, *vi, true, conflict, generator);
+-      }
+-
+-    // Now try installing each target of the dependency.
+-    for(typename dep::solver_iterator si = d.solvers_begin();
+-	!si.end(); ++si)
+-      generate_single_successor(s, d, *si, false, conflict, generator);
+-
+-    // Finally, maybe we can leave this dependency unresolved.
+-    if(d.is_soft())
+-      generator.make_successor(s, (action *) 0, (action *) 0,
+-			       &d, &d+1, universe, weights);
+-  }
+-
+-  /** Processes the given solution by enqueuing its successor nodes
+-   *  (if any are available).  Note that for clarity, we now generate
+-   *  *all* successors before examining *any*.
+-   */
+-  void process_solution(const solution &s)
+-  {
+-    // Any forcings are immediately applied to 'curr', so that
+-    // forcings are performed ASAP.
+-    solution curr = s;
+-
+-    eassert(!s.get_broken().empty());
+-
+-    // Set to \b true if this search node is untenable.
+-    bool dead_end = false;
+-
+-    // This loop attempts to generate all the successors of a
+-    // solution.  However, if a "forced" dependency arises, it
+-    // re-verifies all the dependencies of the solution.
+-    bool done = false;
+-    while(!done)
+-      {
+-	if(debug)
+-	  {
+-	    std::cout << "Processing ";
+-	    curr.dump(std::cout);
+-	    std::cout << std::endl;
+-	  }
+-
+-	done = true;
+-
+-	// Remember the solution whose broken dependencies we're
+-	// iterating over.
+-	solution starting_solution = curr;
+-
+-	for(typename imm::set<dep>::const_iterator bi=starting_solution.get_broken().begin();
+-	    bi!=starting_solution.get_broken().end(); ++bi)
+-
+-	  {
+-	    // Check for the case where this dependency has been
+-	    // fortuitously solved by forcing another broken
+-	    // dependency.
+-	    if(starting_solution != curr && !(*bi).broken_under(curr))
+-	      continue;
+-
+-	    // Assert against impossible conditions (if this happens
+-	    // something is broken elsewhere).
+-	    if(starting_solution == curr && !(*bi).broken_under(curr))
+-	      {
+-		std::ostringstream msg;
+-
+-		msg << "Unexpectedly non-broken dependency "
+-		    << *bi << "!" << std::endl;
+-
+-		version source = (*bi).get_source();
+-
+-		if(curr.version_of(source.get_package()) != source)
+-		  msg << "  (" << source.get_package().get_name()
+-		      << " " << source.get_name()
+-		      << " is not installed)" << std::endl;
+-
+-		for(typename dep::solver_iterator si = (*bi).solvers_begin();
+-		    !si.end(); ++si)
+-		  if(curr.version_of((*si).get_package()) == *si)
+-		    msg << "  (" << (*si).get_package().get_name()
+-			<< " " << (*si).get_name()
+-			<< " is installed)" << std::endl;
+-
+-		throw ResolverInternalErrorException(msg.str());
+-	      }
+-
+-	    imm::map<package, action> conflict;
+-
+-
+-	    int num_successors = 0;
+-	    generate_successors(curr, *bi, conflict,
+-				null_generator(num_successors));
+-
+-
+-
+-	    if(num_successors == 0)
+-	      {
+-		if(debug)
+-		  {
+-		    std::cout << "Discarding solution; unresolvable dependency "
+-			      << *bi << " with conflict ";
+-
+-		    dump_conflict(std::cout, conflict);
+-
+-		    std::cout << std::endl;
+-		  }
+-
+-		add_conflict(conflict);
+-
+-		dead_end = true;
+-	      }
+-	    else if(num_successors == 1)
+-	      {
+-		if(debug)
+-		  std::cout << "Forced resolution of " << *bi << std::endl;
+-
+-		std::vector<solution> v;
+-		real_generator g(v);
+-		// NB: this may do redundant work adding to 'conflict'.
+-		// Use a generator object to avoid that?
+-		generate_successors(curr, *bi, conflict,
+-				    real_generator(v));
+-
+-		eassert(v.size() == 1);
+-
+-		curr = v.back();
+-		done = false;
+-	      }
+-	  }
+-      }
+-
+-    // Discard this node if there is no solution to at least one
+-    // dependency.
+-    if(dead_end)
+-      return;
+-
+-    // In the course of forcing dependencies, we might have actually
+-    // arrived at a solution, in which case we should just enqueue it
+-    // and stop (a full solution has no successors to generate).
+-    if(curr.is_full_solution())
+-      {
+-	try_enqueue(curr);
+-	return;
+-      }
+-
+-    unsigned int nsols = 0;
+-
+-    // First try to enqueue stuff related to a dependency that the
+-    // user constrained; then just go for a free-for-all.
+-    for(typename imm::set<dep>::const_iterator bi=curr.get_broken().begin();
+-	bi!=curr.get_broken().end() && (nsols == 0 ||
+-					nsols < max_successors); ++bi)
+-
+-      if(impinges_user_constraint(*bi))
+-	{
+-	  // Is it possible to take this out somehow?
+-	  imm::map<package, action> conflict;
+-
+-	  if(debug)
+-	    std::cout << "Generating successors for " << *bi
+-		      << std::endl;
+-
+-	  std::vector<solution> v;
+-	  generate_successors(curr, *bi, conflict, real_generator(v));
+-	  try_enqueue(v);
+-	  nsols += v.size();
+-	}
+-
+-    for(typename imm::set<dep>::const_iterator bi=curr.get_broken().begin();
+-	bi!=curr.get_broken().end() && (nsols == 0 ||
+-					nsols < max_successors); ++bi)
+-      {
+-	// Is it possible to take this out somehow?
+-	imm::map<package, action> conflict;
+-
+-	if(debug)
+-	  std::cout << "Generating successors for " << *bi
+-		    << std::endl;
+-
+-	std::vector<solution> v;
+-	generate_successors(curr, *bi, conflict, real_generator(v));
+-	try_enqueue(v);
+-	nsols += v.size();
+-      }
+-  }
+-public:
+-
+-  /** Construct a new generic_problem_resolver.
+-   *
+-   *  \param _score_score the score per "step" of a (partial) solution.  Typically negative.
+-   *  \param _broken_score the score to add per broken dependency of a (partial) solution.  Typically negative.
+-   *  \param _unfixed_soft_score the score to add per soft dependency LEFT UNFIXED.  Typically negative.
+-   *  \param infinity a score value that will be considered to be "infinite".  Solutions
+-   *  with less than -infinity points will be immediately discarded.
+-   *  \param _full_solution_score a bonus for goal nodes (things
+-   *  that solve all dependencies)
+-   *  \param _universe the universe in which we are working.
+-   */
+-  generic_problem_resolver(int _step_score, int _broken_score,
+-			   int _unfixed_soft_score,
+-			   int infinity, unsigned int _max_successors,
+-			   int _full_solution_score,
+-			   const PackageUniverse &_universe)
+-    :weights(_step_score, _broken_score, _unfixed_soft_score,
+-	     _full_solution_score, _universe.get_version_count()),
+-     minimum_score(-infinity), max_successors(_max_successors),
+-     universe(_universe), finished(false), deferred_dirty(false),
+-     debug(false), remove_stupid(true),
+-     solver_executing(false), solver_cancelled(false),
+-     conflicts(_universe.get_package_count())
+-  {
+-    // Find all the broken deps.
+-    for(typename PackageUniverse::broken_dep_iterator bi=universe.broken_begin();
+-	!bi.end(); ++bi)
+-      {
+-	dep bd(*bi);
+-
+-	eassert(bd.broken_under(solution::root_node(initial_broken,
+-						    universe,
+-						    weights)));
+-
+-	initial_broken.insert(bd);
+-      }
+-  }
+-
+-  ~generic_problem_resolver()
+-  {
+-  }
+-
+-  const PackageUniverse &get_universe()
+-  {
+-    return universe;
+-  }
+-
+-  int get_step_score() {return weights.step_score;}
+-  int get_broken_score() {return weights.broken_score;}
+-  int get_unresolved_soft_dep_score() {return weights.unfixed_soft_score;}
+-  int get_infinity() {return -minimum_score;}
+-  int get_max_successors() {return max_successors;}
+-  int get_full_solution_score() {return weights.full_solution_score;}
+-
+-  /** Enables or disables debugging.  Debugging is initially
+-   *  disabled.
+-   */
+-  void set_debug(bool new_debug)
+-  {
+-    debug=new_debug;
+-  }
+-
+-  /** Enables or disables the removal of "stupid pairs".  Initially
+-   *  enabled.
+-   */
+-  void set_remove_stupid(bool new_remove_stupid)
+-  {
+-    remove_stupid = new_remove_stupid;
+-  }
+-
+-  /** Clears all the internal state of the solver, discards solutions,
+-   *  zeroes out scores.  Call this routine after changing the state
+-   *  of packages to avoid inconsistent results.
+-   */
+-  void reset()
+-  {
+-    finished=false;
+-    open.clear();
+-    closed.clear();
+-
+-    for(size_t i=0; i<universe.get_version_count(); ++i)
+-      weights.version_scores[i]=0;
+-  }
+-
+-  /** \return \b true if no solutions have been examined yet.
+-   *  This implies that it is safe to modify package scores.
+-   */
+-  bool fresh()
+-  {
+-    if(deferred_dirty)
+-      reexamine_deferred();
+-
+-    return open.empty() && !finished;
+-  }
+-
+-  /** \return \b true if the open queue is empty. */
+-  bool exhausted()
+-  {
+-    if(deferred_dirty)
+-      reexamine_deferred();
+-
+-    return open.empty() && finished;
+-  }
+-
+-  /** Tells the resolver how highly to value a particular package
+-   *  version.  All scores are relative, and a higher score will
+-   *  result in a bias towards that version appearing in the final
+-   *  solution.
+-   */
+-  void set_version_score(const version &ver, int score)
+-  {
+-    eassert(ver.get_id()<universe.get_version_count());
+-    weights.version_scores[ver.get_id()]=score;
+-  }
+-
+-  /** As set_version_score, but instead of replacing the current score
+-   *  increment it.
+-   */
+-  void add_version_score(const version &ver, int score)
+-  {
+-    eassert(ver.get_id()<universe.get_version_count());
+-    weights.version_scores[ver.get_id()]+=score;
+-  }
+-
+-  /** \return the score of the version ver. */
+-  int get_version_score(const version &ver)
+-  {
+-    eassert(ver.get_id()<universe.get_version_count());
+-    return weights.version_scores[ver.get_id()];
+-  }
+-
+-  /** Reject future solutions containing this version.
+-   */
+-  void reject_version(const version &ver, undo_group *undo = NULL)
+-  {
+-    std::pair<typename std::set<version>::const_iterator, bool>
+-      insert_result = user_rejected.insert(ver);
+-
+-    if(insert_result.second)
+-      {
+-	if(undo != NULL)
+-	  undo->add_item(new undo_resolver_manipulation<PackageUniverse, version>(this, ver, &generic_problem_resolver<PackageUniverse>::unreject_version));
+-
+-	unmandate_version(ver, undo);
+-      }
+-  }
+-
+-  /** Cancel any rejection of ver, allowing the resolver to once
+-   *  again generate solutions containing it.
+-   */
+-  void unreject_version(const version &ver, undo_group *undo = NULL)
+-  {
+-    typename std::set<version>::size_type
+-      erased_count = user_rejected.erase(ver);
+-
+-    if(erased_count > 0)
+-      {
+-	if(undo != NULL)
+-	  undo->add_item(new undo_resolver_manipulation<PackageUniverse, version>(this, ver, &generic_problem_resolver<PackageUniverse>::reject_version));
+-
+-	deferred_dirty = true;
+-      }
+-  }
+-
+-  void mandate_version(const version &ver, undo_group *undo = NULL)
+-  {
+-    std::pair<typename std::set<version>::const_iterator, bool>
+-      insert_result = user_mandated.insert(ver);
+-
+-    if(insert_result.second)
+-      {
+-	if(undo != NULL)
+-	  undo->add_item(new undo_resolver_manipulation<PackageUniverse, version>(this, ver, &generic_problem_resolver<PackageUniverse>::unmandate_version));
+-
+-	unreject_version(ver, undo);
+-      }
+-  }
+-
+-  void unmandate_version(const version &ver, undo_group *undo = NULL)
+-  {
+-    typename std::set<version>::size_type
+-      erased_count = user_mandated.erase(ver);
+-
+-    if(erased_count > 0)
+-      {
+-	if(undo != NULL)
+-	  undo->add_item(new undo_resolver_manipulation<PackageUniverse, version>(this, ver, &generic_problem_resolver<PackageUniverse>::mandate_version));
+-
+-	deferred_dirty = true;
+-      }
+-  }
+-
+-  /** Query whether the given version is rejected. */
+-  bool is_rejected(const version &ver) const
+-  {
+-    return user_rejected.find(ver) != user_rejected.end();
+-  }
+-
+-  /** Query whether the given version is mandated. */
+-  bool is_mandatory(const version &ver) const
+-  {
+-    return user_mandated.find(ver) != user_mandated.end();
+-  }
+-
+-  /** Query whether the given dependency is hardened. */
+-  bool is_hardened(const dep &d) const
+-  {
+-    return user_hardened.find(d) != user_hardened.end();
+-  }
+-
+-  /** Harden the given dependency. */
+-  void harden(const dep &d, undo_group *undo = NULL)
+-  {
+-    eassert(d.is_soft());
+-
+-    std::pair<typename std::set<dep>::const_iterator, bool>
+-      insert_result = user_hardened.insert(d);
+-
+-    if(insert_result.second)
+-      {
+-	if(undo != NULL)
+-	  undo->add_item(new undo_resolver_manipulation<PackageUniverse, dep>(this, d, &generic_problem_resolver<PackageUniverse>::unharden));
+-
+-	unapprove_break(d, undo);
+-      }
+-  }
+-
+-  /** Un-harden (soften?) the given dependency. */
+-  void unharden(const dep &d, undo_group *undo = NULL)
+-  {
+-    typename std::set<dep>::size_type
+-      erased_count = user_hardened.erase(d);
+-
+-    if(erased_count > 0)
+-      {
+-	if(undo != NULL)
+-	  undo->add_item(new undo_resolver_manipulation<PackageUniverse, dep>(this, d, &generic_problem_resolver<PackageUniverse>::harden));
+-
+-	deferred_dirty = true;
+-      }
+-  }
+-
+-  /** \return \b true if the given dependency is in the
+-   *  approved-broken state.
+-   */
+-  bool is_approved_broken(const dep &d) const
+-  {
+-    return user_approved_broken.find(d) != user_approved_broken.end();
+-  }
+-
+-  /** Approve the breaking of the given dependency. */
+-  void approve_break(const dep &d, undo_group *undo = NULL)
+-  {
+-    std::pair<typename std::set<dep>::const_iterator, bool>
+-      insert_result = user_approved_broken.insert(d);
+-
+-    if(insert_result.second)
+-      {
+-	if(undo != NULL)
+-	  undo->add_item(new undo_resolver_manipulation<PackageUniverse, dep>(this, d, &generic_problem_resolver<PackageUniverse>::unapprove_break));
+-
+-	unharden(d, undo);
+-      }
+-  }
+-
+-  /** Cancel the required breaking of the given dependency. */
+-  void unapprove_break(const dep &d, undo_group *undo = NULL)
+-  {
+-    typename std::set<dep>::size_type erased_count
+-      = user_approved_broken.erase(d);
+-
+-    if(erased_count > 0)
+-      {
+-	if(undo != NULL)
+-	  undo->add_item(new undo_resolver_manipulation<PackageUniverse, dep>(this, d, &generic_problem_resolver<PackageUniverse>::approve_break));
+-
+-	deferred_dirty = true;
+-      }
+-  }
+-
+-  /** Add a set of actions on packages to the set of 'conflicts'.  No
+-   *  solution containing these actions will be generated or
+-   *  contemplated.  This routine is public primarily to allow the
+-   *  frontend to discard the 'do-nothing' solution (eg, the aptitude
+-   *  resolver will ignore solutions that cancel all pending user
+-   *  actions).
+-   */
+-  void add_conflict(const imm::map<package, action> &conflict)
+-  {
+-    typename conflictset::const_iterator
+-      found = find_matching_conflict(conflict);
+-
+-    if(found != conflicts.end())
+-      {
+-	if(debug)
+-	  {
+-	    std::cout << "Dropping conflict ";
+-	    dump_conflict(std::cout, conflict);
+-	    std::cout << " because it is redundant with ";
+-	    dump_conflict(std::cout, *found);
+-	    std::cout << std::endl;
+-	  }
+-      }
+-    else
+-      {
+-	if(debug)
+-	  {
+-	    std::cout << "Inserting conflict ";
+-	    dump_conflict(std::cout, conflict);
+-	    std::cout << std::endl;
+-	  }
+-	// TODO: drop conflicts of which this is a subset.  Needs work
+-	// at the setset level.
+-	conflicts.insert(conflict);
+-      }
+-  }
+-
+-  /** Remove all dependency-related information from a set of actions;
+-   *  used to insert conflicts that shouldn't have dependency tags.
+-   */
+-  static imm::map<package, action>
+-  strip_dep_info(const imm::map<package, action> &actmap)
+-  {
+-    imm::map<package, action> rval;
+-
+-    for(typename imm::map<package, action>::const_iterator i = actmap.begin();
+-	i != actmap.end(); ++i)
+-      rval.put(i->first, action(i->second.ver,
+-				dep(), false,
+-				i->second.id));
+-
+-    return rval;
+-  }
+-
+-  /** Cancel any find_next_solution call that is executing in the
+-   *  background.  If no such call is executing, then the next call
+-   *  will immediately be cancelled.
+-   */
+-  void cancel_solver()
+-  {
+-    threads::mutex::lock l(execution_mutex);
+-    solver_cancelled = true;
+-  }
+-
+-  /** Remove any pending find_next_solution cancellation. */
+-  void uncancel_solver()
+-  {
+-    threads::mutex::lock l(execution_mutex);
+-    solver_cancelled = false;
+-  }
+-
+-  /** Atomically read the current queue sizes of this resolver. */
+-  queue_counts get_counts()
+-  {
+-    maybe_update_deferred_and_counts();
+-
+-    threads::mutex::lock l(counts_mutex);
+-    return counts;
+-  }
+-
+-  /** Update the cached queue sizes. */
+-  void update_counts_cache()
+-  {
+-    threads::mutex::lock l(counts_mutex);
+-    counts.open      = open.size();
+-    counts.closed    = closed.size();
+-    counts.deferred  = deferred.size();
+-    counts.conflicts = conflicts.size();
+-    counts.finished  = finished;
+-  }
+-
+-  /** If no resolver is running, run through the deferred list and
+-   *  update the counts cache.  In particular, this allows the
+-   *  'are-we-out-of-solutions' state to be updated immediately when
+-   *  something like reject_version is called.
+-   */
+-  void maybe_update_deferred_and_counts()
+-  {
+-    threads::mutex::lock l(execution_mutex);
+-    if(!solver_executing)
+-      {
+-	if(deferred_dirty)
+-	  reexamine_deferred();
+-	update_counts_cache();
+-      }
+-  }
+-
+-  /** Try to find the "next" solution: remove partial solutions from
+-   *  the open queue and place them in the closed queue until one of
+-   *  the following occurs:
+-   *
+-   *   - The number of broken dependencies drops to 0, in which case
+-   *     there is much rejoicing and we return successfully.
+-   *
+-   *   - The upper limit on the number of steps to perform is exceeded,
+-   *     in which case we just give up and report failure.  (this is a
+-   *     guard against exponential blowup)
+-   *
+-   *   - We run out of potential solutions to try; failure.
+-   *
+-   *  \param max_steps the maximum number of solutions to test.
+-   *
+-   *  \return a solution that fixes all broken dependencies
+-   *
+-   * \throws NoMoreSolutions if the potential solution list is exhausted.
+-   * \throws NoMoreTime if no solution is found within max_steps steps.
+-   *
+-   *  \todo when throwing NoMoreSolutions or NoMoreTime, maybe we
+-   *        should include the "least broken" solution seen.
+-   */
+-  solution find_next_solution(int max_steps)
+-  {
+-    // This object is responsible for managing the instance variables
+-    // that control threaded operation: it sets solver_executing when
+-    // it is created and clears both solver_executing and
+-    // solver_cancelled when it is destroyed.
+-    instance_tracker t(*this);
+- 
+-
+-    // Counter for debugging (see below)
+-    int odometer = 0;
+-
+-    if(deferred_dirty)
+-      reexamine_deferred();
+-
+-    if(finished)
+-      throw NoMoreSolutions();
+-
+-    // If the open queue is empty, then we're between searches and
+-    // should enqueue a new root node.
+-    if(open.empty())
+-      {
+-	closed.clear();
+-
+-	open.push(solution::root_node(initial_broken,
+-				      universe,
+-				      weights));
+-      }
+-
+-    while(max_steps>0 && !open.empty())
+-      {
+-	// Threaded operation: check whether we have been cancelled.
+-	{
+-	  threads::mutex::lock l(execution_mutex);
+-	  if(solver_cancelled)
+-	    throw InterruptedException();
+-	}
+-
+-	update_counts_cache();
+-
+-
+-	solution s=open.top();
+-	open.pop();
+-
+-	++odometer;
+-
+-	if(irrelevant(s))
+-	  {
+-	    if(debug)
+-	      {
+-		std::cout << "Dropping irrelevant solution ";
+-		s.dump(std::cout);
+-		std::cout << std::endl;
+-	      }
+-	    continue;
+-	  }
+-
+-	if(should_defer(s))
+-	  {
+-	    if(debug)
+-	      {
+-		std::cout << "Deferring rejected solution ";
+-		s.dump(std::cout);
+-		std::cout << std::endl;
+-	      }
+-
+-	    deferred.insert(s);
+-	    continue;
+-	  }
+-
+-	closed.insert(s);
+-
+-	// If all dependencies are satisfied, we found a solution.
+-	if(s.is_full_solution())
+-	  {
+-	    if(debug)
+-	      {
+-		std::cout << " --- Found solution ";
+-		s.dump(std::cout);
+-		std::cout << std::endl;
+-	      }
+-
+-	    // Set it here too in case the last tentative solution is
+-	    // really a solution.
+-	    if(open.empty())
+-	      finished=true;
+-
+-	    solution minimized = remove_stupid ? eliminate_stupid(s) : s;
+-
+-	    // We only want to re-enqueue the solution if it changed
+-	    // in version content, meaning that it changed in *size*
+-	    // (recall that the new version content is always a subset
+-	    // of the old).  If we do this whenever the solution
+-	    // *changed*, we sometimes end up re-inserting something
+-	    // with the same version content and hence something
+-	    // that's already on the closed queue.
+-	    if(minimized.get_actions().size() != s.get_actions().size())
+-	      {
+-		// Make it fend for itself! (although I expect it to
+-		// come up again immediately; hrm)
+-		if(debug)
+-		  std::cout << " --- Placing de-stupidified solution back on the open queue" << std::endl;
+-		finished = false;
+-		open.push(minimized);
+-	      }
+-	    else
+-	      {
+-		closed.insert(minimized);
+-		// In the cases where the solution can be completely
+-		// represented by a conflict, add one (so we get the
+-		// benefits of conflict tracking).
+-		//
+-		// \todo extend conflicts so they can represent
+-		// everything or extend everything so a conflict can
+-		// represent it.
+-		if(minimized.get_unresolved_soft_deps().empty())
+-		  add_conflict(strip_dep_info(minimized.get_actions()));
+-		else
+-		  generated_solutions.push_back(minimized);
+-
+-		if(debug)
+-		  {
+-		    std::cout << " *** Converged after " << odometer << " steps." << std::endl;
+-		    std::cout << " *** open: " << open.size()
+-			      << "; closed: " << closed.size()
+-			      << "; conflicts: " << conflicts.size()
+-			      << "; deferred: " << deferred.size()
+-			      << "; generated solutions: " << generated_solutions.size()
+-			      << std::endl;
+-		  }
+-
+-		update_counts_cache();
+-
+-		return minimized;
+-	      }
+-	  }
+-	// Nope, let's go enqueue successor nodes.
+-	else
+-	  process_solution(s);
+-
+-	if(debug)
+-	  std::cout << "Done generating successors." << std::endl;
+-
+-	--max_steps;
+-      }
+-
+-    // Oh no, we either ran out of solutions or ran out of steps.
+-
+-    if(max_steps==0)
+-      throw NoMoreTime();
+-
+-    eassert(open.empty());
+-
+-    finished=true;
+-
+-    update_counts_cache();
+-
+-    if(debug)
+-      {
+-	std::cout << " *** Out of solutions after " << odometer << " steps." << std::endl;
+-	std::cout << " *** open: " << open.size()
+-		  << "; closed: " << closed.size()
+-		  << "; conflicts: " << conflicts.size()
+-		  << "; deferred: " << deferred.size()
+-		  << "; generated solutions: " << generated_solutions.size()
+-		  << std::endl;
+-      }
+-
+-    throw NoMoreSolutions();
+-  }
+-
+-  void dump_scores(std::ostream &out)
+-  {
+-    out << "{" << std::endl;
+-    for(typename PackageUniverse::package_iterator i=universe.packages_begin();
+-	!i.end(); ++i)
+-      {
+-	bool any_modified=false;
+-
+-	for(typename PackageUniverse::package::version_iterator j=(*i).versions_begin();
+-	    !j.end(); ++j)
+-	  if(weights.version_scores[(*j).get_id()]!=0)
+-	    any_modified=true;
+-
+-	if(any_modified)
+-	  {
+-	    out << "  SCORE " << (*i).get_name() << " <";
+-
+-	    for(typename PackageUniverse::package::version_iterator j=(*i).versions_begin();
+-		!j.end(); ++j)
+-	      if(weights.version_scores[(*j).get_id()]!=0)
+-		out << " " << (*j).get_name() << " " << weights.version_scores[(*j).get_id()];
+-
+-	    out << " >" << std::endl;
+-	  }
+-      }
+-    out << "}" << std::endl;
+-  }
+-};
+-
+-template<class PackageUniverse>
+-std::ostream &generic_problem_resolver<PackageUniverse>::dump_conflict(std::ostream &out, const typename generic_problem_resolver<PackageUniverse>::action &act) const
+-{
+-  out << act.ver.get_package().get_name() << " "
+-      << act.ver.get_name();
+-
+-  if(act.from_dep_source)
+-    out << " [" << act.d << "]";
+-
+-  return out;
+-}
+-
+-template<class PackageUniverse>
+-std::ostream &generic_problem_resolver<PackageUniverse>::dump_conflict(std::ostream &out, const typename imm::map<typename PackageUniverse::package, typename generic_solution<PackageUniverse>::action> &act) const
+-{
+-  out << "(";
+-
+-  for(typename imm::map<typename PackageUniverse::package, typename generic_solution<PackageUniverse>::action>::const_iterator ci
+-	= act.begin(); ci != act.end(); ++ci)
+-    {
+-      if(ci != act.begin())
+-	out << ", ";
+-
+-      dump_conflict(out, ci->second);
+-    }
+-
+-  out << ")";
+-
+-  return out;
+-}
+-
+-#endif
+diff --git a/src/generic/problemresolver/resolver_undo.h b/src/generic/problemresolver/resolver_undo.h
+deleted file mode 100644
+index 7e93ec5..0000000
+--- a/src/generic/problemresolver/resolver_undo.h
++++ /dev/null
+@@ -1,56 +0,0 @@
+-// resolver_undo.h                            -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-//
+-// Undo items related to the resolver.  (Q: these could be unified
+-// into a single item based on slots or somesuch?)
+-
+-#ifndef RESOLVER_UNDO_H
+-#define RESOLVER_UNDO_H
+-
+-#include <generic/util/undo.h>
+-
+-template<typename PackageUniverse>
+-class generic_problem_resolver;
+-
+-/** An undoable that executes the given action on the given object. */
+-template<typename PackageUniverse, typename T>
+-class undo_resolver_manipulation : public undoable
+-{
+-public:
+-  typedef void (generic_problem_resolver<PackageUniverse>::*undo_method)(const T &, undo_group *);
+-
+-  generic_problem_resolver<PackageUniverse> *resolver;
+-  T t;
+-  undo_method reverse_action;
+-
+-public:
+-  undo_resolver_manipulation(generic_problem_resolver<PackageUniverse> *_resolver,
+-			     const T &_t,
+-			     undo_method _reverse_action)
+-    : resolver(_resolver), t(_t), reverse_action(_reverse_action)
+-  {
+-  }
+-
+-  void undo()
+-  {
+-    (resolver->*reverse_action)(t, NULL);
+-  }
+-};
+-
+-#endif // RESOLVER_UNDO_H
+diff --git a/src/generic/problemresolver/solution.h b/src/generic/problemresolver/solution.h
+deleted file mode 100644
+index 207d6d7..0000000
+--- a/src/generic/problemresolver/solution.h
++++ /dev/null
+@@ -1,746 +0,0 @@
+-// solution.h                                             -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-//
+-// The solution class for the problem resolver.
+-
+-#ifndef SOLUTION_H
+-#define SOLUTION_H
+-
+-#include <iostream>
+-#include <generic/util/immset.h>
+-
+-/** Represents the current score weights for a resolver.  Used to
+- *  calculate scores at the time a solution is instantiated.
+- */
+-struct solution_weights
+-{
+-  /** How much to reward long and/or broken solutions.  Typically
+-   *  negative to penalize such things, or 0 to ignore them.
+-   */
+-  int step_score, broken_score, unfixed_soft_score;
+-
+-
+-  /** How much to reward real solutions -- solutions that fix all
+-   *  dependencies.  Make this big to immediately pick them up, or
+-   *  small to ignore "bad" solutions (at the risk of running out of
+-   *  time if no better solution pops up).
+-   */
+-  int full_solution_score;
+-
+-  /** The scores to apply to individual package versions.
+-   */
+-  int *version_scores;
+-
+-  solution_weights(int _step_score, int _broken_score,
+-		   int _unfixed_soft_score, int _full_solution_score,
+-		   unsigned long num_versions)
+-    :step_score(_step_score), broken_score(_broken_score),
+-     unfixed_soft_score(_unfixed_soft_score),
+-     full_solution_score(_full_solution_score),
+-     version_scores(new int[num_versions])
+-  {
+-    for(unsigned long i = 0; i < num_versions; ++i)
+-      version_scores[i] = 0;
+-  }
+-
+-  ~solution_weights()
+-  {
+-    delete[] version_scores;
+-  }
+-};
+-
+-/** Represents a partial or complete solution to a dependency
+- *  problem.  Solutions are transparently refcounted to save on
+- *  memory and avoid copies.
+- *
+- *  Solution identity is based on both the mapping stored in the
+- *  solution and on the set of unfixed soft dependencies stored in it.
+- *  Dependencies in unfixed_soft_deps are removed from broken_deps so
+- *  it's easy to check whether a solution is complete.
+- */
+-template<class PackageUniverse>
+-class generic_solution
+-{
+-public:
+-  // Let the resolver tester poke around in our internals.
+-  friend class ResolverTest;
+-
+-  typedef typename PackageUniverse::package package;
+-  typedef typename PackageUniverse::version version;
+-  typedef typename PackageUniverse::dep dep;
+-
+-  /** Represents a single action taken by the resolver: the
+-   *  installation of a particular version of a package.  The
+-   *  *identity* of an action (in terms of operator< and operator==)
+-   *  is based solely on the version it installs, although additional
+-   *  information is provided to "tag" it.
+-   */
+-  struct action
+-  {
+-    version ver;
+-
+-    /** The dependency that triggered this action. */
+-    dep d;
+-
+-    /** If \b true, this action was triggered by removing the source
+-     *	of the dependency d.
+-     */
+-    bool from_dep_source:1;
+-
+-    /** The order in which this action should be placed.  Used when
+-     *  presenting a "story" about a solution.
+-     */
+-    int id:31;
+-
+-    action() {}
+-
+-    action(const version &_ver,
+-	   const dep &_d,
+-	   bool _from_dep_source,
+-	   int _id)
+-      : ver(_ver), d(_d),
+-	from_dep_source(_from_dep_source), id(_id)
+-    {
+-    }
+-
+-    bool operator<(const action &other) const {return ver<other.ver;}
+-
+-    bool operator==(const action &other) const
+-    {
+-      return ver == other.ver;
+-    }
+-
+-    bool operator!=(const action &other) const
+-    {
+-      return ver != other.ver;
+-    }
+-  };
+-
+-private:
+-  /** Hide this, it's meaningless. */
+-  bool operator<(const generic_solution &other) const;
+-
+-  class solution_rep
+-  {
+-    /** The actions performed by this solution.
+-     *
+-     *  Originally the plan was to read this off by tracing to the
+-     *  root -- but it seems likely that this will be read many more
+-     *  times than it's created, so I'm swallowing the space/time
+-     *  hit to build a lookup table at each node in the hope that it
+-     *  pays off later..
+-     *
+-     *  Note that this also means you can't find out chronological
+-     *  ordering, which might help make sense of everything; that
+-     *  can be added in later one way or another, though.  (eg,
+-     *  storing the DAG structure after all?)
+-     */
+-    imm::map<package, action> actions;
+-
+-    /** The full list of currently broken dependencies. */
+-    imm::set<dep> broken_deps;
+-
+-    /** The set of soft dependencies being left unresolved. */
+-    imm::set<dep> unresolved_soft_deps;
+-
+-    /** A set of versions that have been "locked out" by this
+-     *	solution.  Primarily used to optimize the common case of
+-     *	having to "climb a hill" as removals propagate up the
+-     *	dependency chain.  (this allows us to easily force the search
+-     *	in the direction it has to go)
+-     */
+-    imm::map<version, dep> forbidden_versions;
+-
+-    /** The score of this solution. */
+-    int score;
+-
+-    /** The combined score due to package version installations
+-     *  and distance from the root -- "score" is calculated by
+-     *  adding the broken-dependency count to this.
+-     */
+-    int action_score;
+-
+-    /** The reference count of this solution. */
+-    mutable unsigned int refcount;
+-
+-  public:
+-    void incref() const {++refcount;}
+-    void decref() const {eassert(refcount>0); if(--refcount==0) delete this;}
+-
+-    /** Construct a new solution_rep directly. */
+-    solution_rep(const imm::map<package, action> &_actions,
+-		 const imm::set<dep> &_broken_deps,
+-		 const imm::set<dep> &_unresolved_soft_deps,
+-		 const imm::map<version, dep> &_forbidden_versions,
+-		 int _score,
+-		 int _action_score)
+-      : actions(_actions),
+-	broken_deps(_broken_deps),
+-	unresolved_soft_deps(_unresolved_soft_deps),
+-	forbidden_versions(_forbidden_versions),
+-	score(_score),
+-	action_score(_action_score),
+-	refcount(1)
+-    {
+-    }
+-
+-    const imm::set<dep> &get_broken_deps() const
+-    {
+-      return broken_deps;
+-    }
+-
+-    const imm::set<dep> &get_unresolved_soft_deps() const
+-    {
+-      return unresolved_soft_deps;
+-    }
+-
+-    const imm::map<package, action> &get_actions() const
+-    {
+-      return actions;
+-    }
+-
+-    const imm::map<version, dep> &get_forbidden_versions() const
+-    {
+-      return forbidden_versions;
+-    }
+-
+-    int get_score() const {return score;}
+-    int get_action_score() const {return action_score;}
+-
+-    version version_of(const package &pkg) const
+-    {
+-      typename imm::map<package, action>::node found
+-	= actions.lookup(pkg);
+-      if(!found.isValid())
+-	return pkg.current_version();
+-      else
+-	return found.getVal().second.ver;
+-    }
+-
+-    /** \return true iff this solution touches the given package. */
+-    bool package_modified(const package &pkg) const
+-    {
+-      return actions.find(pkg) != actions.end();
+-    }
+-  }; // End solution representation.
+-
+-  solution_rep *real_soln;
+-
+-  /** Create a solution directly from a rep; assumes control of the
+-   *  reference passed in as an argument (i.e., doesn't incref() it)
+-   */
+-  generic_solution(solution_rep *r)
+-    :real_soln(r)
+-  {
+-  }
+-
+-  /** Wrapper structure used to pass a raw map into broken_under().
+-   *  Used to determine the set of packages broken by a solution
+-   *  before the solution is actually created.
+-   */
+-  struct solution_map_wrapper
+-  {
+-    const imm::map<package, action> &actions;
+-  public:
+-    solution_map_wrapper(const imm::map<package, action> &_actions)
+-      :actions(_actions)
+-    {
+-    }
+-
+-    version version_of(const package &p) const
+-    {
+-      typename imm::map<package, action>::node found
+-	= actions.lookup(p);
+-
+-      if(found.isValid())
+-	return found.getVal().second.ver;
+-      else
+-	return p.current_version();
+-    }
+-  };
+-
+-public:
+-  generic_solution():real_soln(0) {}
+-
+-  generic_solution(const generic_solution &other)
+-    :real_soln(other.real_soln)
+-  {
+-    if(real_soln)
+-      real_soln->incref();
+-  }
+-
+-  /** Generate a new, identical solution that shares no memory with
+-   *  this solution and hence is safe to hand to another thread.  Note
+-   *  that as with other refcounted structures, the handover should be
+-   *  done "at one remove" by allocating a generic_solution object on
+-   *  the heap.
+-   */
+-  generic_solution clone() const
+-  {
+-    return generic_solution(new solution_rep(get_actions().clone(),
+-					     get_broken().clone(),
+-					     get_unresolved_soft_deps().clone(),
+-					     get_forbidden_versions().clone(),
+-					     get_score(),
+-					     get_action_score()));
+-  }
+-
+-
+-  /** Generate the root node for a search in the given universe. */
+-  static generic_solution root_node(const imm::set<dep> &initial_broken,
+-				    const PackageUniverse &universe,
+-				    const solution_weights &weights)
+-  {
+-    int score = initial_broken.size() * weights.broken_score;
+-
+-    if(initial_broken.empty())
+-      score += weights.full_solution_score;
+-
+-    return generic_solution(new solution_rep(imm::map<package, action>(),
+-					     initial_broken,
+-					     imm::set<dep>(),
+-					     imm::map<version, dep>(),
+-					     score,
+-					     0));
+-  }
+-
+-  /** Generate a successor to the given solution.
+-   *
+-   *  \param [abegin, aend) a range of actions to perform
+-   *  \param [ubegin, uend) a range of dependencies to leave unresolved
+-   */
+-  template<typename a_iter, typename u_iter>
+-  static generic_solution successor(const generic_solution &s,
+-				    const a_iter &abegin,
+-				    const a_iter &aend,
+-				    const u_iter &ubegin,
+-				    const u_iter &uend,
+-				    const PackageUniverse &universe,
+-				    const solution_weights &weights)
+-  {
+-    // NB: as I fully expect to move to a scheme of shared-memory
+-    // sets/maps, the implicit copies here will go away eventually.
+-    imm::set<dep> broken_deps = s.get_broken();
+-    imm::map<package, action> actions = s.get_actions();
+-    imm::map<version, dep> forbidden_versions = s.get_forbidden_versions();
+-    imm::set<dep> unresolved_soft_deps = s.get_unresolved_soft_deps();
+-    int action_score = s.get_action_score();
+-
+-    // Add notes about unresolved dependencies
+-    for(u_iter ui = ubegin; ui != uend; ++ui)
+-      {
+-	const dep &d = *ui;
+-
+-	eassert(broken_deps.contains(d));
+-	broken_deps.erase(d);
+-	unresolved_soft_deps.insert(d);
+-      }
+-
+-    for(a_iter ai = abegin; ai != aend; ++ai)
+-      {
+-	const action &a = *ai;
+-	eassert(!actions.domain_contains(a.ver.get_package()));
+-	eassert(a.ver != a.ver.get_package().current_version());
+-
+-	actions.put(a.ver.get_package(), a);
+-
+-	action_score += weights.step_score;
+-	action_score += weights.version_scores[a.ver.get_id()];
+-	action_score -= weights.version_scores[a.ver.get_package().current_version().get_id()];
+-
+-	if(a.from_dep_source)
+-	  {
+-	    for(typename dep::solver_iterator si = a.d.solvers_begin();
+-		!si.end(); ++si)
+-	      forbidden_versions.put(*si, a.d);
+-	  }
+-
+-
+-
+-	// Update the set of broken dependencies, trying to re-use as
+-	// much of the former set as possible.
+-	version old_version=s.version_of(a.ver.get_package());
+-	solution_map_wrapper tmpsol(actions);
+-
+-	// Check reverse deps of the old version
+-	for(typename version::revdep_iterator rdi=old_version.revdeps_begin();
+-	    !rdi.end(); ++rdi)
+-	  {
+-	    dep rd = *rdi;
+-
+-	    if((rd).broken_under(tmpsol))
+-	      {
+-		if(!unresolved_soft_deps.contains(rd))
+-		  broken_deps.insert(rd);
+-	      }
+-	    else
+-	      {
+-		broken_deps.erase(rd);
+-		unresolved_soft_deps.erase(rd);
+-	      }
+-	  }
+-
+-	// Check reverse deps of the new version
+-	//
+-	// Because reverse deps of a version might be fixed by its
+-	// removal, we need to check brokenness and insert or erase as
+-	// appropriate.
+-	for(typename version::revdep_iterator rdi = a.ver.revdeps_begin();
+-	    !rdi.end(); ++rdi)
+-	  {
+-	    dep rd = *rdi;
+-
+-	    if((rd).broken_under(tmpsol))
+-	      {
+-		if(!unresolved_soft_deps.contains(rd))
+-		  broken_deps.insert(rd);
+-	      }
+-	    else
+-	      {
+-		broken_deps.erase(rd);
+-		unresolved_soft_deps.erase(rd);
+-	      }
+-	  }
+-
+-	// Remove all forward deps of the old version (they're
+-	// automagically fixed)
+-	for(typename version::dep_iterator di=old_version.deps_begin();
+-	    !di.end(); ++di)
+-	  {
+-	    dep d = *di;
+-
+-	    broken_deps.erase(d);
+-	    unresolved_soft_deps.erase(d);
+-	  }
+-
+-	// Check forward deps of the new version (no need to erase
+-	// non-broken dependencies since they're automatically
+-	// non-broken at the start)
+-	for(typename version::dep_iterator di=a.ver.deps_begin();
+-	    !di.end(); ++di)
+-	  {
+-	    dep d = *di;
+-
+-	    if(!unresolved_soft_deps.contains(d) &&
+-	       (d).broken_under(tmpsol))
+-	      broken_deps.insert(d);
+-	  }
+-      }
+-
+-
+-    int score
+-      = action_score + broken_deps.size()*weights.broken_score
+-      + unresolved_soft_deps.size()*weights.unfixed_soft_score;
+-
+-    if(broken_deps.empty())
+-      score += weights.full_solution_score;
+-
+-    return generic_solution(new solution_rep(actions,
+-					     broken_deps,
+-					     unresolved_soft_deps,
+-					     forbidden_versions,
+-					     score,
+-					     action_score));
+-  }
+-
+-  ~generic_solution()
+-  {
+-    if(real_soln)
+-      real_soln->decref();
+-  }
+-
+-  /** Make this an invalid reference. */
+-  void nullify()
+-  {
+-    if(real_soln)
+-      real_soln->decref();
+-    real_soln=0;
+-  }
+-
+-  generic_solution &operator=(const generic_solution &other)
+-  {
+-    if(other.real_soln)
+-      other.real_soln->incref();
+-    if(real_soln)
+-      real_soln->decref();
+-    real_soln=other.real_soln;
+-
+-    return *this;
+-  }
+-
+-  /** \note solutions are compared by pointer identity, not by
+-   *  value.
+-   *
+-   *  \return \b true if the solutions are the same solution.
+-   */
+-  bool operator==(const generic_solution &other) const
+-  {
+-    return real_soln == other.real_soln;
+-  }
+-
+-  /** Without this method, some random function that produces
+-   *  incorrect results is used.
+-   *
+-   *  \return \b true if the solutions are not the same solution.
+-   */
+-  bool operator!=(const generic_solution &other) const
+-  {
+-    return real_soln != other.real_soln;
+-  }
+-
+-  operator bool() const
+-  {
+-    return real_soln != 0;
+-  }
+-
+-  const action &operator*() const
+-  {
+-    return real_soln->get_action();
+-  }
+-
+-  const action *operator->() const
+-  {
+-    return &real_soln->get_action();
+-  }
+-
+-  const generic_solution &get_parent() const
+-  {
+-    return real_soln->get_parent();
+-  }
+-
+-  /** \return an immutable list of all the broken dependencies
+-   *  in this solution.  The list will live at least as long as
+-   *  the reference from which it was retrieved.
+-   */
+-  const imm::set<dep> &get_broken() const
+-  {
+-    return real_soln->get_broken_deps();
+-  }
+-
+-  const imm::set<dep> &get_unresolved_soft_deps() const
+-  {
+-    return real_soln->get_unresolved_soft_deps();
+-  }
+-
+-  const imm::map<package, action> &get_actions() const
+-  {
+-    return real_soln->get_actions();
+-  }
+-
+-  const imm::map<version, dep> &get_forbidden_versions() const
+-  {
+-    return real_soln->get_forbidden_versions();
+-  }
+-
+-  bool is_full_solution() const
+-  {
+-    return get_broken().empty();
+-  }
+-
+-  /** \return the score of the scolution */
+-  int get_score() const
+-  {
+-    return real_soln->get_score();
+-  }
+-
+-  /** \return the score of the solution's actions. */
+-  int get_action_score() const
+-  {
+-    return real_soln->get_action_score();
+-  }
+-
+-  version version_of(const package &pkg) const
+-  {
+-    return real_soln->version_of(pkg);
+-  }
+-
+-  bool package_modified(const package &pkg) const
+-  {
+-    return real_soln->package_modified(pkg);
+-  }
+-
+-  // The following operators are used to place the solution components
+-  // in order by name, to better permit comparison of debugging output
+-  // between versions.
+-  struct package_action_pair_name_lt
+-  {
+-  public:
+-    bool operator()(const std::pair<package, action> &p1,
+-		    const std::pair<package, action> &p2) const
+-    {
+-      return std::string(p1.first.get_name()) < p2.first.get_name();
+-    }
+-  };
+-
+-  struct ver_name_lt
+-  {
+-  public:
+-    int cmp(const version &v1, const version &v2) const
+-    {
+-      // EW: I don't have a formal standard on what get_name()
+-      // returns, so force it to be a string here:
+-      int pcmp = std::string(v1.get_package().get_name()).compare(v2.get_package().get_name());
+-
+-      if(pcmp != 0)
+-	return pcmp;
+-      else
+-	return std::string(v1.get_name()).compare(v2.get_name());
+-    }
+-
+-    bool operator()(const version &v1, const version &v2) const
+-    {
+-      return cmp(v1, v2) < 0;
+-    }
+-  };
+-
+-  struct dep_name_lt
+-  {
+-  public:
+-    bool operator()(const dep &d1, const dep &d2) const
+-    {
+-      ver_name_lt vlt;
+-
+-      int scmp = vlt.cmp(d1.get_source(), d2.get_source());
+-
+-      if(scmp != 0)
+-	return scmp < 0;
+-      else
+-	{
+-	  typename dep::solver_iterator si1 = d1.solvers_begin();
+-	  typename dep::solver_iterator si2 = d2.solvers_begin();
+-
+-	  while(!si1.end() && !si2.end())
+-	    {
+-	      scmp = vlt.cmp(*si1, *si2);
+-
+-	      if(scmp != 0)
+-		return scmp < 0;
+-
+-	      ++si1;
+-	      ++si2;
+-	    }
+-
+-	  if(si1.end())
+-	    {
+-	      if(si2.end())
+-		return false;
+-	      else
+-		return true;
+-	    }
+-	  else
+-	    return false;
+-	}
+-    }
+-  };
+-
+-  void dump(std::ostream &out) const
+-  {
+-    std::vector<std::pair<package, action> > actions;
+-    for(typename imm::map<package, action>::const_iterator i = get_actions().begin();
+-	i != get_actions().end(); ++i)
+-      actions.push_back(*i);
+-    sort(actions.begin(), actions.end(), package_action_pair_name_lt());
+-
+-
+-    out << "<";
+-    for(typename std::vector<std::pair<package, action> >::const_iterator i = actions.begin();
+-	i != actions.end(); ++i)
+-      {
+-	if(i != actions.begin())
+-	  out << ", ";
+-	out << i->first.get_name() << ":=" << i->second.ver.get_name();
+-      }
+-    out << ">;";
+-
+-
+-    std::vector<dep> unresolved_deps;
+-    for(typename imm::set<dep>::const_iterator i = get_unresolved_soft_deps().begin();
+-	i != get_unresolved_soft_deps().end(); ++i)
+-      unresolved_deps.push_back(*i);
+-    sort(unresolved_deps.begin(), unresolved_deps.end(), dep_name_lt());
+-
+-
+-    if(!get_unresolved_soft_deps().empty())
+-      {
+-	out << "<!";
+-	for(typename std::vector<dep>::const_iterator i
+-	      = unresolved_deps.begin();
+-	    i != unresolved_deps.end(); ++i)
+-	  {
+-	    if(i != unresolved_deps.begin())
+-	      out << ", ";
+-	    out << *i;
+-	  }
+-
+-	out << "!>;";
+-      }
+-
+-    std::vector<dep> broken_deps;
+-    for(typename imm::set<dep>::const_iterator i = get_broken().begin();
+-	i != get_broken().end(); ++i)
+-      broken_deps.push_back(*i);
+-    sort(broken_deps.begin(), broken_deps.end(), dep_name_lt());
+-
+-    out << "[";
+-
+-    for(typename std::vector<dep>::const_iterator i = broken_deps.begin();
+-	i != broken_deps.end(); ++i)
+-      {
+-	if(i != broken_deps.begin())
+-	  out << ", ";
+-	out << *i;
+-      }
+-
+-    out<< "];";
+-
+-    if(!get_forbidden_versions().empty())
+-      {
+-	std::vector<version> forbidden_vers;
+-	for(typename imm::map<version, dep>::const_iterator i = get_forbidden_versions().begin();
+-	    i != get_forbidden_versions().end(); ++i)
+-	  forbidden_vers.push_back(i->first);
+-	sort(forbidden_vers.begin(), forbidden_vers.end(), ver_name_lt());
+-
+-	out << "!!";
+-	for(typename std::vector<version>::const_iterator i = forbidden_vers.begin();
+-	    i != forbidden_vers.end(); ++i)
+-	  {
+-	    if(i != forbidden_vers.begin())
+-	      out << ", ";
+-	    out << i->get_package().get_name() << " " << i->get_name();
+-	  }
+-	out << "!!;";
+-      }
+-
+-    out << get_score();
+-  }
+-
+-  /** Compare actions by their ID */
+-  struct action_id_compare
+-  {
+-  public:
+-    bool operator()(const action &a1,
+-		    const action &a2) const
+-    {
+-      return a1.id < a2.id;
+-    }
+-  };
+-}; // End solution wrapper
+-
+-#endif // SOLUTION_H
+diff --git a/src/generic/problemresolver/test.cc b/src/generic/problemresolver/test.cc
+deleted file mode 100644
+index e01e1c4..0000000
+--- a/src/generic/problemresolver/test.cc
++++ /dev/null
+@@ -1,394 +0,0 @@
+-// test.cc
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.  You should have
+-//   received a copy of the GNU General Public License along with this
+-//   program; see the file COPYING.  If not, write to the Free
+-//   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+-//   MA 02111-1307, USA.
+-//
+-// Demonstrates the use of the problem-resolver and (eventually) runs
+-// tests on it.  The convoluted adaptor classes are the way they are
+-// in order to keep the APT end of things reasonably thin and
+-// efficient.
+-
+-#include "dummy_universe.h"
+-#include "problemresolver.h"
+-
+-#include <iostream>
+-#include <fstream>
+-#include <string>
+-#include <map>
+-#include <vector>
+-
+-#include <generic/util/eassert.h>
+-
+-using namespace std;
+-
+-// To make things easier, the tests are specified as plaintext files.
+-// The syntax is quite simple: it consists of whitespace-separated
+-// words, of the form:
+-//
+-// SCRIPT ::= "UNIVERSE" "[" UNIVERSE "]" TEST ...
+-// UNIVERSE ::= (PACKAGE | DEP) ...
+-// PACKAGE ::= "PACKAGE" pkgname "<" vername1 ... ">" currentver
+-// DEP ::= "DEP" pkgname1 vername1 "->" "<" pkgname2 vername2 ... ">"
+-//       | "SOFTDEP" pkgname1 vername1 "->" "<" pkgname2 vername2 ... ">"
+-//       | "DEP" pkgname1 vername1 "!!" "<" pkgname2 vername2 ... ">"
+-//
+-// TEST ::= "TEST" step_score broken_score "{" SCORE ... "}" "EXPECT" "(" SOLN ... ")"
+-// SCORE ::= "SCORE" pkgname "<" vername1 score1 ... ">"
+-// SOLN ::= step_count "ANY"
+-//       |  step_count "<" pkgname1 vername1 ... ">"
+-//
+-// The second DEP form is a Conflicts, and is implicitly converted to
+-// dependency form internally.
+-
+-/** Reads the list of scores into the resolver. */
+-void read_scores(istream &f,
+-		 dummy_universe_ref universe, dummy_resolver &resolver)
+-{
+-  if(!universe)
+-    throw ParseError("Internal error: NULL universe in read_scores");
+-
+-  f >> ws;
+-
+-  while(f)
+-    {
+-      string s;
+-
+-      f >> s >> ws;
+-
+-      if(s == "}")
+-	return;
+-      else if(s == "SCORE")
+-	{
+-	  if(f.eof())
+-	    throw ParseError("Expected package name following SCORE, got "+s);
+-
+-	  string pkgname;
+-
+-	  f >> pkgname >> ws;
+-
+-	  dummy_universe::package pkg=universe.find_package(pkgname);
+-
+-	  if(f.eof())
+-	    throw ParseError("Expected '<' following package name, got EOF");
+-
+-	  f >> s >> ws;
+-
+-	  if(s != "<")
+-	    throw ParseError("Expected '<' following package name, got "+s);
+-
+-	  if(f.eof())
+-	    throw ParseError("Expected '>' or version name, got EOF");
+-
+-	  while(f)
+-	    {
+-	      string vername;
+-	      int score;
+-
+-	      f >> vername >> ws;
+-
+-	      if(vername == ">")
+-		break;
+-
+-	      dummy_universe::version ver=pkg.version_from_name(vername);
+-
+-	      if(f.eof())
+-		throw ParseError("Expected score, got EOF");
+-
+-	      f >> score >> ws;
+-
+-	      if(f.eof())
+-		throw ParseError("Expected '>' or version name, got EOF");
+-
+-	      if(!f)
+-		throw ParseError("Error reading score of " + pkgname + " " + vername);
+-
+-	      resolver.set_version_score(ver, score);
+-	    }
+-
+-	  if(f.eof())
+-	    throw ParseError("Expected '}' or SCORE, got EOF");
+-	}
+-      else
+-	throw ParseError("Expected 'SCORE' or '}', got "+s);
+-    }
+-
+-  throw ParseError("Unexpected error reading score list.");
+-}
+-
+-/** Reads the tail of a non-ANY SOLN form. */
+-map<dummy_universe::package, dummy_resolver::version> read_solution(istream &f, dummy_universe_ref universe)
+-{
+-  if(!universe)
+-    throw ParseError("Internal error: NULL universe passed to read_solution");
+-
+-  map<dummy_universe::package, dummy_resolver::version> rval;
+-
+-  f >> ws;
+-
+-  while(f)
+-    {
+-      string s;
+-
+-      if(f.eof())
+-	throw ParseError("Expected '>' or package, got EOF");
+-
+-      f >> s >> ws;
+-
+-      if(s == ">")
+-	return rval;
+-      else
+-	{
+-	  if(f.eof())
+-	    throw ParseError("Expected version, got EOF");
+-
+-	  dummy_universe::package pkg=universe.find_package(s);
+-
+-	  f >> s >> ws;
+-
+-	  if(f.eof())
+-	    throw ParseError("Expected '>' or package name, got EOF");
+-
+-	  if(s == ">")
+-	    throw ParseError("Expected version name, got '>'");
+-
+-	  dummy_universe::version ver=pkg.version_from_name(s);
+-
+-	  if(rval.find(pkg) != rval.end())
+-	    throw ParseError("Package "+pkg.get_name()+" bound twice in solution");
+-
+-	  rval[pkg]=ver;
+-	}
+-    }
+-
+-  throw ParseError("Unexpected error reading solution list");
+-}
+-
+-void run_test_file(istream &f, bool show_world)
+-{
+-  dummy_universe_ref universe=NULL;
+-
+-  f >> ws;
+-
+-  while(f)
+-    {
+-      string s;
+-
+-      if(f.eof())
+-	// This is the only place where EOF is valid.
+-	return;
+-
+-      f >> s >> ws;
+-
+-      if(s == "UNIVERSE")
+-	{
+-	  if(f.eof())
+-	    throw ParseError("Expected '[' following UNIVERSE, got EOF.");
+-
+-	  f >> s >> ws;
+-
+-	  if(s != "[")
+-	    throw ParseError("Expected '[' following UNIVERSE, got " + s);
+-
+-	  universe=parse_universe_tail(f);
+-
+-	  if(show_world)
+-	    {
+-	      cout << "Input universe:" << endl;
+-	      dump_universe(universe, cout);
+-	    }
+-	}
+-      else if(s == "TEST")
+-	{
+-	  if(!universe)
+-	    throw ParseError("Expected UNIVERSE before TEST");
+-
+-	  if(f.eof())
+-	    throw ParseError("Expected step_score and broken_score following 'TEST', got EOF");
+-
+-	  int step_score;
+-	  int broken_score;
+-	  int unfixed_soft_score;
+-	  int infinity;
+-	  int max_successors;
+-	  int goal_score;
+-
+-	  f >> step_score >> broken_score >> unfixed_soft_score >> infinity >> max_successors >> goal_score;
+-
+-	  if(f.eof())
+-	    throw ParseError("Expected '{' following broken_score, got EOF");
+-
+-	  if(!f)
+-	    throw ParseError("Error reading step_score, broken_score, unfixed_soft_score, infinity, max_succ, and goal_score after 'TEST'");
+-
+-	  f >> s >> ws;
+-
+-	  if(s != "{")
+-	    throw ParseError("Expected '{' following TEST, got "+s);
+-
+-	  dummy_resolver resolver(step_score, broken_score,
+-				  unfixed_soft_score,
+-				  infinity, max_successors,
+-				  goal_score, universe);
+-
+-	  resolver.set_debug(true);
+-
+-	  read_scores(f, universe, resolver);
+-
+-	  if(f.eof())
+-	    throw ParseError("Expected 'EXPECT', got EOF");
+-
+-	  f >> s >> ws;
+-
+-	  if(s != "EXPECT")
+-	    throw ParseError("Expected 'EXPECT', got "+s);
+-
+-	  if(f.eof())
+-	    throw ParseError("Expected '(' following EXPECT, got EOF");
+-
+-	  f >> s >> ws;
+-
+-	  if(s != "(")
+-	    throw ParseError("Expected '(' following EXPECT, got "+s);
+-
+-	  while(f)
+-	    {
+-	      if(f.eof())
+-		throw ParseError("Expected ')' or package name, got EOF");
+-
+-	      f >> s >> ws;
+-
+-	      if(s == ")")
+-		break;
+-
+-	      int step_count=atoi(s.c_str());
+-
+-	      if(step_count<=0)
+-		throw ParseError("step_count must be a positive integer, not "+s);
+-
+-	      f >> s >> ws;
+-
+-	      if(s == "ANY")
+-		{
+-		  try
+-		    {
+-		      dummy_resolver::solution next_soln=resolver.find_next_solution(step_count);
+-
+-		      cout << "Next solution is ";
+-		      next_soln.dump(cout);
+-
+-		      cout << " (ignored)" << endl;
+-		    }
+-		  catch(NoMoreTime)
+-		    {
+-		      cout << "Ran out of steps (ignored)" << endl;
+-		    }
+-		  catch(NoMoreSolutions)
+-		    {
+-		      cout << "Ran out of solutions (ignored)" << endl;
+-		    }
+-		}
+-	      else if(s == "<")
+-		{
+-		  try
+-		    {
+-		      map<dummy_universe::package, dummy_resolver::version> expected=read_solution(f, universe);
+-
+-		      dummy_resolver::solution next_soln=resolver.find_next_solution(step_count);
+-
+-
+-		      cout << "Next solution is ";
+-		      next_soln.dump(cout);
+-
+-		      bool equal=true;
+-
+-		      std::map<dummy_universe::package, dummy_universe::version>::const_iterator expect_iter=expected.begin();
+-		      imm::map<dummy_universe::package, dummy_resolver::action>::const_iterator soln_iter=next_soln.get_actions().begin();
+-
+-		      while(equal &&
+-			    expect_iter != expected.end() &&
+-			    soln_iter != next_soln.get_actions().end())
+-			{
+-			  if(expect_iter->first != soln_iter->first ||
+-			     expect_iter->second != soln_iter->second.ver)
+-			    equal=false;
+-			}
+-
+-		      if(equal)
+-			cout << " (OK)" << endl;
+-		      else
+-			{
+-			  cout << " (FAILED)" << endl;
+-			  cout << "Expected <";
+-			  for(map<dummy_universe::package, dummy_universe::version>::const_iterator i=expected.begin();
+-			      i!=expected.end(); ++i)
+-			    cout << i->first.get_name()
+-				 << ":="
+-				 << i->second.get_name();
+-			  cout << ">" << endl;
+-			}
+-		    }
+-		  catch(NoMoreSolutions)
+-		    {
+-		      cout << "Ran out of solutions (FAILED)" << endl;
+-		    }
+-		  catch(NoMoreTime)
+-		    {
+-		      cout << "Ran out of time (FAILED)" << endl;
+-		    }
+-		}
+-	      else
+-		throw ParseError("Expected ANY or '<', got "+s);
+-	    }
+-	}
+-      else
+-	throw ParseError("Expected UNIVERSE or TEST, got "+s);
+-    }
+-}
+-
+-int main(int argc, char **argv)
+-{
+-  int rval=0;
+-  bool show_world=false;
+-
+-  for(int i=1; i<argc; ++i)
+-    {
+-      // lame man's command line
+-      if(!strcmp(argv[0], "--dump"))
+-	show_world=true;
+-
+-      ifstream f(argv[i]);
+-
+-      if(!f)
+-	{
+-	  cerr << "Couldn't read from file " << argv[i] << "." << endl;
+-	  rval=-1;
+-	}
+-
+-      try
+-	{
+-	  f >> ws;
+-	  run_test_file(f, show_world);
+-	}
+-      catch(const Exception &e)
+-	{
+-	  cerr << "Error reading " << argv[i] << ": " << e.errmsg() << endl;
+-	  rval=-1;
+-	}
+-    }
+-
+-  return rval;
+-}
+-
+diff --git a/src/generic/problemresolver/test1.txt b/src/generic/problemresolver/test1.txt
+deleted file mode 100644
+index 0f79547..0000000
+--- a/src/generic/problemresolver/test1.txt
++++ /dev/null
+@@ -1,25 +0,0 @@
+-UNIVERSE [
+-  PACKAGE p1 < v1 v2 v3 > v1
+-  PACKAGE p2 < v1 v2 v3 > v1
+-  PACKAGE p3 < v1 v2 v3 > v1
+-  PACKAGE p4 < v1 v2 v3 > v1
+-
+-
+-  DEP p1 v1 -> < p2 v2  p2 v3 >
+-  DEP p1 v2 -> < p2 v2  p2 v3 >
+-  DEP p1 v3 -> < p2 v2  p2 v3 >
+-
+-  DEP p2 v1 -> < p3 v1  p3 v2  p3 v3 >
+-  DEP p2 v2 -> < p3 v1  p3 v2  p3 v3 >
+-
+-  DEP p2 v1 !! < p1 v2  p1 v3 >
+-
+-
+-  DEP p3 v1 -> < p4 v1  p4 v2  p4 v3 >
+-  DEP p3 v2 -> < p4 v1  p4 v2  p4 v3 >
+-  DEP p3 v3 -> < p4 v1  p4 v2  p4 v3 >
+-]
+-
+-TEST 10 10 -100 10000 10 50 { } EXPECT ( 10000 ANY
+-		     	                 10000 ANY
+-                                         10000 ANY )
+\ No newline at end of file
+diff --git a/src/generic/problemresolver/test3.txt b/src/generic/problemresolver/test3.txt
+deleted file mode 100644
+index 413d37f..0000000
+--- a/src/generic/problemresolver/test3.txt
++++ /dev/null
+@@ -1,25 +0,0 @@
+-UNIVERSE [
+-  PACKAGE p1 < v1 v2 v3 > v1
+-  PACKAGE p2 < v1 v2 v3 > v1
+-  PACKAGE p3 < v1 v2 v3 > v1
+-  PACKAGE p4 < v1 v2 v3 > v1
+-
+-
+-  DEP p1 v1 -> < p2 v2  p2 v3 >
+-  DEP p1 v2 -> < p2 v2  p2 v3 >
+-  DEP p1 v3 -> < p2 v2  p2 v3 >
+-
+-  DEP p2 v1 -> < p3 v1  p3 v2  p3 v3 >
+-  DEP p2 v2 -> < p3 v1  p3 v2  p3 v3 >
+-
+-  DEP p2 v1 !! < p1 v2  p1 v3 >
+-
+-
+-  DEP p3 v1 -> < p4 v1  p4 v2  p4 v3 >
+-  DEP p3 v2 -> < p4 v1  p4 v2  p4 v3 >
+-  DEP p3 v3 -> < p4 v1  p4 v2  p4 v3 >
+-]
+-
+-TEST 10 10 -1000 10000 10 50 { } EXPECT ( 10000 ANY
+-					  10000 ANY
+-					  10000 ANY )
+diff --git a/src/generic/problemresolver/test4.txt b/src/generic/problemresolver/test4.txt
+deleted file mode 100644
+index fb22b16..0000000
+--- a/src/generic/problemresolver/test4.txt
++++ /dev/null
+@@ -1,23 +0,0 @@
+-UNIVERSE [
+-  PACKAGE p1 < v1 v2 v3 > v1
+-  PACKAGE p2 < v1 v2 v3 > v1
+-  PACKAGE p3 < v1 v2 v3 > v1
+-  PACKAGE p4 < v1 v2 v3 > v1
+-
+-
+-  DEP p1 v1 -> < p2 v2  p2 v3 >
+-  DEP p1 v2 -> < p2 v2  p2 v3 >
+-  DEP p1 v3 -> < p2 v2  p2 v3 >
+-
+-  DEP p2 v1 -> < p3 v1  p3 v2  p3 v3 >
+-  DEP p2 v2 -> < p3 v1  p3 v2  p3 v3 >
+-
+-  DEP p2 v1 !! < p1 v2  p1 v3 >
+-
+-
+-  DEP p3 v1 -> < p4 v1  p4 v2  p4 v3 >
+-  DEP p3 v2 -> < p4 v1  p4 v2  p4 v3 >
+-  DEP p3 v3 -> < p4 v1  p4 v2  p4 v3 >
+-]
+-
+-TEST 10 10 10000 10 50 { SCORE p1
+diff --git a/src/load_grouppolicy.cc b/src/load_grouppolicy.cc
+index b5c07ed..7c8923e 100644
+--- a/src/load_grouppolicy.cc
++++ b/src/load_grouppolicy.cc
+@@ -25,7 +25,6 @@
+ #include "load_grouppolicy.h"
+ 
+ #include <generic/apt/matchers.h>
+-#include <generic/apt/pkg_hier.h>
+ 
+ #include <generic/util/util.h>
+ 
+@@ -521,50 +520,6 @@ class priority_policy_parser : public string_policy_parser
+   }
+ };
+ 
+-class hier_policy_parser : public string_policy_parser
+-{
+-  group_policy_parse_node *create_node(const vector<string> &args)
+-  {
+-    if(!args.empty())
+-      {
+-	// FIXME: who deletes this??
+-	pkg_hier *hier=new pkg_hier;
+-
+-	for(vector<string>::const_iterator i = args.begin();
+-	    i != args.end(); ++i)
+-	  hier->input_file(*i);
+-
+-	return new policy_node2<pkg_grouppolicy_hier_factory, pkg_hier *, bool>(hier, true);
+-      }
+-    else
+-      return new policy_node2<pkg_grouppolicy_hier_factory, pkg_hier *, bool>(get_user_pkg_hier(), false);
+-  }
+-};
+-
+-class task_policy_parser : public string_policy_parser
+-{
+-  group_policy_parse_node *create_node(const vector<string> &args)
+-  {
+-    if(args.size()!=0)
+-      throw GroupParseException(_("Task grouping policies take no arguments"));
+-
+-    return new policy_node0<pkg_grouppolicy_task_factory>;
+-  }
+-};
+-
+-class tag_policy_parser : public string_policy_parser
+-{
+-  group_policy_parse_node *create_node(const vector<string> &args)
+-  {
+-    if(args.size() == 0)
+-      return new policy_node0<pkg_grouppolicy_facet_tag_factory>;
+-    else if(args.size() != 1)
+-      throw GroupParseException(_("Expected no more than one argument to a tag grouping policy"));
+-    else
+-      return new policy_node1<pkg_grouppolicy_tag_factory, string>(args[0]);
+-  }
+-};
+-
+ class pattern_policy_parser : public group_policy_parser
+ {
+   group_policy_parse_node *parse(string::const_iterator &begin,
+@@ -673,9 +628,6 @@ static void init_parse_types()
+       parse_types["versions"]=new ver_policy_parser;
+       parse_types["deps"]=new dep_policy_parser;
+       parse_types["priority"]=new priority_policy_parser;
+-      parse_types["hier"]=new hier_policy_parser;
+-      parse_types["task"]=new task_policy_parser;
+-      parse_types["tag"]=new tag_policy_parser;
+ 
+       parse_types["pattern"]=new pattern_policy_parser;
+ 
+diff --git a/src/main.cc b/src/main.cc
+index 88ef080..05de858 100644
+--- a/src/main.cc
++++ b/src/main.cc
+@@ -35,19 +35,15 @@
+ #include <generic/apt/apt.h>
+ #include <generic/apt/config_signal.h>
+ 
+-#include <generic/problemresolver/exceptions.h>
+-
+ #include <vscreen/config/keybindings.h>
+ #include <vscreen/transcode.h>
+ #include <vscreen/vscreen.h>
+ #include <vscreen/vs_util.h>
+ 
+-#include <cmdline/cmdline_changelog.h>
+ #include <cmdline/cmdline_clean.h>
+ #include <cmdline/cmdline_common.h>
+ #include <cmdline/cmdline_do_action.h>
+ #include <cmdline/cmdline_download.h>
+-#include <cmdline/cmdline_dump_resolver.h>
+ #include <cmdline/cmdline_forget_new.h>
+ #include <cmdline/cmdline_moo.h>
+ #include <cmdline/cmdline_prompt.h>
+@@ -119,7 +115,6 @@ static void usage()
+   printf(_("  Actions (if none is specified, aptitude will enter interactive mode):\n\n"));
+   printf(_(" install      - Install/upgrade packages\n"));
+   printf(_(" remove       - Remove packages\n"));
+-  printf(_(" purge        - Remove packages and their configuration files\n"));
+   printf(_(" hold         - Place packages on hold\n"));
+   printf(_(" unhold       - Cancel a hold command for a package\n"));
+   printf(_(" markauto     - Mark packages as having been automatically installed\n"));
+@@ -137,7 +132,6 @@ static void usage()
+   printf(_(" show         - Display detailed information about a package\n"));
+   printf(_(" clean        - Erase downloaded package files\n"));
+   printf(_(" autoclean    - Erase old downloaded package files\n"));
+-  printf(_(" changelog    - View a package's changelog\n"));
+   printf(_(" download     - Download the .deb file for a package\n"));
+   printf(_(" reinstall    - Download and (possibly) reinstall a currently installed package\n"));
+   printf("\n");
+@@ -171,7 +165,6 @@ enum {
+   OPTION_VERSION = 1,
+   OPTION_VISUAL_PREVIEW,
+   OPTION_QUEUE_ONLY,
+-  OPTION_PURGE_UNUSED,
+ };
+ int getopt_result;
+ 
+@@ -194,7 +187,6 @@ option opts[]={
+   {"target-release", 1, NULL, 't'},
+   {"visual-preview", 0, &getopt_result, OPTION_VISUAL_PREVIEW},
+   {"schedule-only", 0, &getopt_result, OPTION_QUEUE_ONLY},
+-  {"purge-unused", 0, &getopt_result, OPTION_PURGE_UNUSED},
+   {0,0,0,0}
+ };
+ 
+@@ -374,9 +366,6 @@ int main(int argc, char *argv[])
+ 	    case OPTION_QUEUE_ONLY:
+ 	      queue_only=true;
+ 	      break;
+-	    case OPTION_PURGE_UNUSED:
+-	      aptcfg->Set(PACKAGE "::Purge-Unused", "true");
+-	      break;
+ 	    default:
+ 	      fprintf(stderr, "%s",
+ 		      _("WEIRDNESS: unknown option code received\n"));
+@@ -457,7 +446,6 @@ int main(int argc, char *argv[])
+ 		   (!strcasecmp(argv[optind], "reinstall")) ||
+ 		   (!strcasecmp(argv[optind], "dist-upgrade")) ||
+ 		   (!strcasecmp(argv[optind], "remove")) ||
+-		   (!strcasecmp(argv[optind], "purge")) ||
+ 		   (!strcasecmp(argv[optind], "hold")) ||
+ 		   (!strcasecmp(argv[optind], "unhold")) ||
+ 		   (!strcasecmp(argv[optind], "markauto")) ||
+@@ -480,14 +468,10 @@ int main(int argc, char *argv[])
+ 				   queue_only, verbose);
+ 	  else if(!strcasecmp(argv[optind], "download"))
+ 	    return cmdline_download(argc-optind, argv+optind);
+-	  else if(!strcasecmp(argv[optind], "changelog"))
+-	    return cmdline_changelog(argc-optind, argv+optind);
+ 	  else if(!strcasecmp(argv[optind], "moo"))
+ 	    return cmdline_moo(argc-optind, argv+optind, verbose);
+ 	  else if(!strcasecmp(argv[optind], "show"))
+ 	    return cmdline_show(argc-optind, argv+optind, verbose);
+-	  else if(!strcasecmp(argv[optind], "dump-resolver"))
+-	    return cmdline_dump_resolver(argc-optind, argv+optind, status_fname);
+ 	  else if(!strcasecmp(argv[optind], "help"))
+ 	    {
+ 	      usage();
+diff --git a/src/menu_redirect.cc b/src/menu_redirect.cc
+index 561fc12..1cc59a9 100644
+--- a/src/menu_redirect.cc
++++ b/src/menu_redirect.cc
+@@ -31,7 +31,6 @@ bool menu_redirect::undo_undo() { return false; }
+ bool menu_redirect::package_enabled() { return false; }
+ bool menu_redirect::package_install() { return false; }
+ bool menu_redirect::package_remove() { return false; }
+-bool menu_redirect::package_purge() { return false; }
+ bool menu_redirect::package_hold() { return false; }
+ bool menu_redirect::package_keep() { return false; }
+ bool menu_redirect::package_mark_auto() { return false; }
+@@ -40,14 +39,6 @@ bool menu_redirect::package_forbid_enabled() { return false; }
+ bool menu_redirect::package_forbid() { return false; }
+ bool menu_redirect::package_information_enabled() { return false; }
+ bool menu_redirect::package_information() { return false; }
+-bool menu_redirect::package_changelog_enabled() { return false; }
+-bool menu_redirect::package_changelog() { return false; }
+-bool menu_redirect::resolver_toggle_approved() { return false;}
+-bool menu_redirect::resolver_toggle_approved_enabled() { return false; }
+-bool menu_redirect::resolver_toggle_rejected() { return false;}
+-bool menu_redirect::resolver_toggle_rejected_enabled() { return false; }
+-bool menu_redirect::resolver_view_target() { return false; }
+-bool menu_redirect::resolver_view_target_enabled() { return false; }
+ bool menu_redirect::find_search_enabled() { return false; }
+ bool menu_redirect::find_search() { return false; }
+ bool menu_redirect::find_search_back_enabled() { return false; }
+@@ -108,11 +99,6 @@ void create_menu_bindings(menu_redirect *menu_handler,
+ 				    menu_handler,
+ 				    &menu_redirect::package_remove));
+ 
+-  package_purge.connect(sigc::bind(sigc::ptr_fun(do_menu_callback),
+-				   valve.weak_ref(),
+-				   menu_handler,
+-				   &menu_redirect::package_purge));
+-
+   package_hold.connect(sigc::bind(sigc::ptr_fun(do_menu_callback),
+ 				  valve.weak_ref(),
+ 				  menu_handler,
+@@ -153,47 +139,6 @@ void create_menu_bindings(menu_redirect *menu_handler,
+ 					 menu_handler,
+ 					 &menu_redirect::package_information));
+ 
+-  package_changelog_enabled.connect(sigc::bind(sigc::ptr_fun(do_menu_callback),
+-					       valve.weak_ref(),
+-					       menu_handler,
+-					       &menu_redirect::package_changelog_enabled));
+-
+-  package_changelog.connect(sigc::bind(sigc::ptr_fun(do_menu_callback),
+-				       valve.weak_ref(),
+-				       menu_handler,
+-				       &menu_redirect::package_changelog));
+-
+-
+-  resolver_toggle_rejected_enabled.connect(sigc::bind(sigc::ptr_fun(do_menu_callback),
+-						      valve.weak_ref(),
+-						      menu_handler,
+-						      &menu_redirect::resolver_toggle_rejected_enabled));
+-
+-  resolver_toggle_rejected.connect(sigc::bind(sigc::ptr_fun(do_menu_callback),
+-					      valve.weak_ref(),
+-					      menu_handler,
+-					      &menu_redirect::resolver_toggle_rejected));
+-
+-  resolver_toggle_approved_enabled.connect(sigc::bind(sigc::ptr_fun(do_menu_callback),
+-						      valve.weak_ref(),
+-						      menu_handler,
+-						      &menu_redirect::resolver_toggle_approved_enabled));
+-
+-  resolver_toggle_approved.connect(sigc::bind(sigc::ptr_fun(do_menu_callback),
+-					      valve.weak_ref(),
+-					      menu_handler,
+-					      &menu_redirect::resolver_toggle_approved));
+-
+-  resolver_view_target_enabled.connect(sigc::bind(sigc::ptr_fun(do_menu_callback),
+-						  valve.weak_ref(),
+-						  menu_handler,
+-						  &menu_redirect::resolver_view_target_enabled));
+-
+-  resolver_view_target.connect(sigc::bind(sigc::ptr_fun(do_menu_callback),
+-					  valve.weak_ref(),
+-					  menu_handler,
+-					  &menu_redirect::resolver_view_target));
+-
+ 
+   find_search_enabled.connect(sigc::bind(sigc::ptr_fun(do_menu_callback),
+ 					 valve.weak_ref(),
+diff --git a/src/menu_redirect.h b/src/menu_redirect.h
+index 9072c91..01d0ed3 100644
+--- a/src/menu_redirect.h
++++ b/src/menu_redirect.h
+@@ -46,9 +46,6 @@ public:
+   /** Remove the selected package (if any). */
+   virtual bool package_remove();
+ 
+-  /** Purge the selected package (if any). */
+-  virtual bool package_purge();
+-
+   /** Hold the selected package (if any). */
+   virtual bool package_hold();
+ 
+@@ -77,31 +74,6 @@ public:
+    */
+   virtual bool package_information();
+ 
+-  /** \return \b true if the selected item has a changelog. */
+-  virtual bool package_changelog_enabled();
+-
+-  /** View the changelog of the selected package. */
+-  virtual bool package_changelog();
+-
+-
+-  /** Toggle whether a solution action item is approved. */
+-  virtual bool resolver_toggle_approved();
+-
+-  /** \return \b true if the selected item can be approved. */
+-  virtual bool resolver_toggle_approved_enabled();
+-
+-  /** Toggle whether a solution action item is rejected. */
+-  virtual bool resolver_toggle_rejected();
+-
+-  /** \return \b true if the selected item can be approved. */
+-  virtual bool resolver_toggle_rejected_enabled();
+-
+-  /** View information about a solution action item. */
+-  virtual bool resolver_view_target();
+-
+-  /** \return \b true if the selected item can be approved. */
+-  virtual bool resolver_view_target_enabled();
+-
+ 
+   /** \return \b true if this view knows how to search. */
+   virtual bool find_search_enabled();
+diff --git a/src/menu_tree.cc b/src/menu_tree.cc
+index 5ae7052..13938fa 100644
+--- a/src/menu_tree.cc
++++ b/src/menu_tree.cc
+@@ -24,9 +24,7 @@
+ #include "pkg_item.h"
+ #include "pkg_tree.h" // For pkg_tree::bindings(?!?!)
+ #include "pkg_ver_item.h"
+-#include "solution_item.h"
+ #include "ui.h"
+-#include "view_changelog.h"
+ 
+ #include <generic/apt/apt.h>
+ #include <generic/apt/apt_undo_group.h>
+@@ -107,11 +105,6 @@ bool menu_tree::package_remove()
+   return proxy_redirect(&menu_redirect::package_remove);
+ }
+ 
+-bool menu_tree::package_purge()
+-{
+-  return proxy_redirect(&menu_redirect::package_purge);
+-}
+-
+ bool menu_tree::package_keep()
+ {
+   return proxy_redirect(&menu_redirect::package_keep);
+@@ -142,16 +135,6 @@ bool menu_tree::package_forbid()
+   return proxy_redirect(&menu_redirect::package_forbid);
+ }
+ 
+-bool menu_tree::package_changelog_enabled()
+-{
+-  return proxy_redirect(&menu_redirect::package_changelog_enabled);
+-}
+-
+-bool menu_tree::package_changelog()
+-{
+-  return proxy_redirect(&menu_redirect::package_changelog);
+-}
+-
+ bool menu_tree::package_information_enabled()
+ {
+   return proxy_redirect(&menu_redirect::package_information_enabled);
+@@ -162,37 +145,6 @@ bool menu_tree::package_information()
+   return proxy_redirect(&menu_redirect::package_information);
+ }
+ 
+-bool menu_tree::resolver_toggle_rejected()
+-{
+-  return proxy_redirect(&menu_redirect::resolver_toggle_rejected);
+-}
+-
+-bool menu_tree::resolver_toggle_rejected_enabled()
+-{
+-  return proxy_redirect(&menu_redirect::resolver_toggle_rejected_enabled);
+-}
+-
+-bool menu_tree::resolver_toggle_approved()
+-{
+-  return proxy_redirect(&menu_redirect::resolver_toggle_approved);
+-}
+-
+-bool menu_tree::resolver_toggle_approved_enabled()
+-{
+-  return proxy_redirect(&menu_redirect::resolver_toggle_approved_enabled);
+-}
+-
+-bool menu_tree::resolver_view_target()
+-{
+-  return proxy_redirect(&menu_redirect::resolver_view_target);
+-}
+-
+-bool menu_tree::resolver_view_target_enabled()
+-{
+-  return proxy_redirect(&menu_redirect::resolver_view_target_enabled);
+-}
+-
+-
+ 
+ bool menu_tree::find_search_enabled()
+ {
+diff --git a/src/menu_tree.h b/src/menu_tree.h
+index a668cb4..a3f18a0 100644
+--- a/src/menu_tree.h
++++ b/src/menu_tree.h
+@@ -30,7 +30,6 @@
+ 
+ class pkg_matcher;
+ class pkg_tree_node;
+-class solution_item;
+ class undo_group;
+ 
+ /** A vs_tree that can be generically used as a menu redirector.  All
+@@ -54,11 +53,6 @@ class menu_tree:public vs_tree, public menu_redirect
+   /** Return the selected node, if any, or \b NULL if no node is selected. */
+   pkg_tree_node *pkg_node_selection();
+ 
+-  /** Return the selected solution item, if any, or \b NULL if no
+-   *  solution is selected.
+-   */
+-  solution_item *solution_selection();
+-
+   /** A precompiled matcher representing the last search that was performed. */
+   pkg_matcher *last_search_matcher;
+ 
+@@ -113,9 +107,6 @@ public:
+   /** If a pkg_node is currently selected, execute its "remove" operation. */
+   bool package_remove();
+ 
+-  /** If a pkg_node is currently selected, execute its "purge" operation. */
+-  bool package_purge();
+-
+   /** If a pkg_node is currently selected, execute its "keep" operation. */
+   bool package_keep();
+ 
+@@ -137,37 +128,12 @@ public:
+   bool package_forbid();
+ 
+   /** \return \b true if a package or a package version is selected. */
+-  bool package_changelog_enabled();
+-
+-  /** If a package or version is selected, show its changelog. */
+-  bool package_changelog();
+-
+-  /** \return \b true if a package or a package version is selected. */
+   bool package_information_enabled();
+ 
+   /** If a package or version is selected, show its information. */
+   bool package_information();
+ 
+ 
+-  /** If a solution item is selected, toggle whether it is rejected. */
+-  bool resolver_toggle_rejected();
+-
+-  /** \return \b true if a solution item is selected. */
+-  bool resolver_toggle_rejected_enabled();
+-
+-  /** If a solution item is selected, toggle whether it is approved. */
+-  bool resolver_toggle_approved();
+-
+-  /** \return \b true if a solution item is selected. */
+-  bool resolver_toggle_approved_enabled();
+-
+-  /** If a solution item is selected, view its target. */
+-  bool resolver_view_target();
+-
+-  /** \return \b true if a solution item is selected. */
+-  bool resolver_view_target_enabled();
+-
+-
+   /** \return \b true; all package trees know how to search. */
+   bool find_search_enabled();
+ 
+diff --git a/src/pkg_columnizer.cc b/src/pkg_columnizer.cc
+index c3a1876..47ffe09 100644
+--- a/src/pkg_columnizer.cc
++++ b/src/pkg_columnizer.cc
+@@ -25,7 +25,6 @@
+ 
+ #include <generic/apt/apt.h>
+ #include <generic/apt/config_signal.h>
+-#include <generic/apt/tasks.h>
+ 
+ #include <apt-pkg/error.h>
+ #include <apt-pkg/pkgrecords.h>
+@@ -34,6 +33,10 @@
+ #include <apt-pkg/strutl.h>
+ #include <apt-pkg/version.h>
+ 
++#ifndef HAVE_LIBAPT_PKG3
++#define pkgCheckDep _system->checkDep
++#endif
++
+ #include <vscreen/transcode.h>
+ 
+ #include <unistd.h>
+@@ -261,7 +264,7 @@ column_disposition pkg_item::pkg_columnizer::setup_column(int type)
+ 		!candver.end() && candver.VerStr() == estate.forbidver)
+ 	  return column_disposition("F", 0);
+ 	else if(state.Delete())
+-	  return column_disposition((state.iFlags&pkgDepCache::Purge)?"p":"d", 0);
++	  return column_disposition("d", 0);
+ 	else if(state.InstBroken())
+ 	  return column_disposition("B", 0);
+ 	else if(state.NewInstall())
+@@ -292,7 +295,7 @@ column_disposition pkg_item::pkg_columnizer::setup_column(int type)
+ 		!candver.end() && candver.VerStr() == estate.forbidver)
+ 	  return column_disposition(_("forbidden upgrade"), 0);
+ 	else if(state.Delete())
+-	  return column_disposition((state.iFlags&pkgDepCache::Purge)?_("purge"):_("delete"), 0);
++	  return column_disposition(_("delete"), 0);
+ 	else if(state.InstBroken())
+ 	  return column_disposition(_("broken"), 0);
+ 	else if(state.NewInstall())
+diff --git a/src/pkg_grouppolicy.cc b/src/pkg_grouppolicy.cc
+index bf6abde..ed6e21e 100644
+--- a/src/pkg_grouppolicy.cc
++++ b/src/pkg_grouppolicy.cc
+@@ -29,9 +29,6 @@
+ 
+ #include <generic/apt/apt.h>
+ #include <generic/apt/matchers.h>
+-#include <generic/apt/pkg_hier.h>
+-#include <generic/apt/tags.h>
+-#include <generic/apt/tasks.h>
+ 
+ #include <generic/util/util.h>
+ 
+@@ -158,51 +155,7 @@ void pkg_grouppolicy_section::init_section_descriptions()
+   if(already_done)
+     return;
+ 
+-  section_descriptions["Tasks"]=transcode(_("Packages which set up your computer to perform a particular task\n Packages in the 'Tasks' section contain no files; they merely depend upon other packages. These packages provide an easy way to select a predefined set of packages for a specialized task."));
+-
+   section_descriptions["Unknown"]=transcode(_("Packages with no declared section\n No section is given for these packages. Perhaps there is an error in the Packages file?"));
+-
+-  section_descriptions["admin"]=transcode(_("Administrative utilities (install software, manage users, etc)\n Packages in the 'admin' section allow you to perform administrative tasks such as installing software, managing users, configuring and monitoring your system, examining network traffic, and so on."));
+-
+-  section_descriptions["alien"]=transcode(_("Packages converted from foreign formats (rpm, tgz, etc)\n Packages in the 'alien' section were created by the 'alien' program from a non-Debian package format such as RPM"));
+-  section_descriptions["base"]=transcode(_("The Debian base system\n Packages in the 'base' section are part of the initial system installation."));
+-  section_descriptions["comm"]=transcode(_("Programs for faxmodems and other communication devices\n Packages in the 'comm' section are used to control modems and other hardware communications devices. This includes software to control faxmodems (for instance, PPP for dial-up internet connections and programs originally written for that purpose, such as zmodem/kermit), as well as software to control cellular phones, interface with FidoNet, and run a BBS."));
+-  section_descriptions["devel"]=transcode(_("Utilities and programs for software development\n Packages in the 'devel' section are used to write new software and work on existing software. Non-programmers who do not compile their own software probably do not need much software from this section.\n .\n It includes compilers, debugging tools, programmer's editors, source processing tools, and other things related to software development."));
+-  section_descriptions["doc"]=transcode(_("Documentation and specialized programs for viewing documentation\n Packages in the 'doc' section document parts of the Debian system, or are viewers for documentation formats."));
+-  section_descriptions["editors"]=transcode(_("Text editors and word processors\n Packages in the 'editors' section allow you to edit plain ASCII text. These are not necessarily word processors, although some word processors may be found in this section."));
+-  section_descriptions["electronics"]=transcode(_("Programs for working with circuits and electronics\n Packages in the 'electronics' section include circuit design tools, simulators and assemblers for microcontrollers, and other related software."));
+-  section_descriptions["embedded"]=transcode(_("Programs for embedded systems\n Packages in the 'embedded' section are meant to run on embedded devices. Embedded devices are specialized hardware devices with much less power than a typical desktop system: for instance, a PDA, a cell phone, or a Tivo."));
+-  section_descriptions["gnome"]=transcode(_("The GNOME Desktop System\n GNOME is a collection of software which provides an easy-to-use desktop environment for Linux.  Packages in the 'gnome' section are part of the GNOME environment or closely integrated into it."));
+-  section_descriptions["games"]=transcode(_("Games, toys, and fun programs\n Packages in the 'games' section are meant primarily for entertainment."));
+-  section_descriptions["graphics"]=transcode(_("Utilities to create, view, and edit graphics files\n Packages in the 'graphics' section include viewers for image files, image processing and manipulation software, software to interact with graphics hardware (such as video cards, scanners, and digital cameras), and programming tools for handling graphics."));
+-  section_descriptions["hamradio"]=transcode(_("Software for ham radio operators\n Packages in the 'hamradio' section are meant primarily for ham radio operators."));
+-  section_descriptions["interpreters"]=transcode(_("Interpreters for interpreted languages\n Packages in the 'interpreters' section include interpreters for languages like Python, Perl, and Ruby, and libraries for these same languages."));
+-  section_descriptions["kde"]=transcode(_("The KDE Desktop System\n KDE is a collection of software which provides an easy-to-use desktop environment for Linux.  Packages in the 'kde' section are part of the KDE environment or closely integrated into it."));
+-  section_descriptions["libdevel"]=transcode(_("Development files for libraries\n Packages in the 'libdevel' section contain files required for building programs that use libraries in the 'libs' section.  You don't need packages from this section unless you want to compile software yourself."));
+-  section_descriptions["libs"]=transcode(_("Collections of software routines\n Packages in the 'libs' section provide necessary functionality for other software on the computer. With very few exceptions, you should not need to explicitly install a package from this section; the package system will install them as required to fulfill dependencies."));
+-  section_descriptions["perl"]=transcode(_("Perl interpreter and libraries\n Packages in the 'perl' section provide the Perl programming language and many third-party libraries for it. Unless you are a Perl programmer, you don't need to install packages from this section explicitly; the package system will install them if they are required."));
+-  section_descriptions["python"]=transcode(_("Python interpreter and libraries\n Packages in the 'python' section provide the Python programming language and many third-party libraries for it. Unless you are a Python programmer, you don't need to install packages from this section explicitly; the package system will install them if they are required."));
+-  section_descriptions["mail"]=transcode(_("Programs to write, send, and route email messages\n Packages in the 'mail' section include mail readers, mail transport daemons, mailing list software, and spam filters, as well as various other software related to electronic mail."));
+-  section_descriptions["math"]=transcode(_("Numeric analysis and other mathematics-related software\n Packages in the 'math' section include calculators, languages for mathematical computation (similar to Mathematica), symbolic algebra packages, and programs to visualize mathematical objects."));
+-  section_descriptions["misc"]=transcode(_("Miscellaneous software\n Packages in the 'misc' section have too unusual a function to be classified."));
+-  section_descriptions["net"]=transcode(_("Programs to connect to and provide various services\n Packages in the 'net' section include clients and servers for many protocols, tools to manipulate and debug low-level network protocols, IM systems, and other network-related software."));
+-  section_descriptions["news"]=transcode(_("Usenet clients and servers\n Packages in the 'news' section are related to the Usenet distributed news system.  They include news readers and news servers."));
+-  section_descriptions["oldlibs"]=transcode(_("Obsolete libraries\n Packages in the 'oldlibs' section are obsolete and should not be used by new software.  They are provided for compatibility reasons, or because software distributed by Debian still requires them.\n .\n With very few exceptions, you should not need to explicitly install a package from this section; the package system will install them as required to fulfill dependencies."));
+-  section_descriptions["otherosfs"]=transcode(_("Emulators and software to read foreign filesystems\n Packages in the 'otherosfs' section emulate hardware and operating systems and provide tools for transferring data between different operating systems and hardware platforms. (for instance, utilities to read DOS floppies, and utilities to communicate with Palm Pilots)\n .\n It is worth noting that CD burning software is included in THIS section."));
+-  section_descriptions["science"]=transcode(_("Software for scientific work\n Packages in the 'science' section include tools for astronomy, biology, and chemistry, as well as other science-related software."));
+-  section_descriptions["shells"]=transcode(_("Command shells and alternative console environments\n Packages in the 'shells' section include programs providing a command-line interface."));
+-  section_descriptions["sound"]=transcode(_("Utilities to play and record sound\n Packages in the 'sound' section include sound players, recorders, and encoders for many formats, mixers and volume controls, MIDI sequencers and programs to generate musical notation, drivers for sound hardware, and sound processing software."));
+-  section_descriptions["tex"]=transcode(_("The TeX typesetting system\n Packages in the 'tex' section are related to TeX, a system for producing high-quality typeset output.  They include TeX itself, TeX packages, editors designed for TeX, utilities to convert TeX and TeX output files to various formats, TeX fonts, and other software related to TeX."));
+-  section_descriptions["text"]=transcode(_("Text processing utilities\n Packages in the 'text' section include text filters and processors, spelling checkers, dictionary programs, utilities to convert between character encodings and text file formats (eg, Unix and DOS), text formatters and pretty-printers, and other software which operates on plain text."));
+-  section_descriptions["utils"]=transcode(_("Various system utilities\n Packages in the 'utils' section are utilities whose purpose is too unique to be classified."));
+-  section_descriptions["web"]=transcode(_("Web browsers, servers, proxies, and other tools\n Packages in the 'web' section include Web browsers, Web servers and proxies, software to write CGI scripts or Web-based programs, pre-written Web-based programs, and other software related to the World Wide Web."));
+-  section_descriptions["x11"]=transcode(_("The X window system and related software\n Packages in the 'x11' section include the core packages for the X window system, window managers, utility programs for X, and miscellaneous programs with an X GUI which were placed here because they didn't fit anywhere else."));
+-
+-  section_descriptions["contrib"]=transcode(_("Programs which depend on software not in Debian\n Packages in the 'contrib' section are not part of Debian.\n .\n These packages are Free Software, but they depend on software which is not part of Debian.  This may be because it is not Free Software, but is packaged in the non-free section of the archive, because Debian cannot distribute it at all, or (in rare cases) because no-one has packaged it yet.\n .\n For more information about what Debian considers to be Free Software, see http://www.debian.org/social_contract#guidelines"));
+-  section_descriptions["main"]=transcode(_("The main Debian archive\n The Debian distribution consists of packages from the 'main' section. Every package in 'main' is Free Software.\n .\n For more information about what Debian considers to be Free Software, see http://www.debian.org/social_contract#guidelines"));
+-  section_descriptions["non-US"]=transcode(_("Programs stored outside the US due to export controls\n Packages in 'non-US' likely contain cryptography; a few implement patented algorithms. Because of this, they cannot be exported from the United States, and hence are stored on a server in the \"free world\".\n .\n Note: the Debian Project is currently merging cryptographic software into the US-based archives after consulting with legal experts about recent changes in export policies. Most packages which were formerly found in this section, therefore, are now in 'main'."));
+-  section_descriptions["non-free"]=transcode(_("Programs which are not free software\n Packages in the 'non-free' section are not part of Debian.\n .\n These packages fail to meet one or more of the requirements of the Debian Free Software Guidelines (see below). You should read the license of programs in this section to be sure that you are allowed to use them in the way you intend.\n .\n For more information about what Debian considers to be Free Software, see http://www.debian.org/social_contract#guidelines"));
+-
+   section_descriptions["virtual"]=transcode(_("Virtual packages\n These packages do not exist; they are names other packages use to require or provide some functionality."));
+ 
+   already_done=true;
+@@ -212,25 +165,18 @@ void pkg_grouppolicy_section::add_package(const pkgCache::PkgIterator &pkg,
+ 					  pkg_subtree *root)
+ {
+   const char *section=pkg.VersionList().Section();
+-  const char *name=pkg.Name();
+   bool maypassthrough=false; // FIXME: HACK!
+ 
+-  if(name[0] == 't' && name[1] == 'a' && name[2] == 's' && name[3] == 'k' && name[4] == '-')
+-    {
+-      maypassthrough=true;
+-      section=split_mode!=pkg_grouppolicy_section_factory::split_none?_("Tasks/Tasks"):_("Tasks");
+-    }
+-
+   if(!section)
+     {
+       maypassthrough=true;
+-      section=split_mode!=pkg_grouppolicy_section_factory::split_none?_("Unknown/Unknown"):_("Unknown");
++      section=_("Unknown");
+     }
+ 
+   if(pkg.VersionList().end())
+     {
+       maypassthrough=true;
+-      section=split_mode!=pkg_grouppolicy_section_factory::split_none?_("virtual/virtual"):_("virtual");
++      section=_("virtual");
+     }
+ 
+   const char *split=strchr(section, '/');
+@@ -241,13 +187,13 @@ void pkg_grouppolicy_section::add_package(const pkgCache::PkgIterator &pkg,
+   if(split_mode==pkg_grouppolicy_section_factory::split_none)
+     tag=section;
+   else if(split_mode==pkg_grouppolicy_section_factory::split_topdir)
+-    tag=(split?string(section,split-section):string(_("main")));
++    tag=(split?string(section,split-section):section);
+   else if(split_mode==pkg_grouppolicy_section_factory::split_subdir)
+     tag=subdir;
+ 
+   section_map::iterator found=sections.find(tag);
+ 
+-  if(maypassthrough && passthrough)
++  if((split == NULL || maypassthrough) && passthrough)
+     {
+       if(found==sections.end())
+ 	sections[tag].first=chain->instantiate(get_sig(), get_desc_sig());
+@@ -259,15 +205,10 @@ void pkg_grouppolicy_section::add_package(const pkgCache::PkgIterator &pkg,
+       if(found==sections.end())
+ 	{
+ 	  pkg_subtree *newtree;
+-	  string realtag=tag;
+ 
+-	  // Go by the last element of the section for multi-level sections.
+-	  if(tag.find('/')!=tag.npos)
+-	    realtag=string(tag, tag.rfind('/')+1);
+-
+-	  if(section_descriptions.find(realtag)!=section_descriptions.end())
++	  if(section_descriptions.find(tag)!=section_descriptions.end())
+ 	    {
+-	      wstring desc=section_descriptions[realtag];
++	      wstring desc=section_descriptions[tag];
+ 
+ 	      if(desc.find(L'\n')!=desc.npos)
+ 		newtree=new pkg_subtree(transcode(tag)+L" - "+wstring(desc, 0, desc.find('\n')),
+@@ -698,318 +639,6 @@ pkg_grouppolicy *pkg_grouppolicy_priority_factory::instantiate(pkg_signal *sig,
+ 
+ /*****************************************************************************/
+ 
+-// This class generates a pkg_subtree from a hierarchy
+-class pkg_hier_grouper:public pkg_hier::hierarchy_realizer, public sigc::trackable
+-{
+-  pkg_subtree *uncategorized;
+-  pkg_grouppolicy *uncategorized_policy;
+-
+-  pkg_grouppolicy_factory *chain;
+-
+-  pkg_signal *sig;
+-  desc_signal *desc_sig;
+-
+-  pkg_subtree *root;
+-
+-  typedef pair<pkg_grouppolicy *, pkg_subtree *> nodedata;
+-
+-  // This tracks the grouping policies we have created so that we can
+-  // destroy them.
+-  vector<nodedata *> data_out_there;
+-
+-  void handle_reload()
+-  {
+-    for(vector<nodedata *>::iterator i=data_out_there.begin();
+-     	i!=data_out_there.end();
+-     	++i)
+-      {
+-     	delete (*i)->first;
+-     	delete *i;
+-      }
+-    data_out_there.clear();
+-
+-    uncategorized=NULL;
+-    uncategorized_policy=NULL;
+-
+-    root=NULL;
+-
+-    reset_groupinfo();
+-  }
+-public:
+-  pkg_hier_grouper(pkg_hier *_hier,
+-		   pkg_grouppolicy_factory *_chain,
+-		   pkg_signal *_sig,
+-		   desc_signal *_desc_sig)
+-    :hierarchy_realizer(_hier), uncategorized(NULL),
+-     uncategorized_policy(NULL), chain(_chain), sig(_sig), desc_sig(_desc_sig),
+-     root(NULL)
+-  {
+-    hier_reloaded.connect(sigc::mem_fun(*this, &pkg_hier_grouper::handle_reload));
+-  }
+-
+-  ~pkg_hier_grouper()
+-  {
+-    delete uncategorized_policy;
+-    for(vector<nodedata *>::iterator i=data_out_there.begin();
+-     	i!=data_out_there.end();
+-     	++i)
+-      {
+-     	delete (*i)->first;
+-     	delete *i;
+-      }
+-  }
+-
+-  // HACK: the root has to be set each time
+-  void set_root(pkg_subtree *_root)
+-  {
+-    root=_root;
+-  }
+-
+-  void realize_item(pkg_hier::item *item, void *parent_data)
+-  {
+-    pkgCache::PkgIterator pkg=(*apt_cache_file)->FindPkg(item->name);
+-    nodedata *data=(nodedata *) parent_data;
+-
+-    if(data)
+-      data->first->add_package(pkg, data->second);
+-    else
+-      {
+-	if(!uncategorized)
+-	  {
+-	    uncategorized=new pkg_subtree(transcode(_("UNCATEGORIZED")));
+-	    uncategorized_policy=chain->instantiate(sig, desc_sig);
+-	    root->add_child(uncategorized);
+-	  }
+-
+-	uncategorized_policy->add_package(pkg, uncategorized);
+-      }
+-  }
+-
+-  void *realize_group(pkg_hier::group *group, void *parent_data)
+-  {
+-    nodedata *data=(nodedata *) parent_data;
+-
+-    pkg_subtree *newtree=new pkg_subtree(transcode(group->description));
+-    pkg_grouppolicy *newpolicy=chain->instantiate(sig, desc_sig);
+-
+-    nodedata *rval=new nodedata(newpolicy, newtree);
+-    data_out_there.push_back(rval);
+-
+-    if(data)
+-      data->second->add_child(newtree);
+-    else
+-      root->add_child(newtree);
+-
+-    return rval;
+-  }
+-};
+-
+-class pkg_grouppolicy_hier:public pkg_grouppolicy
+-{
+-  pkg_hier *hier;
+-  pkg_hier_grouper grouper;
+-
+-public:
+-  pkg_grouppolicy_hier(pkg_hier *_hier, pkg_grouppolicy_factory *_chain,
+-		       pkg_signal *_sig, desc_signal *_desc_sig)
+-    :pkg_grouppolicy(_sig, _desc_sig), hier(_hier),
+-     grouper(_hier, _chain, _sig, _desc_sig)
+-  {
+-  }
+-
+-  void add_package(const pkgCache::PkgIterator &pkg, pkg_subtree *root)
+-  {
+-    // HACK:
+-    grouper.set_root(root);
+-
+-    if(!hier->realize_item_up(pkg.Name(), &grouper))
+-      {
+-	pkg_hier::item tmp;
+-	tmp.name=pkg.Name();
+-
+-	// MORE HACK
+-	grouper.realize_item(&tmp, NULL);
+-      }
+-  }
+-};
+-
+-pkg_grouppolicy *pkg_grouppolicy_hier_factory::instantiate(pkg_signal *sig,
+-							   desc_signal *desc_sig)
+-{
+-  return new pkg_grouppolicy_hier(hier, chain, sig, desc_sig);
+-}
+-
+-pkg_grouppolicy_hier_factory::~pkg_grouppolicy_hier_factory()
+-{
+-  if(del_hier)
+-    delete hier;
+-  delete chain;
+-}
+-
+-/****************************************************************************/
+-
+-//  This class generates a "hierarchy" by grouping packages by Task, and
+-// optionally throwing away non-task packages.
+-
+-class pkg_grouppolicy_task:public pkg_grouppolicy
+-{
+-  /** The subtrees are indexed by Task. */
+-  typedef hash_map<string, pkg_subtree *> subtree_map;
+-
+-  /** A list of [task,description] pairs. */
+-  typedef vector<pair<string, wstring> > desclist;
+-
+-  // HACK: put all our stuff under this.
+-  pkg_subtree *tasks_subtree;
+-
+-  subtree_map task_children, section_children;
+-
+-  pkg_grouppolicy *chain;
+-
+-  static desclist task_section_descriptions;
+-  // Lifted from tasksel.  There are so few of them that it's not
+-  // worth using a hash_map.  Even a map is overkill.
+-
+-  static void init_section_descriptions();
+-public:
+-  pkg_grouppolicy_task(pkg_grouppolicy_factory *_chain,
+-		       pkg_signal *_sig, desc_signal *_desc_sig)
+-    :pkg_grouppolicy(_sig, _desc_sig), tasks_subtree(NULL),
+-     chain(_chain?_chain->instantiate(_sig, _desc_sig):NULL)
+-  {
+-    init_section_descriptions();
+-  }
+-
+-  ~pkg_grouppolicy_task() {delete chain;}
+-
+-  void add_package(const pkgCache::PkgIterator &pkg,
+-		   pkg_subtree *root);
+-};
+-
+-pkg_grouppolicy_task::desclist pkg_grouppolicy_task::task_section_descriptions;
+-
+-void pkg_grouppolicy_task::init_section_descriptions()
+-{
+-  static bool already_done=false;
+-
+-  if(already_done)
+-    return;
+-
+-  task_section_descriptions.push_back(pair<string,wstring>("user", transcode(dgettext("tasksel", "End-user"))));
+-  task_section_descriptions.push_back(pair<string,wstring>("server", transcode(dgettext("tasksel", "Servers"))));
+-  task_section_descriptions.push_back(pair<string,wstring>("devel", transcode(dgettext("tasksel", "Development"))));
+-  task_section_descriptions.push_back(pair<string,wstring>("l10n", transcode(dgettext("tasksel", "Localization"))));
+-  task_section_descriptions.push_back(pair<string,wstring>("hware", transcode(dgettext("tasksel", "Hardware Support"))));
+-  task_section_descriptions.push_back(pair<string,wstring>("misc", transcode(dgettext("tasksel", "Miscellaneous"))));
+-  task_section_descriptions.push_back(pair<string,wstring>("unknown", transcode(dgettext("tasksel", "Unrecognized tasks"))));
+-}
+-
+-/** Uses the fact that 0<=Relevance<=10 to encode Relevance as a character. */
+-class task_subtree:public pkg_subtree
+-{
+-  char relevance[2];
+-public:
+-  task_subtree(const std::wstring &_name, const std::wstring &_description,
+-	       desc_signal *_info_signal,
+-	       int _relevance)
+-    :pkg_subtree(_name, _description, _info_signal)
+-  {
+-    relevance[0]='z'-_relevance;
+-    relevance[1]=0;
+-  }
+-
+-  const char *tag() const {return relevance;}
+-};
+-
+-void pkg_grouppolicy_task::add_package(const pkgCache::PkgIterator &pkg,
+-				       pkg_subtree *root)
+-{
+-  list<string> *tasks=get_tasks(pkg);
+-
+-  eassert(tasks);
+-
+-  chain->add_package(pkg, root);
+-
+-  for(list<string>::iterator i=tasks->begin(); i!=tasks->end(); ++i)
+-    {
+-      subtree_map::iterator found=task_children.find(*i);
+-
+-      if(found==task_children.end())
+-	{
+-	  string section;
+-	  map<string,task>::iterator taskfound=task_list->find(*i);
+-	  pkg_subtree *newtree, *sectiontree;
+-
+-	  if(taskfound==task_list->end())
+-	    section="unknown";
+-	  else
+-	    {
+-	      if(!taskfound->second.keys_present())
+-		continue; // skip to the next task of this package.
+-
+-	      section=taskfound->second.section;
+-	    }
+-
+-	  if(!tasks_subtree)
+-	    {
+-	      tasks_subtree=new pkg_subtree(transcode(_("Tasks")),
+-					    transcode(_("\n Tasks are groups of packages which provide an easy way to select a predefined set of packages for a particular purpose.")), get_desc_sig());
+-	      root->add_child(tasks_subtree);
+-	    }
+-
+-	  subtree_map::iterator sectionfound=section_children.find(section);
+-	  if(sectionfound==section_children.end())
+-	    {
+-	      wstring sectiondesc=transcode(section, "ASCII");
+-
+-	      for(desclist::iterator j=task_section_descriptions.begin();
+-		  j!=task_section_descriptions.end();
+-		  ++j)
+-		if(j->first==section)
+-		  {
+-		    sectiondesc=j->second;
+-		    break;
+-		  }
+-
+-	      sectiontree=new pkg_subtree(sectiondesc);
+-	      section_children[section]=sectiontree;
+-	      tasks_subtree->add_child(sectiontree);
+-	    }
+-	  else
+-	    sectiontree=sectionfound->second;
+-
+-	  if(taskfound!=task_list->end())
+-	    newtree=new task_subtree(transcode(taskfound->second.shortdesc),
+-				     transcode(taskfound->second.longdesc),
+-				     get_desc_sig(),
+-				     taskfound->second.relevance);
+-	  else
+-	    newtree=new task_subtree(transcode(*i), L"",
+-				     get_desc_sig(), 5);
+-
+-	  task_children[*i]=newtree;
+-
+-	  sectiontree->add_child(newtree);
+-
+-	  newtree->add_child(new pkg_item(pkg, get_sig()));
+-	}
+-      else
+-	found->second->add_child(new pkg_item(pkg, get_sig()));
+-    }
+-}
+-
+-pkg_grouppolicy *pkg_grouppolicy_task_factory::instantiate(pkg_signal *sig,
+-							   desc_signal *desc_sig)
+-{
+-  return new pkg_grouppolicy_task(chain, sig, desc_sig);
+-}
+-
+-pkg_grouppolicy_task_factory::~pkg_grouppolicy_task_factory()
+-{
+-  delete chain;
+-}
+-
+-
+ class pkg_grouppolicy_matchers : public pkg_grouppolicy
+ {
+ public:
+@@ -1178,261 +807,3 @@ pkg_grouppolicy_matchers_factory :: ~pkg_grouppolicy_matchers_factory()
+     delete i->matcher;
+   delete chain;
+ }
+-
+-
+-
+-
+-
+-class pkg_grouppolicy_tag : public pkg_grouppolicy
+-{
+-  pkg_grouppolicy_factory *chain;
+-
+-  string facet;
+-
+-  typedef hash_map<string, pair<pkg_grouppolicy *, pkg_subtree *> > childmap;
+-
+-  childmap children;
+-public:
+-  pkg_grouppolicy_tag(const string &_facet, pkg_grouppolicy_factory *_chain,
+-		      pkg_signal *sig, desc_signal *desc_sig)
+-    :pkg_grouppolicy(sig, desc_sig), chain(_chain), facet(_facet)
+-  {
+-  }
+-
+-  virtual void add_package(const pkgCache::PkgIterator &pkg,
+-			   pkg_subtree *root)
+-  {
+-    const set<tag> *tags = get_tags(pkg);
+-    for(set<tag>::const_iterator ti = tags->begin();
+-	ti != tags->end(); ++ti)
+-      {
+-	tag::const_iterator j = ti->begin();
+-	if(j == ti->end())
+-	  continue;
+-
+-	string thisfacet = *j;
+-
+-	if(thisfacet != facet)
+-	  continue;
+-
+-	++j;
+-	if(j == ti->end())
+-	  continue;
+-
+-	string tagname = *j;
+-	childmap::const_iterator found =
+-	  children.find(tagname);
+-
+-	pkg_subtree *subtree = NULL;
+-	pkg_grouppolicy *subpolicy = NULL;
+-
+-	if(found == children.end())
+-	  {
+-	    string desc = tag_description(ti->str());
+-	    string shortdesc(desc, 0, desc.find('\n'));
+-
+-	    subtree = new pkg_subtree(swsprintf(L"%s - %s",
+-						tagname.c_str(),
+-						shortdesc.c_str()),
+-				      transcode(desc),
+-				      get_desc_sig());
+-	    root->add_child(subtree);
+-	    subpolicy = chain->instantiate(get_sig(),
+-					   get_desc_sig());
+-
+-	    children[tagname] = pair<pkg_grouppolicy *, pkg_subtree *>(subpolicy, subtree);
+-	  }
+-	else
+-	  {
+-	    subpolicy = found->second.first;
+-	    subtree = found->second.second;
+-	  }
+-
+-	subpolicy->add_package(pkg, subtree);
+-      }
+-  }
+-
+-  ~pkg_grouppolicy_tag()
+-  {
+-    // Delete the subpolicies.
+-    for(childmap::const_iterator i = children.begin();
+-	i != children.end(); ++i)
+-      delete i->second.first;
+-  }
+-};
+-
+-pkg_grouppolicy *pkg_grouppolicy_tag_factory::instantiate(pkg_signal *pkg_sig,
+-							  desc_signal *desc_sig)
+-{
+-  return new pkg_grouppolicy_tag(facet, chain, pkg_sig, desc_sig);
+-}
+-
+-pkg_grouppolicy_tag_factory::~pkg_grouppolicy_tag_factory()
+-{
+-  delete chain;
+-}
+-
+-
+-
+-
+-
+-class pkg_grouppolicy_facet_tag : public pkg_grouppolicy
+-{
+-  pkg_grouppolicy_factory *chain;
+-
+-  typedef hash_map<string, pair<pkg_grouppolicy *, pkg_subtree *> > tagmap;
+-
+-  typedef hash_map<string, pair<tagmap *, pkg_subtree *> > facetmap;
+-
+-  pkg_subtree *untagged_tree;
+-  pkg_grouppolicy *untagged_policy;
+-
+-  facetmap children;
+-public:
+-  pkg_grouppolicy_facet_tag(pkg_grouppolicy_factory *_chain,
+-			    pkg_signal *pkg_sig,
+-			    desc_signal *desc_sig)
+-    :pkg_grouppolicy(pkg_sig, desc_sig),
+-     chain(_chain),
+-     untagged_tree(NULL),
+-     untagged_policy(NULL)
+-  {
+-  }
+-
+-
+-  virtual void add_package(const pkgCache::PkgIterator &pkg,
+-			   pkg_subtree *root)
+-  {
+-    const set<tag> *tags = get_tags(pkg);
+-
+-    // Put all untagged, non-virtual packages into a separate list.
+-    if(tags->empty() && !pkg.VersionList().end())
+-      {
+-	if(untagged_tree == NULL)
+-	  {
+-	    eassert(untagged_policy == NULL);
+-
+-	    untagged_tree = new pkg_subtree(transcode(_("TAGLESS PACKAGES")),
+-					    transcode(_("\n These packages have not yet been classified in debtags.")),
+-					    get_desc_sig());
+-	    root->add_child(untagged_tree);
+-
+-	    untagged_policy = chain->instantiate(get_sig(), get_desc_sig());
+-	  }
+-
+-	untagged_policy->add_package(pkg, untagged_tree);
+-      }
+-
+-    for(set<tag>::const_iterator ti = tags->begin();
+-	ti != tags->end(); ++ti)
+-      {
+-	tag::const_iterator j = ti->begin();
+-
+-	eassert(j != ti->end());
+-
+-	string thisfacet = *j;
+-
+-	if(j != ti->end())
+-	  ++j;
+-
+-	string thistag;
+-
+-	if(j == ti->end())
+-	  thistag = _("MISSING TAG");
+-	else
+-	  thistag = *j;
+-
+-	facetmap::const_iterator facetfound =
+-	  children.find(thisfacet);
+-
+-	tagmap *tagchildren = NULL;
+-	pkg_subtree *tagtree = NULL;
+-
+-	if(facetfound == children.end())
+-	  {
+-	    string desc = facet_description(thisfacet);
+-	    string shortdesc(desc, 0, desc.find('\n'));
+-
+-	    if(!shortdesc.empty())
+-	      tagtree = new pkg_subtree(swsprintf(L"%s - %s",
+-						  thisfacet.c_str(),
+-						  shortdesc.c_str()),
+-					transcode(desc),
+-					get_desc_sig());
+-	    else
+-	      tagtree = new pkg_subtree(transcode(thisfacet),
+-					transcode(desc),
+-					get_desc_sig());
+-	    root->add_child(tagtree);
+-	    tagchildren = new tagmap;
+-
+-	    children[thisfacet] = pair<tagmap *, pkg_subtree *>(tagchildren, tagtree);
+-	  }
+-	else
+-	  {
+-	    tagchildren = facetfound->second.first;
+-	    tagtree = facetfound->second.second;
+-	  }
+-
+-	tagmap::const_iterator tagfound =
+-	  tagchildren->find(thistag);
+-
+-	pkg_grouppolicy *subpolicy = NULL;
+-	pkg_subtree *subtree = NULL;
+-
+-	if(tagfound == tagchildren->end())
+-	  {
+-	    string desc = tag_description(ti->str());
+-	    string shortdesc(desc, 0, desc.find('\n'));
+-
+-	    if(!shortdesc.empty())
+-	      subtree = new pkg_subtree(swsprintf(L"%s - %s",
+-						  thistag.c_str(),
+-						  shortdesc.c_str()),
+-					transcode(desc),
+-					get_desc_sig());
+-	    else
+-	      subtree = new pkg_subtree(transcode(thistag),
+-					transcode(desc),
+-					get_desc_sig());
+-
+-	    tagtree->add_child(subtree);
+-	    subpolicy = chain->instantiate(get_sig(), get_desc_sig());
+-
+-	    (*tagchildren)[thistag] = pair<pkg_grouppolicy *, pkg_subtree *>(subpolicy, subtree);
+-	  }
+-	else
+-	  {
+-	    subpolicy = tagfound->second.first;
+-	    subtree = tagfound->second.second;
+-	  }
+-
+-	subpolicy->add_package(pkg, subtree);
+-      }
+-  }
+-
+-  ~pkg_grouppolicy_facet_tag()
+-  {
+-    for(facetmap::const_iterator i = children.begin();
+-	i != children.end(); ++i)
+-      {
+-	for(tagmap::const_iterator j = i->second.first->begin();
+-	    j != i->second.first->end(); ++j)
+-	  delete j->second.first;
+-
+-	delete i->second.first;
+-      }
+-  }
+-};
+-
+-pkg_grouppolicy *
+-pkg_grouppolicy_facet_tag_factory::instantiate(pkg_signal *sig,
+-					       desc_signal *desc_sig)
+-{
+-  return new pkg_grouppolicy_facet_tag(chain, sig, desc_sig);
+-}
+-
+-pkg_grouppolicy_facet_tag_factory::~pkg_grouppolicy_facet_tag_factory()
+-{
+-  delete chain;
+-}
+diff --git a/src/pkg_grouppolicy.h b/src/pkg_grouppolicy.h
+index 8c61343..4b2edfb 100644
+--- a/src/pkg_grouppolicy.h
++++ b/src/pkg_grouppolicy.h
+@@ -216,49 +216,6 @@ public:
+   {delete chain;}
+ };
+ 
+-class pkg_hier;
+-
+-// Groups by a 'hierarchy' as described in generic/README.hier
+-class pkg_grouppolicy_hier_factory:public pkg_grouppolicy_factory
+-{
+-  // This is deleted with the factory iff del_hier==true.
+-  pkg_hier *hier;
+-
+-  pkg_grouppolicy_factory *chain;
+-
+-  // If true, delete our hierarchy object when we are destroyed.
+-  bool del_hier;
+-public:
+-  pkg_grouppolicy_hier_factory(pkg_hier *_hier,
+-			       bool _del_hier,
+-			       pkg_grouppolicy_factory *_chain)
+-    :hier(_hier), chain(_chain), del_hier(_del_hier)
+-  {
+-  }
+-
+-  pkg_grouppolicy *instantiate(pkg_signal *sig,
+-			       desc_signal *_desc_sig);
+-
+-  virtual ~pkg_grouppolicy_hier_factory();
+-};
+-
+-// Groups packages by task; if they are not in any task, they may be
+-// discarded (based on the value of "discard")
+-class pkg_grouppolicy_task_factory:public pkg_grouppolicy_factory
+-{
+-  pkg_grouppolicy_factory *chain;
+-public:
+-  pkg_grouppolicy_task_factory(pkg_grouppolicy_factory *_chain)
+-    :chain(_chain)
+-  {
+-  }
+-
+-  pkg_grouppolicy *instantiate(pkg_signal *sig,
+-			       desc_signal *_desc_sig);
+-
+-  virtual ~pkg_grouppolicy_task_factory();
+-};
+-
+ // Groups packages using the given list of matchers/tree names.  Match
+ // results can be substituted into tree names using \N notation.
+ class pkg_grouppolicy_matchers_factory:public pkg_grouppolicy_factory
+@@ -293,39 +250,4 @@ public:
+   ~pkg_grouppolicy_matchers_factory();
+ };
+ 
+-/** Groups packages by their tags within a single facet. */
+-class pkg_grouppolicy_tag_factory : public pkg_grouppolicy_factory
+-{
+-  pkg_grouppolicy_factory *chain;
+-
+-  std::string facet;
+-public:
+-  pkg_grouppolicy_tag_factory(const std::string &_facet,
+-			      pkg_grouppolicy_factory *_chain)
+-    :chain(_chain), facet(_facet)
+-  {
+-  }
+-
+-  pkg_grouppolicy *instantiate(pkg_signal *sig,
+-			       desc_signal *desc_sig);
+-
+-  ~pkg_grouppolicy_tag_factory();
+-};
+-
+-/** Groups packages by their facets and their tags. */
+-class pkg_grouppolicy_facet_tag_factory : public pkg_grouppolicy_factory
+-{
+-  pkg_grouppolicy_factory *chain;
+-public:
+-  pkg_grouppolicy_facet_tag_factory(pkg_grouppolicy_factory *_chain)
+-    :chain(_chain)
+-  {
+-  }
+-
+-  pkg_grouppolicy *instantiate(pkg_signal *sig,
+-			       desc_signal *desc_sig);
+-
+-  ~pkg_grouppolicy_facet_tag_factory();
+-};
+-
+ #endif
+diff --git a/src/pkg_info_screen.cc b/src/pkg_info_screen.cc
+index f76c01e..f470e57 100644
+--- a/src/pkg_info_screen.cc
++++ b/src/pkg_info_screen.cc
+@@ -79,7 +79,7 @@ void pkg_grouppolicy_info::setup_package_info(const pkgCache::PkgIterator &pkg,
+       pkgRecords::Parser &rec=apt_package_records->Lookup(ver.FileList());
+ 
+       std::wstring desc(get_long_description(ver));
+-      std::wstring shortdesc(desc, 0, desc.find(L'\n'));
++      std::wstring shortdesc(get_short_description(ver));
+ 
+       vector<fragment*> frags;
+ 
+@@ -95,10 +95,6 @@ void pkg_grouppolicy_info::setup_package_info(const pkgCache::PkgIterator &pkg,
+ 				    _("Description: "), shortdesc.c_str())));
+       frags.push_back(indentbox(2, 2, make_desc_fragment(desc)));
+ 
+-      fragment *tags = make_tags_fragment(pkg);
+-      if(tags != NULL)
+-	frags.push_back(fragf("%n%F", tags));
+-
+       // Can I use something other than a clipbox below?
+ 
+       if((pkg->Flags&pkgCache::Flag::Essential)==pkgCache::Flag::Essential ||
+diff --git a/src/pkg_item.cc b/src/pkg_item.cc
+index d8b42f9..0279e43 100644
+--- a/src/pkg_item.cc
++++ b/src/pkg_item.cc
+@@ -27,11 +27,9 @@
+ #include <vscreen/transcode.h>
+ #include <vscreen/vs_util.h>
+ 
+-#include "edit_pkg_hier.h"
+ #include "pkg_columnizer.h"
+ #include "pkg_item.h"
+ #include "ui.h"
+-#include "view_changelog.h"
+ #include "vs_progress.h"
+ 
+ #include <generic/apt/apt.h>
+@@ -181,16 +179,6 @@ void pkg_item::remove(undo_group *undo)
+     }
+ }
+ 
+-// No "do_purge" because purge was always idempotent.
+-void pkg_item::purge(undo_group *undo)
+-{
+-  if((package->Flags&pkgCache::Flag::Essential)==pkgCache::Flag::Essential ||
+-     (package->Flags&pkgCache::Flag::Important)==pkgCache::Flag::Important)
+-    confirm_delete_essential(package, false);
+-  else
+-    (*apt_cache_file)->mark_delete(package, true, false, undo);
+-}
+-
+ void pkg_item::reinstall(undo_group *undo)
+ {
+   if(!package.CurrentVer().end())
+@@ -227,11 +215,6 @@ void pkg_item::show_information()
+   insert_main_widget(w, menulabel, "", tablabel);
+ }
+ 
+-void pkg_item::show_changelog()
+-{
+-   view_changelog(visible_version());
+-}
+-
+ style pkg_item::get_highlight_style()
+ {
+   return vs_treeitem::get_normal_style() + pkg_style(package, true);
+@@ -351,9 +334,6 @@ bool pkg_item::dispatch_key(const key &k, vs_tree *owner)
+     }
+   else if(bindings->key_matches(k, "InfoScreen"))
+     show_information();
+-  else if(bindings->key_matches(k, "Changelog") &&
+-	  !visible_version().end())
+-    show_changelog();
+   else if(bindings->key_matches(k, "InstallSingle"))
+     {
+       if((*apt_cache_file)[package].CandidateVerIter(*apt_cache_file).end())
+@@ -399,60 +379,6 @@ bool pkg_item::dispatch_key(const key &k, vs_tree *owner)
+ 
+       vscreen_resume();
+     }
+-  else if(bindings->key_matches(k, "DpkgReconfigure"))
+-    // Don't bother with my internal su-to-root stuff here, since I don't
+-    // need to touch the package lists in the subprocess.
+-    {
+-      // Try to do *something*.
+-      const char *sucmd=NULL;
+-
+-      if(getuid()==0)
+-	sucmd="dpkg-reconfigure '%s'";
+-      else if(access("/usr/sbin/su-to-root", X_OK)==0)
+-	sucmd="/usr/sbin/su-to-root -c \"/usr/sbin/dpkg-reconfigure '%s'\"";
+-      else if(access("/bin/su", X_OK)==0)
+-	sucmd="/bin/su -c \"/usr/sbin/dpkg-reconfigure '%s'\"";
+-      else
+-	popup_widget(vs_dialog_ok(text_fragment(_("You are not root and I cannot find any way to become root.  To reconfigure this package, install the menu package, the login package, or run aptitude as root."))));
+-
+-      if(sucmd)
+-	{
+-	  vscreen_suspend();
+-
+-	  apt_cache_file->ReleaseLock();
+-
+-	  printf(_("Reconfiguring %s\n"), package.Name());
+-
+-	  char buf[512];
+-	  if(sucmd)
+-	    {
+-	      snprintf(buf, 512, sucmd,
+-		       package.Name());
+-
+-	      system(buf);
+-
+-	      cerr<<_("Press return to continue.\n");
+-	      getchar();
+-
+-	      vscreen_resume();
+-	    }
+-
+-	  vs_progress_ref p = gen_progress_bar();
+-	  apt_reload_cache(p.unsafe_get_ref(), true);
+-	  p->destroy();
+-	}
+-    }
+-  else if(bindings->key_matches(k, "EditHier"))
+-    {
+-      vs_hier_editor_ref e=vs_hier_editor::create();
+-      e->set_package(package, visible_version());
+-
+-      // FIXME: better title
+-      add_main_widget(e, _("Hierarchy editor"), "", _("Hierarchy Editor"));
+-
+-      e->connect_key("Quit", &global_bindings,
+-		     sigc::mem_fun(*e.unsafe_get_ref(), &vscreen_widget::destroy));
+-    }
+   else
+     return pkg_tree_node::dispatch_key(k, owner);
+ 
+@@ -541,17 +467,6 @@ bool pkg_item::package_forbid()
+   return true;
+ }
+ 
+-bool pkg_item::package_changelog_enabled()
+-{
+-  return true;
+-}
+-
+-bool pkg_item::package_changelog()
+-{
+-  show_changelog();
+-  return true;
+-}
+-
+ bool pkg_item::package_information_enabled()
+ {
+   return true;
+diff --git a/src/pkg_item.h b/src/pkg_item.h
+index 934ec2b..1e4a959 100644
+--- a/src/pkg_item.h
++++ b/src/pkg_item.h
+@@ -61,7 +61,6 @@ public:
+   virtual void hold(undo_group *undo);
+   virtual void keep(undo_group *undo);
+   virtual void remove(undo_group *undo);
+-  virtual void purge(undo_group *undo);
+   virtual void reinstall(undo_group *undo);
+   virtual void set_auto(bool isauto, undo_group *undo);
+   virtual void forbid_upgrade(undo_group *undo);
+@@ -72,7 +71,6 @@ public:
+   virtual style get_highlight_style();
+   virtual style get_normal_style();
+ 
+-  void show_changelog();
+   void show_information();
+ 
+   const pkgCache::PkgIterator &get_package() const;
+@@ -92,8 +90,6 @@ public:
+   // Menu redirections:
+   bool package_forbid_enabled();
+   bool package_forbid();
+-  bool package_changelog_enabled();
+-  bool package_changelog();
+   bool package_information_enabled();
+   bool package_information();
+ };
+diff --git a/src/pkg_node.cc b/src/pkg_node.cc
+index 6a88f5a..7387e2a 100644
+--- a/src/pkg_node.cc
++++ b/src/pkg_node.cc
+@@ -54,8 +54,6 @@ bool pkg_tree_node::dispatch_key(const key &k, vs_tree *owner)
+     hold(grp);
+   else if(bindings->key_matches(k, "Keep"))
+     keep(grp);
+-  else if(bindings->key_matches(k, "Purge"))
+-    purge(grp);
+   else if(bindings->key_matches(k, "Reinstall"))
+     reinstall(grp);
+   else if(bindings->key_matches(k, "SetAuto"))
+@@ -114,11 +112,6 @@ bool pkg_tree_node::package_remove()
+   return package_action(&pkg_tree_node::remove);
+ }
+ 
+-bool pkg_tree_node::package_purge()
+-{
+-  return package_action(&pkg_tree_node::purge);
+-}
+-
+ bool pkg_tree_node::package_keep()
+ {
+   return package_action(&pkg_tree_node::keep);
+diff --git a/src/pkg_node.h b/src/pkg_node.h
+index 6bde970..fbdc7b3 100644
+--- a/src/pkg_node.h
++++ b/src/pkg_node.h
+@@ -42,7 +42,6 @@ public:
+   virtual void hold(undo_group *undo)=0;
+   virtual void keep(undo_group *undo)=0;
+   virtual void remove(undo_group *undo)=0;
+-  virtual void purge(undo_group *undo)=0;
+   virtual void reinstall(undo_group *undo)=0;
+   // set_auto is idempotent!  No stupid toggling stuff.
+   virtual void set_auto(bool isauto, undo_group *undo)=0;
+@@ -61,7 +60,6 @@ public:
+   bool package_enabled();
+   bool package_install();
+   bool package_remove();
+-  bool package_purge();
+   bool package_hold();
+   bool package_keep();
+   bool package_mark_auto();
+diff --git a/src/pkg_subtree.cc b/src/pkg_subtree.cc
+index 67486be..d9b25ab 100644
+--- a/src/pkg_subtree.cc
++++ b/src/pkg_subtree.cc
+@@ -89,16 +89,6 @@ void pkg_subtree::remove(undo_group *undo)
+   (*apt_cache_file)->end_action_group(undo);
+ }
+ 
+-void pkg_subtree::purge(undo_group *undo)
+-{
+-  (*apt_cache_file)->begin_action_group();
+-
+-  for(child_iterator i=get_children_begin(); i!=get_children_end(); i++)
+-    (*i)->purge(undo);
+-
+-  (*apt_cache_file)->end_action_group(undo);
+-}
+-
+ void pkg_subtree::reinstall(undo_group *undo)
+ {
+   (*apt_cache_file)->begin_action_group();
+diff --git a/src/pkg_subtree.h b/src/pkg_subtree.h
+index dc29c43..c1ec282 100644
+--- a/src/pkg_subtree.h
++++ b/src/pkg_subtree.h
+@@ -58,7 +58,6 @@ public:
+   virtual void hold(undo_group *undo);
+   virtual void keep(undo_group *undo);
+   virtual void remove(undo_group *undo);
+-  virtual void purge(undo_group *undo);
+   virtual void reinstall(undo_group *undo);
+   virtual void set_auto(bool isauto, undo_group *undo);
+ 
+diff --git a/src/pkg_ver_item.cc b/src/pkg_ver_item.cc
+index 45a5e8f..fa77fd1 100644
+--- a/src/pkg_ver_item.cc
++++ b/src/pkg_ver_item.cc
+@@ -29,7 +29,6 @@
+ #include "pkg_ver_item.h"
+ #include "pkg_sortpolicy.h"
+ #include "ui.h"
+-#include "view_changelog.h"
+ #include "vs_progress.h"
+ 
+ #include <generic/apt/apt.h>
+@@ -50,6 +49,8 @@
+ 
+ using namespace std;
+ 
++#define pkgCheckDep _system->checkDep
++
+ class pkg_ver_columnizer:public pkg_item::pkg_columnizer
+ {
+   bool show_pkg_name;
+@@ -254,7 +255,7 @@ column_disposition pkg_ver_columnizer::setup_column(int type)
+ 	else if(ver.VerStr() == estate.forbidver)
+ 	  return column_disposition("F", 0);
+ 	else if(state.Delete())
+-	  return column_disposition((state.iFlags&pkgDepCache::Purge)?"p":"d", 0);
++	  return column_disposition("d", 0);
+ 	else if(state.InstBroken() && state.InstVerIter(*apt_cache_file)==ver)
+ 	  return column_disposition("B", 0);
+ 	else if(state.NewInstall())
+@@ -297,7 +298,7 @@ column_disposition pkg_ver_columnizer::setup_column(int type)
+ 	else if(ver.VerStr() == estate.forbidver)
+ 	  return column_disposition("forbidden version", 0);
+ 	else if(state.Delete())
+-	  return column_disposition((state.iFlags&pkgDepCache::Purge)?"p":"d", 0);
++	  return column_disposition("d", 0);
+ 	else if(state.InstBroken() && state.InstVerIter(*apt_cache_file)==ver)
+ 	  return column_disposition(_("broken"), 0);
+ 	else if(state.NewInstall())
+@@ -621,12 +622,6 @@ void pkg_ver_item::keep(undo_group *undo)
+   // Do nothing for now.
+ }
+ 
+-void pkg_ver_item::purge(undo_group *undo)
+-{
+-  if(version==version.ParentPkg().CurrentVer())
+-    (*apt_cache_file)->mark_delete(version.ParentPkg(), true, false, undo);
+-}
+-
+ void pkg_ver_item::reinstall(undo_group *undo)
+ {
+   if(version.ParentPkg().CurrentVer()==version)
+@@ -708,11 +703,6 @@ bool pkg_ver_item::dispatch_key(const key &k, vs_tree *owner)
+       show_information();
+       return true;
+     }
+-  else if(bindings->key_matches(k, "Changelog"))
+-    {
+-      view_changelog(version);
+-      return true;
+-    }
+   else if(bindings->key_matches(k, "ForbidUpgrade"))
+     {
+       undo_group *grp=new apt_undo_group;
+@@ -790,17 +780,6 @@ bool pkg_ver_item::package_forbid()
+   return true;
+ }
+ 
+-bool pkg_ver_item::package_changelog_enabled()
+-{
+-  return true;
+-}
+-
+-bool pkg_ver_item::package_changelog()
+-{
+-  view_changelog(get_version());
+-  return true;
+-}
+-
+ bool pkg_ver_item::package_information_enabled()
+ {
+   return true;
+diff --git a/src/pkg_ver_item.h b/src/pkg_ver_item.h
+index 2b84f2a..dc1d2e4 100644
+--- a/src/pkg_ver_item.h
++++ b/src/pkg_ver_item.h
+@@ -32,9 +32,13 @@
+ #include "pkg_grouppolicy.h"
+ #include "pkg_item_with_subtree.h"
+ 
+-#include <apt-pkg/version.h>
+ #include <apt-pkg/depcache.h>
+ #include <apt-pkg/pkgsystem.h>
++#include <apt-pkg/version.h>
++
++#ifndef HAVE_LIBAPT_PKG3
++#define pkgVersionCompare _system->versionCompare
++#endif
+ 
+ class pkg_ver_item:public pkg_tree_node
+ {
+@@ -66,7 +70,6 @@ public:
+   virtual void hold(undo_group *undo);
+   virtual void keep(undo_group *undo);
+   virtual void remove(undo_group *undo);
+-  virtual void purge(undo_group *undo);
+   virtual void reinstall(undo_group *undo);
+   virtual void set_auto(bool isauto, undo_group *undo);
+ 
+@@ -88,8 +91,6 @@ public:
+   // Menu redirections:
+   bool package_forbid_enabled();
+   bool package_forbid();
+-  bool package_changelog_enabled();
+-  bool package_changelog();
+   bool package_information_enabled();
+   bool package_information();
+ };
+diff --git a/src/pkg_view.cc b/src/pkg_view.cc
+index 681fb83..0ba09f6 100644
+--- a/src/pkg_view.cc
++++ b/src/pkg_view.cc
+@@ -22,7 +22,6 @@
+ #include "aptitude.h"
+ 
+ #include "desc_parse.h"
+-#include "edit_pkg_hier.h"
+ #include "menu_redirect.h"
+ #include "pkg_columnizer.h"
+ #include "reason_fragment.h"
+@@ -182,12 +181,6 @@ public:
+ 
+     fragment *frag=make_desc_fragment(newdesc);
+ 
+-    fragment *tags=make_tags_fragment(pkg);
+-    if(tags != NULL)
+-      tags = fragf("%n%n%F", tags);
+-    else
+-      tags = fragf("");
+-
+     fragment *untrusted_frag;
+ 
+     if(pkg.end() || ver.end())
+@@ -196,9 +189,9 @@ public:
+       untrusted_frag=make_untrusted_warning(ver);
+ 
+     if(untrusted_frag == NULL)
+-      set_fragment(fragf("%F%F", frag, tags));
++      set_fragment(fragf("%F", frag));
+     else
+-      set_fragment(fragf("%F%n%F%F", untrusted_frag, frag, tags));
++      set_fragment(fragf("%F%n%F", untrusted_frag, frag));
+   }
+ };
+ 
+@@ -216,7 +209,6 @@ typedef ref_ptr<pkg_description_widget> pkg_description_widget_ref;
+ // This is still rather gross, and a better way would be nice.
+ class info_area_multiplex:public vs_multiplex
+ {
+-  vs_hier_editor_ref editor;
+   pkg_description_widget_ref description;
+   vs_table_ref description_table;
+   vs_text_layout_ref reasons;
+@@ -234,13 +226,11 @@ class info_area_multiplex:public vs_multiplex
+   vs_widget_ref autoswitch;
+ 
+ protected:
+-  info_area_multiplex(const vs_hier_editor_ref &_editor,
+-		      const pkg_description_widget_ref &_description,
++  info_area_multiplex(const pkg_description_widget_ref &_description,
+ 		      const vs_table_ref &_description_table,
+ 		      const vs_text_layout_ref &_reasons,
+ 		      const vs_table_ref &_reasons_table)
+     :vs_multiplex(false),
+-     editor(_editor),
+      description(_description), description_table(_description_table),
+      reasons(_reasons), reasons_table(_reasons_table),
+      hadBreakage(false), autoswitch(NULL)
+@@ -251,14 +241,13 @@ protected:
+ 
+ public:
+   static ref_ptr<info_area_multiplex>
+-  create(const vs_hier_editor_ref &editor,
+-	 const pkg_description_widget_ref &description,
++  create(const pkg_description_widget_ref &description,
+ 	 const vs_table_ref &description_table,
+ 	 const vs_text_layout_ref &reasons,
+ 	 const vs_table_ref &reasons_table)
+   {
+     ref_ptr<info_area_multiplex>
+-      rval(new info_area_multiplex(editor, description, description_table,
++      rval(new info_area_multiplex(description, description_table,
+ 				   reasons, reasons_table));
+     rval->decref();
+     return rval;
+@@ -297,7 +286,6 @@ public:
+ 
+     description->set_package(pkg, ver);
+     reasons->set_fragment(reason_fragment(pkg, hasBreakage));
+-    editor->set_package(pkg, ver);
+ 
+     // autoswitch if a package is newly broken, or if we have just
+     // moved to a broken package.
+@@ -430,14 +418,12 @@ vs_widget_ref make_package_view(list<package_view_item> &format,
+ 	  break;
+ 	case PACKAGE_VIEW_DESCRIPTION:
+ 	  {
+-	    vs_hier_editor_ref e=vs_hier_editor::create();
+ 	    pkg_description_widget_ref w=pkg_description_widget::create();
+ 	    vs_text_layout_ref l=vs_text_layout::create();
+ 
+ 	    vs_table_ref wt=vs_table::create();
+ 	    vs_table_ref lt=vs_table::create();
+-	    info_area_multiplex_ref m=info_area_multiplex::create(e,
+-								  w, wt,
++	    info_area_multiplex_ref m=info_area_multiplex::create(w, wt,
+ 								  l, lt);
+ 	    vs_scrollbar_ref ws=vs_scrollbar::create(vs_scrollbar::VERTICAL);
+ 	    vs_scrollbar_ref ls=vs_scrollbar::create(vs_scrollbar::VERTICAL);
+@@ -451,9 +437,6 @@ vs_widget_ref make_package_view(list<package_view_item> &format,
+ 	    lt->add_widget_opts(l, 0, 0, 1, 1, vs_table::EXPAND | vs_table::FILL | vs_table::SHRINK, vs_table::EXPAND | vs_table::FILL | vs_table::SHRINK);
+ 	    lt->add_widget_opts(ls, 0, 1, 1, 1, vs_table::ALIGN_RIGHT, vs_table::EXPAND | vs_table::ALIGN_CENTER | vs_table::FILL);
+ 
+-	    // HACK: speaks for itself
+-	    vs_tree_ref thetree=mainwidget.dyn_downcast<vs_tree>();
+-
+ 	    i->widget=m;
+ 
+ 	    // Set up a null reason to start with.  (the package
+@@ -476,23 +459,7 @@ vs_widget_ref make_package_view(list<package_view_item> &format,
+ 	    mainwidget->connect_key("DescriptionCycle", &global_bindings,
+ 				    sigc::mem_fun(*m.unsafe_get_ref(),
+ 						  &info_area_multiplex::cycle));
+-	    mainwidget->connect_key("EditHier", &global_bindings,
+-				    sigc::mem_fun(*e.unsafe_get_ref(),
+-						  &vscreen_widget::show));
+-	    mainwidget->connect_key("EditHier", &global_bindings,
+-				    sigc::mem_fun(*m.unsafe_get_ref(),
+-						  &vscreen_widget::show));
+-	    mainwidget->connect_key("EditHier", &global_bindings,
+-				    sigc::bind(sigc::mem_fun(*rval.unsafe_get_ref(), &vs_table::focus_widget_bare),
+-					       m.weak_ref()));
+-
+-	    e->hidden_sig.connect(sigc::bind(sigc::mem_fun(*rval.unsafe_get_ref(), &vs_table::focus_widget_bare),
+-					     mainwidget.weak_ref()));
+-
+-	    if(thetree.valid())
+-	      e->commit_changes.connect(sigc::mem_fun(*thetree.unsafe_get_ref(), &vs_tree::line_down));
+ 
+-	    m->add_visible_widget(e, false);
+ 	    m->add_visible_widget(wt, true);
+ 	    m->add_visible_widget(lt, true);
+ 
+diff --git a/src/solution_dialog.cc b/src/solution_dialog.cc
+deleted file mode 100644
+index fc94cfc..0000000
+--- a/src/solution_dialog.cc
++++ /dev/null
+@@ -1,208 +0,0 @@
+-// solution_dialog.cc
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#include "solution_dialog.h"
+-#include "solution_fragment.h"
+-#include "ui.h"
+-
+-#include <aptitude.h>
+-
+-#include <vscreen/config/colors.h>
+-#include <vscreen/config/keybindings.h>
+-#include <vscreen/fragment.h>
+-#include <vscreen/vs_button.h>
+-#include <vscreen/vs_center.h>
+-#include <vscreen/vs_frame.h>
+-#include <vscreen/vs_scrollbar.h>
+-#include <vscreen/vs_table.h>
+-#include <vscreen/vs_text_layout.h>
+-#include <vscreen/vscreen.h>
+-
+-#include <generic/apt/apt.h>
+-#include <generic/apt/aptitude_resolver_universe.h>
+-#include <generic/apt/resolver_manager.h>
+-
+-#include <generic/problemresolver/exceptions.h>
+-#include <generic/problemresolver/solution.h>
+-
+-#include <sigc++/bind.h>
+-
+-typedef generic_solution<aptitude_universe> aptitude_solution;
+-
+-class solution_dialog:public vs_text_layout
+-{
+-  aptitude_solution last_sol;
+-
+-  void handle_cache_reload()
+-  {
+-    if(apt_cache_file)
+-      resman->state_changed.connect(sigc::mem_fun(*this, &solution_dialog::post_update));
+-
+-    update();
+-  }
+-
+-  void post_update()
+-  {
+-    vscreen_post_event(new slot_event(sigc::mem_fun(this, &solution_dialog::update)));
+-  }
+-
+-protected:
+-  solution_dialog()
+-  {
+-    if(apt_cache_file)
+-      resman->state_changed.connect(sigc::mem_fun(*this, &solution_dialog::post_update));
+-
+-    cache_closed.connect(sigc::mem_fun(*this, &solution_dialog::update));
+-    cache_reloaded.connect(sigc::mem_fun(*this, &solution_dialog::handle_cache_reload));
+-
+-    update();
+-  }
+-
+-public:
+-  static ref_ptr<solution_dialog> create()
+-  {
+-    ref_ptr<solution_dialog> rval(new solution_dialog);
+-    rval->decref();
+-    return rval;
+-  }
+-
+-  void update()
+-  {
+-    vs_widget_ref tmpref(this);
+-
+-    if(!apt_cache_file)
+-      {
+-	set_fragment(fragf("%s", _("The package cache is not available.")));
+-	last_sol.nullify();
+-	return;
+-      }
+-
+-    if(!resman->resolver_exists())
+-      {
+-	// This makes ASS-U-MPTIONS about how resolver_exists works.
+-	set_fragment(fragf("%s", _("No packages are broken.")));
+-	last_sol.nullify();
+-	return;
+-      }
+-
+-    resolver_manager::state state = resman->state_snapshot();
+-
+-    if(state.solutions_exhausted && state.generated_solutions == 0)
+-      {
+-	set_fragment(fragf("%s", _("No resolution found.")));
+-	return;
+-      }
+-
+-    if(state.selected_solution >= state.generated_solutions)
+-      {
+-	set_fragment(fragf("%s", _("Resolving dependencies...")));
+-	return;
+-      }
+-
+-    aptitude_solution sol = resman->get_solution(state.selected_solution, 0);
+-
+-    if(sol == last_sol)
+-      return;
+-
+-    last_sol=sol;
+-
+-    if(sol.get_actions().empty())
+-      set_fragment(fragf("%s", _("Internal error: unexpected null solution.")));
+-    else
+-      set_fragment(solution_fragment(sol));
+-  }
+-};
+-
+-typedef ref_ptr<solution_dialog> solution_dialog_ref;
+-
+-static void do_apply(vscreen_widget &wBare)
+-{
+-  vs_widget_ref w(&wBare);
+-
+-  do_apply_solution();
+-  w->destroy();
+-}
+-
+-vs_widget_ref make_solution_dialog()
+-{
+-  vs_table_ref t=vs_table::create();
+-  vs_widget_ref rval=vs_center::create(vs_frame::create(t));
+-
+-  vs_text_layout_ref display=solution_dialog::create();
+-  vs_scrollbar_ref scrl=vs_scrollbar::create(vs_scrollbar::VERTICAL);
+-
+-  display->location_changed.connect(sigc::mem_fun(scrl.unsafe_get_ref(), &vs_scrollbar::set_slider));
+-  scrl->scrollbar_interaction.connect(sigc::mem_fun(display.unsafe_get_ref(), &vs_text_layout::scroll));
+-
+-  t->add_widget_opts(display,
+-		     0, 0, 1, 1,
+-		     vs_table::EXPAND | vs_table::FILL | vs_table::SHRINK,
+-		     vs_table::EXPAND | vs_table::FILL | vs_table::SHRINK);
+-
+-  t->add_widget_opts(scrl,
+-		     0, 1, 1, 1,
+-		     vs_table::ALIGN_RIGHT,
+-		     vs_table::ALIGN_CENTER | vs_table::FILL | vs_table::SHRINK);
+-
+-  vs_table_ref bt=vs_table::create();
+-
+-  //t->set_bg(get_color("DefaultWidgetBackground")|A_REVERSE);
+-
+-  // TODO: for dialogs like this, I really should have support for
+-  // "wrapping" lines of buttons if they get too long, like fragments.
+-  vs_button_ref bprev  = vs_button::create(_("Previous"));
+-  vs_button_ref bnext  = vs_button::create(_("Next"));
+-  vs_button_ref bapply = vs_button::create(_("Apply"));
+-  vs_button_ref bclose = vs_button::create(_("Close"));
+-
+-  bprev->pressed.connect(sigc::ptr_fun(do_previous_solution));
+-  bnext->pressed.connect(sigc::ptr_fun(do_next_solution));
+-  bapply->pressed.connect(sigc::bind(sigc::ptr_fun(do_apply),
+-				     rval.weak_ref()));
+-  bclose->pressed.connect(sigc::mem_fun(rval.unsafe_get_ref(),
+-					&vscreen_widget::destroy));
+-
+-  rval->connect_key("ApplySolution", &global_bindings,
+-		    sigc::bind(sigc::ptr_fun(do_apply),
+-			       rval.weak_ref()));
+-
+-  bprev->set_bg_style(style_attrs_flip(A_REVERSE));
+-  bnext->set_bg_style(style_attrs_flip(A_REVERSE));
+-  bapply->set_bg_style(style_attrs_flip(A_REVERSE));
+-  bclose->set_bg_style(style_attrs_flip(A_REVERSE));
+-
+-  bt->add_widget_opts(bprev,
+-		     0, 0, 1, 1,
+-		     vs_table::FILL | vs_table::EXPAND, vs_table::FILL);
+-  bt->add_widget_opts(bnext,
+-		     0, 1, 1, 1,
+-		     vs_table::FILL | vs_table::EXPAND, vs_table::FILL);
+-  bt->add_widget_opts(bapply,
+-		     0, 2, 1, 1,
+-		     vs_table::FILL | vs_table::EXPAND, vs_table::FILL);
+-  bt->add_widget_opts(bclose,
+-		     0, 3, 1, 1,
+-		     vs_table::FILL | vs_table::EXPAND, vs_table::FILL);
+-
+-  t->add_widget_opts(bt, 1, 0, 1, 2,
+-		     vs_table::FILL | vs_table::EXPAND | vs_table::SHRINK,
+-		     vs_table::FILL);
+-
+-  return rval;
+-}
+diff --git a/src/solution_dialog.h b/src/solution_dialog.h
+deleted file mode 100644
+index d38a098..0000000
+--- a/src/solution_dialog.h
++++ /dev/null
+@@ -1,31 +0,0 @@
+-// solution_dialog.h                                 -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-//
+-// Display the current solution.
+-
+-#ifndef SOLUTION_DIALOG_H
+-#define SOLUTION_DIALOG_H
+-
+-class vscreen_widget;
+-template<class T> class ref_ptr;
+-typedef ref_ptr<vscreen_widget> vs_widget_ref;
+-
+-vs_widget_ref make_solution_dialog();
+-
+-#endif // SOLUTION_DIALOG_H
+diff --git a/src/solution_fragment.cc b/src/solution_fragment.cc
+deleted file mode 100644
+index b50b549..0000000
+--- a/src/solution_fragment.cc
++++ /dev/null
+@@ -1,303 +0,0 @@
+-// solution_fragment.cc
+-//
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#include "solution_fragment.h"
+-
+-#include <aptitude.h>
+-
+-#include <generic/apt/aptitude_resolver_universe.h>
+-
+-#include <generic/problemresolver/solution.h>
+-
+-#include <generic/util/util.h>
+-
+-#include <vscreen/fragment.h>
+-#include <vscreen/transcode.h>
+-
+-#include <vector>
+-
+-typedef generic_solution<aptitude_universe> aptitude_solution;
+-
+-using namespace std;
+-
+-string archives_text(const pkgCache::VerIterator &ver)
+-{
+-  string rval;
+-
+-  bool is_first = true;
+-
+-  for(pkgCache::VerFileIterator vf=ver.FileList(); !vf.end(); ++vf)
+-    {
+-      if(is_first)
+-	is_first = false;
+-      else
+-	rval += ", ";
+-
+-      if(vf.File().Archive())
+-	rval += vf.File().Archive();
+-      else
+-	rval += _("<NULL>");
+-    }
+-
+-  return rval;
+-}
+-
+-string dep_targets(const pkgCache::DepIterator &start)
+-{
+-  string rval;
+-
+-  bool is_first = true;
+-
+-  eassert(!start.end());
+-
+-  for(pkgCache::DepIterator d = start; !d.end(); ++d)
+-    {
+-      if(is_first)
+-	is_first = false;
+-      else
+-	rval += " | ";
+-
+-      rval += d.TargetPkg().Name();
+-
+-      if(d.TargetVer())
+-	{
+-	  rval += " (";
+-	  rval += d.CompType();
+-	  rval += " ";
+-	  rval += d.TargetVer();
+-	  rval += ")";
+-	}
+-
+-      if((d->CompareOp & pkgCache::Dep::Or) == 0)
+-	break;
+-    }
+-
+-  return rval;
+-}
+-
+-wstring dep_text(const pkgCache::DepIterator &d)
+-{
+-  const char *name = const_cast<pkgCache::DepIterator &>(d).ParentPkg().Name();
+-
+-  string targets = dep_targets(d);
+-
+-  switch(d->Type)
+-    {
+-    case pkgCache::Dep::Depends:
+-      return swsprintf(transcode(_("%s depends upon %s")).c_str(),
+-		       name, targets.c_str());
+-    case pkgCache::Dep::PreDepends:
+-      return swsprintf(transcode(_("%s pre-depends upon %s")).c_str(),
+-		       name, targets.c_str());
+-    case pkgCache::Dep::Suggests:
+-      return swsprintf(transcode(_("%s suggests %s")).c_str(),
+-		       name, targets.c_str());
+-    case pkgCache::Dep::Recommends:
+-      return swsprintf(transcode(_("%s recommends %s")).c_str(),
+-		       name, targets.c_str());
+-    case pkgCache::Dep::Conflicts:
+-      return swsprintf(transcode(_("%s conflicts with %s")).c_str(),
+-		       name, targets.c_str());
+-    case pkgCache::Dep::Replaces:
+-      return swsprintf(transcode(_("%s replaces %s")).c_str(),
+-				 name, targets.c_str());
+-    case pkgCache::Dep::Obsoletes:
+-      return swsprintf(transcode(_("%s obsoletes %s")).c_str(),
+-				 name, targets.c_str());
+-    default:
+-      abort();
+-    }
+-}
+-
+-wstring conflict_text(const pkgCache::DepIterator &conflict,
+-		      const pkgCache::PrvIterator &prv)
+-{
+-  if(prv.end() || conflict->Type != pkgCache::Dep::Conflicts)
+-    return dep_text(conflict);
+-
+-  return swsprintf(transcode(_("%s conflicts with %s [provided by %s %s]")).c_str(),
+-		   const_cast<pkgCache::DepIterator &>(conflict).ParentPkg().Name(),
+-		   const_cast<pkgCache::PrvIterator &>(prv).ParentPkg().Name(),
+-		   const_cast<pkgCache::PrvIterator &>(prv).OwnerPkg().Name(),
+-		   const_cast<pkgCache::PrvIterator &>(prv).OwnerVer().VerStr());
+-}
+-
+-fragment *action_fragment(const aptitude_solution::action &a)
+-{
+-  if(a.ver.get_ver().end())
+-    return fragf(_("Removing %s"), a.ver.get_pkg().Name());
+-  else
+-    return fragf(_("Installing %s %s (%s)"),
+-		   a.ver.get_pkg().Name(), a.ver.get_ver().VerStr(),
+-		   archives_text(a.ver.get_ver()).c_str());
+-}
+-
+-
+-fragment *solution_fragment(const aptitude_solution &sol)
+-{
+-  // Bin packages according to what will happen to them.
+-  vector<pkgCache::PkgIterator> remove_packages;
+-  vector<pkgCache::PkgIterator> keep_packages;
+-  vector<pkgCache::VerIterator> install_packages;
+-  vector<pkgCache::VerIterator> downgrade_packages;
+-  vector<pkgCache::VerIterator> upgrade_packages;
+-
+-  for(imm::map<aptitude_universe::package,
+-	aptitude_solution::action>::const_iterator i=sol.get_actions().begin();
+-      i!=sol.get_actions().end(); ++i)
+-    {
+-      pkgCache::PkgIterator pkg=i->first.get_pkg();
+-      pkgCache::VerIterator curver=pkg.CurrentVer();
+-      pkgCache::VerIterator newver=i->second.ver.get_ver();
+-
+-      if(curver.end())
+-	{
+-	  if(newver.end())
+-	    keep_packages.push_back(pkg);
+-	  else
+-	    install_packages.push_back(newver);
+-	}
+-      else if(newver.end())
+-	remove_packages.push_back(pkg);
+-      else if(newver == curver)
+-	keep_packages.push_back(pkg);
+-      else
+-	{
+-	  int cmp=_system->VS->CmpVersion(curver.VerStr(),
+-					  newver.VerStr());
+-
+-	  // The versions shouldn't be equal -- otherwise
+-	  // something is majorly wrong.
+-	  // eassert(cmp!=0);
+-	  //
+-	  // The above is not true: consider, eg, the case of a
+-	  // locally compiled package and a standard package.
+-
+-	  /** \todo indicate "sidegrades" separately? */
+-	  if(cmp<=0)
+-	    upgrade_packages.push_back(newver);
+-	  else if(cmp>0)
+-	    downgrade_packages.push_back(newver);
+-	}
+-    }
+-
+-  sort(remove_packages.begin(), remove_packages.end(),
+-       pkg_name_lt());
+-  sort(keep_packages.begin(), keep_packages.end(),
+-       pkg_name_lt());
+-  sort(install_packages.begin(), install_packages.end(),
+-       ver_name_lt());
+-  sort(downgrade_packages.begin(), downgrade_packages.end(),
+-       ver_name_lt());
+-  sort(upgrade_packages.begin(), upgrade_packages.end(),
+-       ver_name_lt());
+-
+-  vector<fragment *> fragments;
+-
+-  if(!remove_packages.empty())
+-    {
+-      fragments.push_back(fragf(_("%BRemove%b the following packages:%n")));
+-      for(vector<pkgCache::PkgIterator>::const_iterator i=remove_packages.begin();
+-	  i!=remove_packages.end(); ++i)
+-	fragments.push_back(fragf("  %s%n", i->Name()));
+-
+-      fragments.push_back(newline_fragment());
+-    }
+-
+-  if(!install_packages.empty())
+-    {
+-      fragments.push_back(fragf(_("%BInstall%b the following packages:%n")));
+-      for(vector<pkgCache::VerIterator>::const_iterator i=install_packages.begin();
+-	  i!=install_packages.end(); ++i)
+-	fragments.push_back(fragf("  %s [%s (%s)]%n",
+-				  i->ParentPkg().Name(),
+-				  i->VerStr(),
+-				  archives_text(*i).c_str()));
+-
+-      fragments.push_back(newline_fragment());
+-    }
+-
+-  if(!keep_packages.empty())
+-    {
+-      fragments.push_back(fragf(_("%BKeep%b the following packages at their current version:%n")));
+-      for(vector<pkgCache::PkgIterator>::const_iterator i=keep_packages.begin();
+-	  i!=keep_packages.end(); ++i)
+-	{
+-	  if(i->CurrentVer().end())
+-	    fragments.push_back(fragf("  %s [%s]%n",
+-				      i->Name(),
+-				      _("Not Installed")));
+-	  else
+-	    fragments.push_back(fragf("  %s [%s (%s)]%n",
+-				      i->Name(),
+-				      i->CurrentVer().VerStr(),
+-				      archives_text(i->CurrentVer()).c_str()));
+-	}
+-
+-      fragments.push_back(newline_fragment());
+-    }
+-
+-  if(!upgrade_packages.empty())
+-    {
+-      fragments.push_back(fragf(_("%BUpgrade%b the following packages:%n")));
+-      for(vector<pkgCache::VerIterator>::const_iterator i=upgrade_packages.begin();
+-	  i!=upgrade_packages.end(); ++i)
+-	fragments.push_back(fragf("  %s [%s (%s) -> %s (%s)]%n",
+-				  i->ParentPkg().Name(),
+-				  i->ParentPkg().CurrentVer().VerStr(),
+-				  archives_text(i->ParentPkg().CurrentVer()).c_str(),
+-				  i->VerStr(),
+-				  archives_text(*i).c_str()));
+-
+-      fragments.push_back(newline_fragment());
+-    }
+-
+-  if(!downgrade_packages.empty())
+-    {
+-      fragments.push_back(fragf(_("%BDowngrade%b the following packages:%n")));
+-      for(vector<pkgCache::VerIterator>::const_iterator i=downgrade_packages.begin();
+-	  i!=downgrade_packages.end(); ++i)
+-	fragments.push_back(fragf("  %s [%s (%s) -> %s (%s)]%n",
+-				  i->ParentPkg().Name(),
+-				  i->ParentPkg().CurrentVer().VerStr(),
+-				  archives_text(i->ParentPkg().CurrentVer()).c_str(),
+-				  i->VerStr(),
+-				  archives_text(*i).c_str()));
+-
+-      fragments.push_back(newline_fragment());
+-    }
+-
+-  const imm::set<aptitude_universe::dep> &unresolved = sol.get_unresolved_soft_deps();
+-
+-  if(!unresolved.empty())
+-    {
+-      fragments.push_back(fragf(_("Leave the following dependencies unresolved:%n")));
+-
+-      for(imm::set<aptitude_universe::dep>::const_iterator i = unresolved.begin();
+-	  i != unresolved.end(); ++i)
+-	fragments.push_back(fragf("%ls%n", dep_text((*i).get_dep()).c_str()));
+-    }
+-
+-  char buf[512];
+-  snprintf(buf, 512, _("Score is %d"), sol.get_score());
+-  fragments.push_back(fragf("%s", buf));
+-
+-  return flowbox(sequence_fragment(fragments));
+-}
+diff --git a/src/solution_fragment.h b/src/solution_fragment.h
+deleted file mode 100644
+index 645d404..0000000
+--- a/src/solution_fragment.h
++++ /dev/null
+@@ -1,64 +0,0 @@
+-// solution_fragment.h            -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-//
+-// Code to convert an aptitude resolver solution and some of its
+-// individual components to fragments.
+-
+-#ifndef SOLUTION_FRAGMENT_H
+-#define SOLUTION_FRAGMENT_H
+-
+-#include <apt-pkg/pkgcache.h>
+-
+-// For aptitude_solution::action
+-#include <generic/problemresolver/solution.h>
+-
+-// So passing aptitude_solution::action to a function is legal
+-#include <generic/apt/aptitude_resolver_universe.h>
+-
+-class fragment;
+-class aptitude_universe;
+-
+-fragment *solution_fragment(const generic_solution<aptitude_universe> &solution);
+-
+-/** \return a list of the archives to which a version
+- *  belongs in the form "archive1,archive2,..."
+- */
+-std::string archives_text(const pkgCache::VerIterator &v);
+-
+-/** \return a fragment describing the given action. */
+-fragment *action_fragment(const generic_solution<aptitude_universe>::action &a);
+-
+-/** \return descriptive text about a single dependency. */
+-std::wstring dep_text(const pkgCache::DepIterator &d);
+-
+-/** \return descriptive text about a conflict through a provides.
+- *
+- *  \param conflict any dependency
+- *  \param p a provides iterator corresponding to conflict.  If conflict
+- *           is not a Conflict, then p is ignored and conflict_text is
+- *           identical to dep_text.  Otherwise, p is taken to be
+- *           the provides through which the conflict was discovered.
+- */
+-std::wstring conflict_text(const pkgCache::DepIterator &conflict,
+-			   const pkgCache::PrvIterator &p);
+-
+-/** \return descriptive text about the targets of a dependency. */
+-std::string dep_targets(const pkgCache::DepIterator &start);
+-
+-#endif // SOLUTION_FRAGMENT_H
+diff --git a/src/solution_item.cc b/src/solution_item.cc
+deleted file mode 100644
+index cc3eca4..0000000
+--- a/src/solution_item.cc
++++ /dev/null
+@@ -1,615 +0,0 @@
+-// solution_item.cc
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#include "solution_item.h"
+-
+-
+-#include "aptitude.h"
+-#include "pkg_info_screen.h"
+-#include "solution_fragment.h"
+-#include "ui.h"
+-
+-
+-#include <apt-pkg/pkgrecords.h>
+-
+-#include <generic/apt/resolver_manager.h>
+-
+-#include <generic/util/util.h>
+-
+-#include <vscreen/config/keybindings.h>
+-#include <vscreen/fragment.h>
+-#include <vscreen/transcode.h>
+-#include <vscreen/vs_tree.h>
+-
+-
+-using namespace std;
+-
+-
+-action_type analyze_action(const aptitude_universe::version &ver)
+-{
+-  pkgCache::PkgIterator pkg=ver.get_pkg();
+-  pkgCache::VerIterator curver=pkg.CurrentVer();
+-  pkgCache::VerIterator newver=ver.get_ver();
+-
+-  if(curver.end())
+-    {
+-      if(newver.end())
+-	return action_keep;
+-      else
+-	return action_install;
+-    }
+-  else if(newver.end())
+-    return action_remove;
+-  else if(newver == curver)
+-    return action_keep;
+-  else
+-    {
+-      int cmp=_system->VS->CmpVersion(curver.VerStr(),
+-				      newver.VerStr());
+-
+-      // The versions shouldn't be equal -- otherwise
+-      // something is majorly wrong.
+-      // eassert(cmp!=0);
+-      //
+-      // The above is not true: consider, eg, the case of a
+-      // locally compiled package and a standard package.
+-
+-      /** \todo indicate "sidegrades" separately? */
+-      if(cmp <= 0)
+-	return action_upgrade;
+-      else
+-	return action_downgrade;
+-    }
+-}
+-
+-/** \return a description of what will happen if the given version
+- *  is installed.
+- */
+-static fragment *action_description(const aptitude_resolver_version &ver)
+-{
+-  pkgCache::PkgIterator pkg = ver.get_pkg();
+-
+-  switch(analyze_action(ver))
+-    {
+-    case action_remove:
+-      return fragf(_("Remove %F [%s (%s)]"),
+-		   text_fragment(pkg.Name(), style_attrs_on(A_BOLD)),
+-		   pkg.CurrentVer().VerStr(),
+-		   archives_text(pkg.CurrentVer()).c_str());
+-      break;
+-
+-    case action_install:
+-      return fragf(_("Install %F [%s (%s)]"),
+-		   text_fragment(pkg.Name(), style_attrs_on(A_BOLD)),
+-		   ver.get_ver().VerStr(),
+-		   archives_text(ver.get_ver()).c_str());
+-      break;
+-
+-    case action_keep:
+-      if(ver.get_ver().end())
+-	return fragf(_("Cancel the installation of %F"),
+-		     text_fragment(pkg.Name(), style_attrs_on(A_BOLD)));
+-      else if(ver.get_package().current_version().get_ver().end())
+-	return fragf(_("Cancel the removal of %F"),
+-		     text_fragment(pkg.Name(), style_attrs_on(A_BOLD)));
+-      else
+-	return fragf(_("Keep %F at version %s (%s)"),
+-		     text_fragment(pkg.Name(), style_attrs_on(A_BOLD)),
+-		     ver.get_ver().VerStr(),
+-		     archives_text(ver.get_ver()).c_str());
+-
+-      break;
+-
+-    case action_upgrade:
+-      return fragf(_("Upgrade %F [%s (%s) -> %s (%s)]"),
+-		   text_fragment(pkg.Name(), style_attrs_on(A_BOLD)),
+-		   pkg.CurrentVer().VerStr(),
+-		   archives_text(pkg.CurrentVer()).c_str(),
+-		   ver.get_ver().VerStr(), archives_text(ver.get_ver()).c_str());
+-      break;
+-
+-
+-    case action_downgrade:
+-      return fragf(_("Downgrade %F [%s (%s) -> %s (%s)]"),
+-		   text_fragment(pkg.Name(), style_attrs_on(A_BOLD)),
+-		   pkg.CurrentVer().VerStr(), archives_text(pkg.CurrentVer()).c_str(),
+-		   ver.get_ver().VerStr(), archives_text(ver.get_ver()).c_str());
+-      break;
+-    default:
+-      // Impossible.
+-      abort();
+-    }
+-
+-  abort();
+-}
+-
+-
+-const wchar_t *solution_item::tag()
+-{
+-  return L"";
+-}
+-
+-const wchar_t *solution_item::label()
+-{
+-  return L"";
+-}
+-
+-style solution_item::get_normal_style()
+-{
+-  if(is_rejected())
+-    return get_style("SolutionActionRejected");
+-  else if(is_mandatory())
+-    return get_style("SolutionActionApproved");
+-  else
+-    return style();
+-}
+-
+-bool solution_item::dispatch_key(const key &k, vs_tree *owner)
+-{
+-  if(global_bindings.key_matches(k, "SolutionActionReject"))
+-    {
+-      toggle_rejected();
+-      owner->line_down();
+-    }
+-  else if(global_bindings.key_matches(k, "SolutionActionApprove"))
+-    {
+-      toggle_mandated();
+-      owner->line_down();
+-    }
+-  else
+-    return vs_treeitem::dispatch_key(k, owner);
+-
+-  return true;
+-}
+-
+-
+-//////////////////////////// Menu Redirections //////////////////////////
+-
+-bool solution_item::resolver_toggle_approved()
+-{
+-  toggle_mandated();
+-  return true;
+-}
+-
+-bool solution_item::resolver_toggle_approved_enabled()
+-{
+-  return true;
+-}
+-
+-bool solution_item::resolver_toggle_rejected()
+-{
+-  toggle_rejected();
+-  return true;
+-}
+-
+-bool solution_item::resolver_toggle_rejected_enabled()
+-{
+-  return true;
+-}
+-
+-
+-/////////////////////////////////////////////////////////////////////////
+-
+-bool solution_act_item::is_rejected()
+-{
+-  eassert(resman->resolver_exists());
+-
+-  return resman->is_rejected(ver);
+-}
+-
+-bool solution_act_item::is_mandatory()
+-{
+-  eassert(resman->resolver_exists());
+-
+-  return resman->is_mandatory(ver);
+-}
+-
+-void solution_act_item::reject()
+-{
+-  resman->reject_version(ver);
+-}
+-
+-void solution_act_item::unreject()
+-{
+-  resman->unreject_version(ver);
+-}
+-
+-void solution_act_item::mandate()
+-{
+-  resman->mandate_version(ver);
+-}
+-
+-void solution_act_item::unmandate()
+-{
+-  resman->unmandate_version(ver);
+-}
+-
+-void solution_act_item::highlighted(vs_tree *win)
+-{
+-  if(apt_cache_file == NULL)
+-    {
+-      set_short_description(fragf(""));
+-      set_active_dep(aptitude_resolver_dep());
+-      return;
+-    }
+-
+-  pkgCache::VerIterator real_ver = ver.get_ver();
+-
+-  if(real_ver.end())
+-    real_ver = ver.get_package().current_version().get_ver();
+-
+-  if(real_ver.end())
+-    real_ver = ver.get_pkg().VersionList();
+-
+-  if(real_ver.end() || real_ver.FileList().end() ||
+-     apt_package_records == NULL)
+-    set_short_description(fragf(""));
+-  else
+-    set_short_description(text_fragment(get_short_description(real_ver)));
+-
+-  set_active_dep(d);
+-}
+-
+-void solution_act_item::unhighlighted(vs_tree *win)
+-{
+-  set_short_description(fragf(""));
+-
+-  set_active_dep(aptitude_resolver_dep());
+-}
+-
+-void solution_act_item::show_target_info()
+-{
+-  pkgCache::VerIterator real_ver = ver.get_ver();
+-  pkgCache::PkgIterator pkg = ver.get_pkg();
+-
+-  if(real_ver.end())
+-    real_ver = ver.get_package().current_version().get_ver();
+-
+-  if(real_ver.end())
+-    real_ver = pkg.VersionList();
+-
+-  // Show information about the corresponding package/version.
+-  insert_main_widget(make_info_screen(pkg, real_ver),
+-		     ssprintf(_("%s info"), pkg.Name()),
+-		     "",
+-		     ssprintf(_("Information about %s"), pkg.Name()));
+-}
+-
+-bool solution_act_item::dispatch_key(const key &k, vs_tree *owner)
+-{
+-  if(global_bindings.key_matches(k, "InfoScreen"))
+-    {
+-      show_target_info();
+-      return true;
+-    }
+-  else
+-    return solution_item::dispatch_key(k, owner);
+-}
+-
+-void solution_act_item::paint(vs_tree *win, int y, bool hierarchical, const style &st)
+-{
+-  unsigned int basex = hierarchical ? 2*get_depth() : 0;
+-  unsigned int width = win->getmaxx();
+-
+-  unsigned int x = 0;
+-
+-  win->move(y, 0);
+-
+-  if(x < width)
+-    {
+-      if(is_rejected())
+-	win->addch('R'); // For "reject"
+-      else if(is_mandatory())
+-	win->addch('A'); // For "accept"
+-      else
+-	win->addch(' ');
+-      ++x;
+-    }
+-
+-  if(x < width)
+-    {
+-      win->addch(' ');
+-      ++x;
+-    }
+-
+-  while(x < width && x < basex)
+-    {
+-      win->addch(' ');
+-      ++x;
+-    }
+-
+-  if(x < width)
+-    {
+-      win->addch('-');
+-      ++x;
+-    }
+-
+-  if(x < width)
+-    {
+-      win->addch('>');
+-      ++x;
+-    }
+-
+-  if(x < width)
+-    {
+-      win->addch(' ');
+-      ++x;
+-    }
+-
+-  fragment *f = clipbox(action_description(ver));
+-  fragment_contents c = f->layout(width-x, width-x, st);
+-  delete f;
+-
+-  eassert(c.size() < 2);
+-  if(c.size() > 0)
+-    {
+-      const fragment_line &l = c.front();
+-
+-      fragment_line::const_iterator loc = l.begin();
+-      while(loc != l.end() && x < width)
+-	{
+-	  win->attrset(loc->attrs);
+-	  win->add_wch(loc->ch);
+-	  x += wcwidth(loc->ch);
+-	  ++loc;
+-	}
+-    }
+-
+-  win->apply_style(st);
+-
+-  while(x < width)
+-    {
+-      win->addch(' ');
+-      ++x;
+-    }
+-}
+-
+-bool solution_act_item::view_target_enabled()
+-{
+-  return true;
+-}
+-
+-bool solution_act_item::view_target()
+-{
+-  show_target_info();
+-  return true;
+-}
+-
+-
+-
+-
+-void solution_act_item_bare::paint(vs_tree *win, int y, bool hierarchical, const style &st)
+-{
+-  unsigned int basex = hierarchical ? 2*get_depth() : 0;
+-  unsigned int width = win->getmaxx();
+-
+-  unsigned int x = 0;
+-
+-  win->move(y, 0);
+-
+-  if(x < width)
+-    {
+-      if(is_rejected())
+-	win->addch('R'); // For "reject"
+-      else if(is_mandatory())
+-	win->addch('A'); // For "accept"
+-      else
+-	win->addch(' ');
+-      ++x;
+-    }
+-
+-  if(x < width)
+-    {
+-      win->addch(' ');
+-      ++x;
+-    }
+-
+-  while(x < width && x < basex)
+-    {
+-      win->addch(' ');
+-      ++x;
+-    }
+-
+-  win->apply_style(st+style_attrs_on(A_BOLD));
+-
+-  aptitude_universe::version ver = get_ver();
+-
+-  const char *name = ver.get_pkg().Name();
+-  while(x < width && *name)
+-    {
+-      win->addch(*name);
+-      ++name;
+-      ++x;
+-    }
+-
+-  // Ensure that at least one space separates the two columns.
+-  if(x < width)
+-    {
+-      win->addch(' ');
+-      ++x;
+-    }
+-
+-  win->apply_style(st);
+-  string righttext;
+-
+-  pkgCache::VerIterator currver = ver.get_pkg().CurrentVer();
+-
+-  if(currver.end() || ver.get_ver().end() || currver == ver.get_ver())
+-    {
+-      pkgCache::VerIterator dispv = currver;
+-
+-      if(dispv.end())
+-	dispv = ver.get_ver();
+-
+-      if(dispv.end())
+-	righttext = "[UNINST]";
+-      else
+-	righttext = ssprintf("[%s (%s)]",
+-			     dispv.VerStr(), archives_text(dispv).c_str());
+-    }
+-  else
+-    {
+-      righttext = "[";
+-
+-      if(currver.end())
+-	righttext += "UNINST";
+-      else
+-	{
+-	  righttext += currver.VerStr();
+-	  righttext += " ";
+-	  righttext += archives_text(currver);
+-	}
+-
+-      righttext += " -> ";
+-
+-      if(ver.get_ver().end())
+-	righttext += "UNINST";
+-      else
+-	{
+-	  righttext += ver.get_ver().VerStr();
+-	  righttext += " ";
+-	  righttext += archives_text(ver.get_ver());
+-	}
+-
+-      righttext += "]";
+-    }
+-
+-  unsigned int startx;
+-  if(x+righttext.size() >= width)
+-    startx = x;
+-  else
+-    startx = width-righttext.size();
+-  while(x < startx)
+-    {
+-      win->addch(' ');
+-      ++x;
+-    }
+-
+-  unsigned int rightloc = 0;
+-  while(x < width && rightloc < righttext.size())
+-    {
+-      win->addch(righttext[rightloc]);
+-      ++rightloc;
+-      ++x;
+-    }
+-}
+-
+-
+-
+-bool solution_unresolved_item::is_rejected()
+-{
+-  return resman->is_hardened(d);
+-}
+-
+-bool solution_unresolved_item::is_mandatory()
+-{
+-  return resman->is_approved_broken(d);
+-}
+-
+-void solution_unresolved_item::highlighted(vs_tree *win)
+-{
+-  if(apt_cache_file == NULL)
+-    set_active_dep(aptitude_resolver_dep());
+-  else
+-    set_active_dep(d);
+-}
+-
+-void solution_unresolved_item::unhighlighted(vs_tree *win)
+-{
+-  set_active_dep(aptitude_resolver_dep());
+-}
+-
+-void solution_unresolved_item::reject()
+-{
+-  resman->harden_dep(d);
+-}
+-
+-void solution_unresolved_item::unreject()
+-{
+-  resman->unharden_dep(d);
+-}
+-
+-void solution_unresolved_item::mandate()
+-{
+-  resman->approve_broken_dep(d);
+-}
+-
+-void solution_unresolved_item::unmandate()
+-{
+-  resman->unapprove_broken_dep(d);
+-}
+-
+-void solution_unresolved_item::paint(vs_tree *win, int y, bool hierarchical, const style &st)
+-{
+-  unsigned int basex = hierarchical ? 2*get_depth() : 0;
+-  unsigned int width = win->getmaxx();
+-
+-  unsigned int x = 0;
+-
+-  win->move(y, 0);
+-
+-  if(x < width)
+-    {
+-      if(is_rejected())
+-	win->addch('R'); // For "reject"
+-      else if(is_mandatory())
+-	win->addch('A'); // For "accept"
+-      else
+-	win->addch(' ');
+-      ++x;
+-    }
+-
+-  if(x < width)
+-    {
+-      win->addch(' ');
+-      ++x;
+-    }
+-
+-  while(x < width && x < basex)
+-    {
+-      win->addch(' ');
+-      ++x;
+-    }
+-
+-  wstring text;
+-
+-  if(!fully_explained)
+-    text = swsprintf(transcode(_("%s recommends %s")).c_str(),
+-		     d.get_dep().ParentPkg().Name(),
+-		     dep_targets(d.get_dep()).c_str());
+-  else
+-    text = swsprintf(transcode(_("-> Leave the dependency \"%s recommends %s\" unresolved.")).c_str(),
+-		     d.get_dep().ParentPkg().Name(),
+-		     dep_targets(d.get_dep()).c_str());
+-
+-  wstring::const_iterator loc = text.begin();
+-
+-  while(loc != text.end() && x < width)
+-    {
+-      win->add_wch(*loc);
+-      x += wcwidth(*loc);
+-      ++loc;
+-    }
+-
+-  while(x < width)
+-    {
+-      win->addch(' ');
+-      ++x;
+-    }
+-}
+diff --git a/src/solution_item.h b/src/solution_item.h
+deleted file mode 100644
+index 4242660..0000000
+--- a/src/solution_item.h
++++ /dev/null
+@@ -1,214 +0,0 @@
+-// solution_item.h                                   -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-//
+-// Tree items that represent the contents of a solution.
+-
+-#ifndef SOLUTION_ITEM_H
+-#define SOLUTION_ITEM_H
+-
+-#include "menu_redirect.h"
+-
+-#include <sigc++/slot.h>
+-
+-#include <generic/apt/aptitude_resolver_universe.h>
+-
+-#include <generic/problemresolver/solution.h>
+-
+-#include <vscreen/vs_treeitem.h>
+-
+-class fragment;
+-
+-class solution_item : public vs_treeitem, public menu_redirect
+-{
+-public:
+-  const wchar_t *tag();
+-
+-  const wchar_t *label();
+-
+-  /** \return \b true if this item is rejected. */
+-  virtual bool is_rejected() = 0;
+-
+-  /** \return \b true if this item is mandatory. */
+-  virtual bool is_mandatory() = 0;
+-
+-  /** Reject this item. */
+-  virtual void reject() = 0;
+-
+-  /** Cancel the rejection of this item. */
+-  virtual void unreject() = 0;
+-
+-  /** Make this item mandatory. */
+-  virtual void mandate() = 0;
+-
+-  /** Make this item not mandatory. */
+-  virtual void unmandate() = 0;
+-
+-  void toggle_rejected()
+-  {
+-    if(!is_rejected())
+-      reject();
+-    else
+-      unreject();
+-  }
+-
+-  void toggle_mandated()
+-  {
+-    if(!is_mandatory())
+-      mandate();
+-    else
+-      unmandate();
+-  }
+-
+-  style get_normal_style();
+-
+-  bool dispatch_key(const key &k, vs_tree *owner);
+-
+-  // Menu redirections:
+-  bool resolver_toggle_approved();
+-  bool resolver_toggle_approved_enabled();
+-  bool resolver_toggle_rejected();
+-  bool resolver_toggle_rejected_enabled();
+-};
+-
+-class solution_act_item : public solution_item
+-{
+-  aptitude_universe::version ver;
+-  aptitude_universe::dep d;
+-
+-  /** A callback to be invoked with a fragment-based description of
+-   *  this item.
+-   */
+-  sigc::slot1<void, fragment *> set_short_description;
+-
+-  /** A callback to be invoked with the dependency corresponding to this item. */
+-  sigc::slot1<void, aptitude_resolver_dep> set_active_dep;
+-public:
+-
+-  /** Create a solution_act_item.
+-   *
+-   *  \param act the action that this item corresponds to
+-   *  \param _set_short_description a callback to be invoked with a
+-   *               brief description of this item when it is selected
+-   *  \param _set_active_dep a callback to be invoked with the dependency
+-   *               corresponding to this item when the item is selected
+-   */
+-  solution_act_item(const generic_solution<aptitude_universe>::action &act,
+-		    const sigc::slot1<void, fragment *> &_set_short_description,
+-		    const sigc::slot1<void, aptitude_resolver_dep> &_set_active_dep)
+-    :ver(act.ver),
+-     d(act.d),
+-     set_short_description(_set_short_description),
+-     set_active_dep(_set_active_dep)
+-  {
+-  }
+-
+-  bool is_rejected();
+-
+-  bool is_mandatory();
+-
+-  void reject();
+-
+-  void unreject();
+-
+-  void mandate();
+-
+-  void unmandate();
+-
+-  void show_target_info();
+-
+-  void highlighted(vs_tree *win);
+-
+-  void unhighlighted(vs_tree *win);
+-
+-  aptitude_universe::version get_ver() const
+-  {
+-    return ver;
+-  }
+-
+-  bool dispatch_key(const key &k, vs_tree *owner);
+-
+-  void paint(vs_tree *win, int y, bool hierarchical, const style &st);
+-
+-
+-  // Menu redirections.
+-  bool view_target_enabled();
+-  bool view_target();
+-};
+-
+-/** Like a solution_act_item, but the display doesn't include the
+- *  descriptive verb ("install" or whatever).
+- */
+-class solution_act_item_bare : public solution_act_item
+-{
+-public:
+-  solution_act_item_bare(const generic_solution<aptitude_universe>::action &act,
+-			 const sigc::slot1<void, fragment *> &set_short_description,
+-			 const sigc::slot1<void, aptitude_resolver_dep> &set_active_dep)
+-    :solution_act_item(act, set_short_description, set_active_dep)
+-  {
+-  }
+-
+-  void paint(vs_tree *win, int y, bool hierarchical, const style &st);
+-};
+-
+-/** A solution item corresponding to leaving a dependency unresolved. */
+-class solution_unresolved_item : public solution_item
+-{
+-  aptitude_universe::dep d;
+-
+-  /** If \b true, then a brief explanation about what this item is
+-   *  (suitable for inclusion in a list of alternatives) will be
+-   *  displayed.
+-   */
+-  bool fully_explained;
+-
+-  sigc::slot1<void, aptitude_resolver_dep> set_active_dep;
+-public:
+-  solution_unresolved_item(const aptitude_universe::dep &_d,
+-			   bool _fully_explained,
+-			   const sigc::slot1<void, aptitude_resolver_dep> &_set_active_dep)
+-    :d(_d), fully_explained(_fully_explained), set_active_dep(_set_active_dep)
+-  {
+-  }
+-
+-  bool is_rejected();
+-  bool is_mandatory();
+-  void highlighted(vs_tree *win);
+-  void unhighlighted(vs_tree *win);
+-  void reject();
+-  void unreject();
+-  void mandate();
+-  void unmandate();
+-
+-  void paint(vs_tree *win, int y, bool hierarchical, const style &st);
+-};
+-
+-
+-enum action_type {action_remove, action_keep, action_install,
+-		  action_downgrade, action_upgrade};
+-
+-
+-/** A simpler version of find_pkg_state that doesn't care about
+- *  automaticness.  Provided here because it's used by the solution
+- *  item and screen, but should probably migrate to generic/
+- *  eventually.
+- */
+-action_type analyze_action(const aptitude_universe::version &ver);
+-
+-#endif
+diff --git a/src/solution_screen.cc b/src/solution_screen.cc
+deleted file mode 100644
+index 82580c5..0000000
+--- a/src/solution_screen.cc
++++ /dev/null
+@@ -1,603 +0,0 @@
+-// solution_screen.cc
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#include "solution_screen.h"
+-
+-#include "aptitude.h"
+-#include "menu_redirect.h"
+-#include "menu_tree.h"
+-#include "solution_fragment.h"
+-#include "solution_item.h"
+-
+-#include <generic/apt/aptitude_resolver_universe.h>
+-#include <generic/apt/resolver_manager.h>
+-
+-#include <generic/problemresolver/solution.h>
+-
+-#include <generic/util/util.h>
+-
+-#include <sigc++/adaptors/bind.h>
+-
+-#include <vscreen/config/style.h>
+-#include <vscreen/fragment.h>
+-#include <vscreen/transcode.h>
+-#include <vscreen/vs_label.h>
+-#include <vscreen/vs_layout_item.h>
+-#include <vscreen/vs_multiplex.h>
+-#include <vscreen/vs_staticitem.h>
+-#include <vscreen/vs_subtree.h>
+-#include <vscreen/vs_table.h>
+-
+-typedef generic_solution<aptitude_universe> aptitude_solution;
+-
+-using namespace std;
+-
+-struct act_name_lt
+-{
+-public:
+-  bool operator()(const aptitude_solution::action &v1,
+-		  const aptitude_solution::action &v2) const
+-  {
+-    return strcmp(v1.ver.get_pkg().Name(), v2.ver.get_pkg().Name()) < 0;
+-  }
+-};
+-
+-/** Partition the set of all packages into several vectors,
+- *  according to the action to be performed on each package.
+- *
+- *  \param remove_actions each package to be removed will be placed in this vector.
+- *  \param keep_actions each package which is being kept will be placed
+- *         in this vector.
+- *  \param install_actions if a package is being newly installed,
+- *         its target version will be placed in this vector.
+- *  \param downgrade_actions if a package is being downgraded,
+- *         its target version will be placed in this vector.
+- *  \param upgrade_actions if a package is being upgraded,
+- *         its target version will be placed in this vector.
+- */
+-void bin_actions(const aptitude_solution &sol,
+-		 vector<aptitude_solution::action> &remove_actions,
+-		 vector<aptitude_solution::action> &keep_actions,
+-		 vector<aptitude_solution::action> &install_actions,
+-		 vector<aptitude_solution::action> &downgrade_actions,
+-		 vector<aptitude_solution::action> &upgrade_actions)
+-{
+-
+-  for(imm::map<aptitude_universe::package,
+-	aptitude_solution::action>::const_iterator i=sol.get_actions().begin();
+-      i!=sol.get_actions().end(); ++i)
+-    switch(analyze_action(i->second.ver))
+-      {
+-      case action_remove:
+-	remove_actions.push_back(i->second);
+-	break;
+-      case action_keep:
+-	keep_actions.push_back(i->second);
+-	break;
+-      case action_install:
+-	install_actions.push_back(i->second);
+-	break;
+-      case action_downgrade:
+-	downgrade_actions.push_back(i->second);
+-	break;
+-      case action_upgrade:
+-	upgrade_actions.push_back(i->second);
+-	break;
+-      default:
+-	abort();
+-      }
+-}
+-
+-class label_tree : public vs_subtree_generic
+-{
+-  wstring my_label;
+-public:
+-  label_tree(wstring _label, bool _expanded = true,
+-	     bool selectable = true,
+-	     int depth = 0)
+-    :vs_subtree_generic(_expanded), my_label(_label)
+-  {
+-    set_selectable(selectable);
+-    set_depth(depth);
+-  }
+-
+-  void paint(vs_tree *win, int y, bool hierarchical,
+-	     const style &st)
+-  {
+-    vs_subtree<vs_treeitem>::paint(win, y, hierarchical, my_label);
+-  }
+-
+-  const wchar_t *tag()
+-  {
+-    return my_label.c_str();
+-  }
+-
+-  const wchar_t *label()
+-  {
+-    return my_label.c_str();
+-  }
+-};
+-
+-
+-
+-vs_subtree_generic *make_dep_solvers_tree(const aptitude_resolver_dep &d)
+-{
+-  pkgCache::DepIterator real_dep = d.get_dep();
+-  pkgCache::PrvIterator prv = d.get_prv();
+-
+-  vs_subtree_generic *root = new label_tree(L"", true, true, -1);
+-
+-  vs_staticitem *conflict_item = new vs_staticitem(conflict_text(real_dep, prv), L"");
+-  root->add_child(conflict_item);
+-
+-  vs_subtree_generic *resolvers = new label_tree(transcode(_("The following actions will resolve this dependency:")), true, false);
+-
+-  root->add_child(resolvers);
+-
+-  for(aptitude_resolver_package::version_iterator
+-	vi = d.get_source().get_package().versions_begin(); !vi.end(); ++vi)
+-    if(*vi != d.get_source())
+-      {
+-	aptitude_solution::action act(*vi, d, true, 0);
+-
+-	resolvers->add_child(new solution_act_item(act,
+-						   sigc::slot1<void, fragment *>(),
+-						   sigc::slot1<void, aptitude_resolver_dep>()));
+-      }
+-
+-  for(aptitude_resolver_dep::solver_iterator
+-	si = d.solvers_begin(); !si.end(); ++si)
+-    {
+-      aptitude_solution::action act(*si, d, false, 0);
+-
+-      resolvers->add_child(new solution_act_item(act,
+-						 sigc::slot1<void, fragment *>(),
+-						 sigc::slot1<void, aptitude_resolver_dep>()));
+-    }
+-
+-  if(d.get_dep()->Type == pkgCache::Dep::Recommends)
+-    resolvers->add_child(new solution_unresolved_item(d, true, sigc::slot1<void, aptitude_resolver_dep>()));
+-
+-  return root;
+-}
+-
+-vs_subtree_generic *make_story_tree(const aptitude_solution &sol,
+-				    const sigc::slot1<void, fragment *> &set_short_description,
+-				    const sigc::slot1<void, aptitude_resolver_dep> &set_active_dep)
+-{
+-  vector<aptitude_solution::action> actions;
+-
+-  for(imm::map<aptitude_universe::package, aptitude_solution::action>::const_iterator
+-	i = sol.get_actions().begin() ; i != sol.get_actions().end(); ++i)
+-    actions.push_back(i->second);
+-
+-  sort(actions.begin(), actions.end(), aptitude_solution::action_id_compare());
+-
+-  vs_subtree_generic *root = new label_tree(L"");
+-
+-  for(vector<aptitude_solution::action>::const_iterator
+-	i = actions.begin(); i != actions.end(); ++i)
+-    {
+-      vs_subtree_generic *tree = new label_tree(dep_text(i->d.get_dep()), true, false);
+-
+-      tree->add_child(new solution_act_item(*i, set_short_description, set_active_dep));
+-      root->add_child(tree);
+-    }
+-
+-  return root;
+-}
+-
+-vs_subtree_generic *make_solution_tree(const aptitude_solution &sol,
+-				       const sigc::slot1<void, fragment *> &set_short_description,
+-				       const sigc::slot1<void, aptitude_resolver_dep> &set_active_dep)
+-{
+-  // Bin packages according to what will happen to them.
+-  vector<aptitude_solution::action> remove_actions;
+-  vector<aptitude_solution::action> keep_actions;
+-  vector<aptitude_solution::action> install_actions;
+-  vector<aptitude_solution::action> downgrade_actions;
+-  vector<aptitude_solution::action> upgrade_actions;
+-
+-  bin_actions(sol, remove_actions, keep_actions, install_actions,
+-	       downgrade_actions, upgrade_actions);
+-
+-  sort(remove_actions.begin(), remove_actions.end(),
+-       act_name_lt());
+-  sort(keep_actions.begin(), keep_actions.end(),
+-       act_name_lt());
+-  sort(install_actions.begin(), install_actions.end(),
+-       act_name_lt());
+-  sort(downgrade_actions.begin(), downgrade_actions.end(),
+-       act_name_lt());
+-  sort(upgrade_actions.begin(), upgrade_actions.end(),
+-       act_name_lt());
+-
+-  vs_subtree_generic *root = new label_tree(L"");
+-
+-  if(!remove_actions.empty())
+-    {
+-      vs_subtree_generic *remove_tree = new label_tree(transcode(_("Remove the following packages:")));
+-
+-      for(vector<aptitude_solution::action>::const_iterator i = remove_actions.begin();
+-	  i != remove_actions.end(); ++i)
+-	remove_tree->add_child(new solution_act_item_bare(*i, set_short_description, set_active_dep));
+-
+-      root->add_child(remove_tree);
+-    }
+-
+-  if(!keep_actions.empty())
+-    {
+-      vs_subtree_generic *keep_tree = new label_tree(transcode(_("Keep the following packages at their current version:")));
+-
+-      for(vector<aptitude_solution::action>::const_iterator i = keep_actions.begin();
+-	  i != keep_actions.end(); ++i)
+-	keep_tree->add_child(new solution_act_item_bare(*i, set_short_description, set_active_dep));
+-
+-      root->add_child(keep_tree);
+-    }
+-
+-  if(!install_actions.empty())
+-    {
+-      vs_subtree_generic *install_tree = new label_tree(transcode(_("Install the following packages:")));
+-
+-      for(vector<aptitude_solution::action>::const_iterator i = install_actions.begin();
+-	  i != install_actions.end(); ++i)
+-	install_tree->add_child(new solution_act_item_bare(*i, set_short_description, set_active_dep));
+-
+-      root->add_child(install_tree);
+-    }
+-
+-  if(!upgrade_actions.empty())
+-    {
+-      vs_subtree_generic *upgrade_tree = new label_tree(transcode(_("Upgrade the following packages:")));
+-
+-      for(vector<aptitude_solution::action>::const_iterator i = upgrade_actions.begin();
+-	  i != upgrade_actions.end(); ++i)
+-	upgrade_tree->add_child(new solution_act_item_bare(*i, set_short_description, set_active_dep));
+-
+-      root->add_child(upgrade_tree);
+-    }
+-
+-  if(!downgrade_actions.empty())
+-    {
+-      vs_subtree_generic *downgrade_tree = new label_tree(transcode(_("Downgrade the following packages:")));
+-
+-      for(vector<aptitude_solution::action>::const_iterator i = downgrade_actions.begin();
+-	  i != downgrade_actions.end(); ++i)
+-	downgrade_tree->add_child(new solution_act_item_bare(*i, set_short_description, set_active_dep));
+-
+-      root->add_child(downgrade_tree);
+-    }
+-
+-  const imm::set<aptitude_universe::dep> &unresolved = sol.get_unresolved_soft_deps();
+-
+-  if(!unresolved.empty())
+-    {
+-      vs_subtree_generic *unresolved_tree = new label_tree(transcode(_("Leave the following recommendations unresolved:")));
+-
+-      for(imm::set<aptitude_universe::dep>::const_iterator i = unresolved.begin();
+-	  i != unresolved.end(); ++i)
+-	unresolved_tree->add_child(new solution_unresolved_item(*i, false, set_active_dep));
+-
+-      root->add_child(unresolved_tree);
+-    }
+-
+-  return root;
+-}
+-
+-/** A class for trees in which 'undo' should be mapped to the solution
+- *  undo command.
+- */
+-class solution_undo_tree : public menu_tree
+-{
+-protected:
+-  solution_undo_tree()
+-  {
+-  }
+-public:
+-  static ref_ptr<solution_undo_tree> create()
+-  {
+-    ref_ptr<solution_undo_tree> rval(new solution_undo_tree);
+-    rval->decref();
+-    return rval;
+-  }
+-
+-  bool undo_undo_enabled()
+-  {
+-    return resman != NULL && resman->has_undo_items();
+-  }
+-
+-  bool undo_undo()
+-  {
+-    return resman != NULL && resman->undo();
+-  }
+-};
+-typedef ref_ptr<solution_undo_tree> solution_undo_tree_ref;
+-
+-class solution_examiner : public vs_multiplex
+-{
+-  aptitude_solution last_sol;
+-
+-  menu_tree_ref solution_tree;
+-  menu_tree_ref story_tree;
+-
+-  sigc::slot1<void, fragment *> set_short_description;
+-  sigc::slot1<void, aptitude_resolver_dep> set_active_dep;
+-
+-  void attach_apt_cache_signals()
+-  {
+-    if(apt_cache_file)
+-      resman->state_changed.connect(sigc::mem_fun(*this, &solution_examiner::update));
+-  }
+-
+-  /** Re-connects the signals attached to the apt cache file. */
+-  void handle_cache_reload()
+-  {
+-    attach_apt_cache_signals();
+-
+-    update();
+-  }
+-
+-  void set_static_root(const wstring &s)
+-  {
+-    solution_tree->set_root(new vs_staticitem(s, L""), true);
+-    story_tree->set_root(new vs_staticitem(s, L""), true);
+-  }
+-
+-  /** Send highlighted/unhighlighted messages to the subwidgets so
+-   *  that the short description ends up correct.
+-   */
+-  void update_highlights()
+-  {
+-    vs_widget_ref tmpref(this);
+-
+-    if(solution_tree == visible_widget())
+-      {
+-	story_tree->unhighlight_current();
+-	solution_tree->highlight_current();
+-      }
+-    else if(story_tree == visible_widget())
+-      {
+-	solution_tree->unhighlight_current();
+-	story_tree->highlight_current();
+-      }
+-  }
+-
+-  void tick()
+-  {
+-    vs_widget_ref tmpref(this);
+-
+-    if(resman != NULL && resman->resolver_exists())
+-      {
+-	resolver_manager::state state = resman->state_snapshot();
+-
+-	if(state.background_thread_active &&
+-	   state.selected_solution >= state.generated_solutions)
+-	  update_from_state(state);
+-      }
+-
+-    vscreen_addtimeout(new slot_event(sigc::mem_fun(this, &solution_examiner::tick)), 1000);
+-  }
+-
+-protected:
+-  solution_examiner(const sigc::slot1<void, fragment *> &_set_short_description,
+-		    const sigc::slot1<void, aptitude_resolver_dep> &_set_active_dep)
+-    : vs_multiplex(false),
+-      solution_tree(solution_undo_tree::create()), story_tree(solution_undo_tree::create()),
+-      set_short_description(_set_short_description),
+-      set_active_dep(_set_active_dep)
+-  {
+-    add_visible_widget(solution_tree, true);
+-    add_visible_widget(story_tree, true);
+-    solution_tree->show();
+-
+-    attach_apt_cache_signals();
+-
+-    cache_closed.connect(sigc::mem_fun(*this, &solution_examiner::update));
+-    cache_reloaded.connect(sigc::mem_fun(*this, &solution_examiner::handle_cache_reload));
+-
+-    cycled.connect(sigc::mem_fun(*this, &solution_examiner::update_highlights));
+-
+-    vscreen_addtimeout(new slot_event(sigc::mem_fun(this, &solution_examiner::tick)), 1000);
+-
+-    // Because the update event might destroy this object, it needs to
+-    // take place after the constructor returns.
+-    vscreen_post_event(new slot_event(sigc::mem_fun(this, &solution_examiner::update)));
+-  }
+-
+-  bool handle_key(const key &k)
+-  {
+-    vs_widget_ref tmpref(this);
+-
+-    if(global_bindings.key_matches(k, "CycleOrder"))
+-      cycle_forward();
+-    else
+-      return vs_multiplex::handle_key(k);
+-
+-    return true;
+-  }
+-public:
+-  void connect_menu_signals()
+-  {
+-    create_menu_bindings(story_tree.unsafe_get_ref(), story_tree);
+-    create_menu_bindings(solution_tree.unsafe_get_ref(), solution_tree);
+-  }
+-
+-  static ref_ptr<solution_examiner> create(const sigc::slot1<void, fragment *> &set_short_description,
+-					   const sigc::slot1<void, aptitude_resolver_dep> &set_active_dep)
+-  {
+-    ref_ptr<solution_examiner>
+-      rval(new solution_examiner(set_short_description, set_active_dep));
+-    rval->decref();
+-    return rval;
+-  }
+-
+-  void paint(const style &st)
+-  {
+-    if(apt_cache_file == NULL)
+-      update();
+-
+-    vs_multiplex::paint(st);
+-  }
+-
+-  void update()
+-  {
+-    ref_ptr<solution_examiner> tmpref(this);
+-
+-    if(!apt_cache_file)
+-      {
+-	set_static_root(transcode(_("The package cache is not available.")));
+-	set_active_dep(aptitude_resolver_dep());
+-	return;
+-      }
+-
+-    if(!resman->resolver_exists())
+-      {
+-	set_static_root(transcode(_("No broken packages.")));
+-	set_short_description(fragf(""));
+-	set_active_dep(aptitude_resolver_dep());
+-	return;
+-      }
+-
+-    resolver_manager::state state = resman->state_snapshot();
+-    update_from_state(state);
+-  }
+-
+-  void update_from_state(const resolver_manager::state &state)
+-  {
+-    vs_widget_ref tmpref(this);
+-
+-    if(state.solutions_exhausted && state.generated_solutions == 0)
+-      {
+-	set_static_root(transcode(_("No resolution found.")));
+-	last_sol.nullify();
+-	return;
+-      }
+-
+-    if(state.selected_solution >= state.generated_solutions)
+-      {
+-	wstring generation_info = swsprintf(transcode(_("open: %d; closed: %d; defer: %d; conflict: %d")).c_str(),
+-					    state.open_size, state.closed_size,
+-					    state.deferred_size, state.conflicts_size);
+-
+-	wstring msg = transcode(_("Resolving dependencies..."));
+-
+-	vs_subtree_generic *sol_root = new label_tree(msg);
+-	sol_root->add_child(new vs_layout_item(hardwrapbox(text_fragment(generation_info))));
+-
+-	vs_subtree_generic *story_root = new label_tree(msg);
+-	story_root->add_child(new vs_layout_item(hardwrapbox(text_fragment(generation_info))));
+-
+-	solution_tree->set_root(sol_root, true);
+-	story_tree->set_root(story_root, true);
+-
+-	last_sol.nullify();
+-	return;
+-      }
+-
+-    aptitude_solution sol = resman->get_solution(state.selected_solution, 0);
+-
+-    if(sol == last_sol)
+-      return;
+-
+-    last_sol = sol;
+-
+-    if(sol.get_actions().empty())
+-      set_static_root(transcode(_("Internal error: unexpected null solution.")));
+-    else
+-      {
+-	solution_tree->set_root(make_solution_tree(sol, set_short_description, set_active_dep));
+-	story_tree->set_root(make_story_tree(sol, set_short_description, set_active_dep));
+-      }
+-
+-    update_highlights();
+-  }
+-};
+-
+-typedef ref_ptr<solution_examiner> solution_examiner_ref;
+-
+-static
+-void update_dep_display(aptitude_resolver_dep d, vs_tree *tBare)
+-{
+-  vs_tree_ref t(tBare);
+-
+-  if(d.get_dep().end())
+-    t->set_root(NULL);
+-  else
+-    t->set_root(make_dep_solvers_tree(d));
+-}
+-
+-static
+-void maybe_remove_examiner(vscreen_widget &wBare)
+-{
+-  vs_widget_ref w(&wBare);
+-
+-  if(resman && !resman->resolver_exists())
+-    w->destroy();
+-}
+-
+-vs_widget_ref make_solution_screen()
+-{
+-  vs_table_ref rval     = vs_table::create();
+-
+-  vs_label_ref l        = vs_label::create(L"");
+-  menu_tree_ref info_tree = solution_undo_tree::create();
+-
+-  solution_examiner_ref examiner
+-    = solution_examiner::create(sigc::mem_fun(l.unsafe_get_ref(),
+-					      (void (vs_label::*) (fragment *)) &vs_label::set_text),
+-				sigc::bind(sigc::ptr_fun(update_dep_display),
+-					   info_tree.unsafe_get_ref()));
+-
+-
+-  examiner->connect_menu_signals();
+-  create_menu_bindings(info_tree.unsafe_get_ref(), info_tree);
+-
+-
+-  info_tree->connect_key("ShowHideDescription", &global_bindings,
+-			 sigc::mem_fun(info_tree.unsafe_get_ref(),
+-				       &vscreen_widget::toggle_visible));
+-
+-  l->set_bg_style(get_style("Status"));
+-
+-  rval->add_widget_opts(examiner,
+-			0, 0, 1, 1, vs_table::EXPAND | vs_table::FILL,
+-			vs_table::EXPAND | vs_table::FILL | vs_table::SHRINK);
+-  rval->add_widget_opts(l,
+-			1, 0, 1, 1, vs_table::EXPAND | vs_table::FILL,
+-			0);
+-
+-  rval->add_widget_opts(info_tree,
+-			2, 0, 1, 1, vs_table::EXPAND | vs_table::FILL,
+-			vs_table::EXPAND | vs_table::FILL | vs_table::SHRINK);
+-
+-
+-  cache_reloaded.connect(sigc::bind(sigc::ptr_fun(&maybe_remove_examiner),
+-				    rval.weak_ref()));
+-  if(resman)
+-    resman->state_changed.connect(sigc::bind(sigc::ptr_fun(&maybe_remove_examiner),
+-					     rval.weak_ref()));
+-
+-
+-  l->show();
+-  examiner->show();
+-  info_tree->show();
+-
+-  return rval;
+-}
+diff --git a/src/solution_screen.h b/src/solution_screen.h
+deleted file mode 100644
+index b2c2d0c..0000000
+--- a/src/solution_screen.h
++++ /dev/null
+@@ -1,37 +0,0 @@
+-// solution_screen.h                          -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#ifndef SOLUTION_SCREEN_H
+-#define SOLUTION_SCREEN_H
+-
+-#include <vscreen/ref_ptr.h>
+-
+-class aptitude_universe;
+-template<class PackageUniverse> class generic_solution;
+-class vscreen_widget;
+-
+-typedef generic_solution<aptitude_universe> aptitude_solution;
+-typedef ref_ptr<vscreen_widget> vs_widget_ref;
+-
+-/** Generate a new widget suitable for inclusion at the top-level
+- *  which describes the given solution.
+- */
+-vs_widget_ref make_solution_screen();
+-
+-#endif // SOLUTION_SCREEN_H
+diff --git a/src/ui.cc b/src/ui.cc
+index 6471bb1..24ab473 100644
+--- a/src/ui.cc
++++ b/src/ui.cc
+@@ -50,14 +50,10 @@
+ 
+ #include "apt_config_widgets.h"
+ #include "apt_options.h"
+-#include "broken_indicator.h"
+ #include "defaults.h"
+ #include "load_config.h"
+ #include "load_grouppolicy.h"
+ #include "load_pkgview.h"
+-#include "solution_dialog.h"
+-#include "solution_fragment.h"
+-#include "solution_screen.h"
+ 
+ #include <vscreen/curses++.h>
+ #include <vscreen/fragment.h>
+@@ -85,15 +81,11 @@
+ 
+ #include <generic/apt/apt.h>
+ #include <generic/apt/apt_undo_group.h>
+-#include <generic/apt/aptitude_resolver_universe.h>
+ #include <generic/apt/config_signal.h>
+ #include <generic/apt/download_install_manager.h>
+ #include <generic/apt/download_update_manager.h>
+ #include <generic/apt/download_signal_log.h>
+-#include <generic/apt/resolver_manager.h>
+-
+-#include <generic/problemresolver/exceptions.h>
+-#include <generic/problemresolver/solution.h>
++#include <generic/apt/matchers.h>
+ 
+ #include <generic/util/temp.h>
+ #include <generic/util/util.h>
+@@ -114,8 +106,6 @@
+ 
+ using namespace std;
+ 
+-typedef generic_solution<aptitude_universe> aptitude_solution;
+-
+ static vs_menubar_ref main_menu;
+ static vs_menu_ref views_menu;
+ 
+@@ -152,7 +142,6 @@ sigc::signal0<void> package_states_changed;
+ sigc::signal0<bool, accumulate_or> package_menu_enabled;
+ sigc::signal0<bool, accumulate_or> package_forbid_enabled;
+ sigc::signal0<bool, accumulate_or> package_information_enabled;
+-sigc::signal0<bool, accumulate_or> package_changelog_enabled;
+ 
+ sigc::signal0<bool, accumulate_or> find_search_enabled;
+ sigc::signal0<bool, accumulate_or> find_search_back_enabled;
+@@ -163,21 +152,12 @@ sigc::signal0<bool, accumulate_or> find_broken_enabled;
+ 
+ sigc::signal0<bool, accumulate_or> package_install;
+ sigc::signal0<bool, accumulate_or> package_remove;
+-sigc::signal0<bool, accumulate_or> package_purge;
+ sigc::signal0<bool, accumulate_or> package_hold;
+ sigc::signal0<bool, accumulate_or> package_keep;
+ sigc::signal0<bool, accumulate_or> package_mark_auto;
+ sigc::signal0<bool, accumulate_or> package_unmark_auto;
+ sigc::signal0<bool, accumulate_or> package_forbid;
+ sigc::signal0<bool, accumulate_or> package_information;
+-sigc::signal0<bool, accumulate_or> package_changelog;
+-
+-sigc::signal0<bool, accumulate_or> resolver_toggle_rejected;
+-sigc::signal0<bool, accumulate_or> resolver_toggle_rejected_enabled;
+-sigc::signal0<bool, accumulate_or> resolver_toggle_approved;
+-sigc::signal0<bool, accumulate_or> resolver_toggle_approved_enabled;
+-sigc::signal0<bool, accumulate_or> resolver_view_target;
+-sigc::signal0<bool, accumulate_or> resolver_view_target_enabled;
+ 
+ sigc::signal0<bool, accumulate_or> find_search;
+ sigc::signal0<bool, accumulate_or> find_search_back;
+@@ -188,7 +168,7 @@ sigc::signal0<bool, accumulate_or> find_broken;
+ 
+ const char *default_pkgstatusdisplay="%d";
+ const char *default_pkgheaderdisplay="%N %n #%B %u %o";
+-const char *default_grpstr="task,status,section(subdir,passthrough),section(topdir)";
++const char *default_grpstr="status,section(none)";
+ 
+ void ui_start_download(bool hide_preview)
+ {
+@@ -377,117 +357,6 @@ static void do_connect_read_only_callbacks()
+     }
+ }
+ 
+-// Runs a sub-aptitude with the same selections that the user
+-// has currently made, but as root.
+-//
+-// Because tagfiles don't work on FIFOs, and su closes all open fds,
+-// this is a lot hairier than it should be.
+-//
+-// This writes the current status to a file in a designated temporary
+-// directory, then loads it in a su'd instance.  A FIFO is used to
+-// make the reader block until the writer is done writing.  Not
+-// foolproof but the user would have to go to a lot of pointless
+-// trouble to screw it up.
+-//
+-// Note that the deletion of the temporary files is safe, since this
+-// routine blocks until the sub-process exits.
+-
+-static void do_su_to_root(string args)
+-{
+-  if(getuid()==0)
+-    {
+-      show_message(_("You already are root!"));
+-      return;
+-    }
+-
+-  temp::dir  tempdir("aptitude");
+-  temp::name statusname(tempdir, "pkgstates");
+-  temp::name fifoname(tempdir, "control");
+-
+-  if(mkfifo(fifoname.get_name().c_str(), 0600) != 0)
+-    {
+-      _error->Errno("do_su_to_root",
+-		    "Couldn't create temporary FIFO");
+-      return;
+-    }
+-
+-  int pid=fork();
+-
+-  if(pid==-1)
+-    _error->Error("Unable to fork: %s", strerror(errno));
+-  else if(pid==0) // I'm a child!
+-    {
+-      // Read one byte from the FIFO for synchronization
+-      char tmp;
+-      int fd = open(fifoname.get_name().c_str(), O_RDONLY);
+-      read(fd, &tmp, 1); // Will block until the other process writes.
+-      close(fd);
+-
+-      // It's ok to use argv0 to generate the command,
+-      // since the user has to authenticate themselves as root (ie, if
+-      // they're going to do something evil that way they'd have su'd
+-      // directly)
+-      //
+-      // What happens if tmpdir has spaces in it?  Can I get more
+-      // control over how the su-to-root function is called?
+-      char cmdbuf[512];
+-      snprintf(cmdbuf, 512, "%s -S %s %s",
+-	       argv0, statusname.get_name().c_str(), args.c_str());
+-      execl("/bin/su", "/bin/su", "-c", cmdbuf, NULL);
+-    }
+-  else
+-    {
+-      int status;
+-      OpProgress foo; // Need a generic non-outputting progress bar
+-
+-      // Save the selection list.  Check first if it's NULL to handle the
+-      // case of a closed cache.
+-      if(apt_cache_file != NULL)
+-	(*apt_cache_file)->save_selection_list(foo, statusname.get_name().c_str());
+-
+-      // Shut curses down.
+-      vscreen_suspend();
+-
+-      // Ok, wake the other process up.
+-      char tmp=0;
+-      int fd=open(fifoname.get_name().c_str(), O_WRONLY);
+-      write(fd, &tmp, 1);
+-      close(fd);
+-
+-      // Wait for a while so we don't accidentally daemonize ourselves.
+-      while(waitpid(pid, &status, 0)!=pid)
+-	;
+-
+-      if(!WIFEXITED(status) || WEXITSTATUS(status))
+-	{
+-	  _error->Error("%s",
+-			_("Subprocess exited with an error -- did you type your password correctly?"));
+-	  vscreen_resume();
+-	  check_apt_errors();
+-	  // We have to clear these out or the cache won't reload properly (?)
+-
+-	  vs_progress_ref p = gen_progress_bar();
+-	  apt_reload_cache(p.unsafe_get_ref(), true, statusname.get_name().c_str());
+-	  p->destroy();
+-	}
+-      else
+-	{
+-	  // Clear out our references to these objects so they get
+-	  // removed.
+-	  tempdir    = temp::dir();
+-	  statusname = temp::name();
+-	  fifoname   = temp::name();
+-
+-	  exit(0);
+-	}
+-    }
+-}
+-
+-static bool su_to_root_enabled()
+-{
+-  return getuid()!=0;
+-}
+-
+ static void update_menubar_autohide()
+ {
+   main_menu->set_always_visible(main_multiplex->num_children()==0 ||
+@@ -692,7 +561,8 @@ void do_new_package_view(OpProgress &progress)
+       if(!grp)
+ 	// Eek!  The default grouping failed to parse.  Fall all the
+ 	// way back.
+-	grp=new pkg_grouppolicy_task_factory(new pkg_grouppolicy_status_factory(new pkg_grouppolicy_section_factory(pkg_grouppolicy_section_factory::split_subdir,true,new pkg_grouppolicy_section_factory(pkg_grouppolicy_section_factory::split_topdir,false,new pkg_grouppolicy_end_factory()))));
++	// status,section(none,nopassthrough)
++	grp=new pkg_grouppolicy_status_factory(new pkg_grouppolicy_section_factory(pkg_grouppolicy_section_factory::split_none,false,new pkg_grouppolicy_end_factory()));
+     }
+ 
+   pkg_tree_ref tree=pkg_tree::create(grpstr.c_str(), grp);
+@@ -715,29 +585,6 @@ static void do_new_package_view_with_new_bar()
+   p->destroy();
+ }
+ 
+-static void do_new_recommendations_view()
+-{
+-  vs_progress_ref p = gen_progress_bar();
+-
+-  pkg_grouppolicy_factory *grp = new pkg_grouppolicy_end_factory();
+-  std::string grpstr="section(subdir, passthrough)";
+-
+-  pkg_tree_ref tree=pkg_tree::create(grpstr.c_str(), grp,
+-				     L"!~v!~i~RBrecommends:~i");
+-
+-  add_main_widget(make_default_view(tree,
+-				    &tree->selected_signal,
+-				    &tree->selected_desc_signal,
+-				    true,
+-				    true),
+-		  _("Recommended Packages"),
+-		  _("View packages that it is recommended that you install"),
+-		  _("Recommendations"));
+-
+-  tree->build_tree(*p.unsafe_get_ref());
+-  p->destroy();
+-}
+-
+ static void do_new_flat_view_with_new_bar()
+ {
+   vs_progress_ref p = gen_progress_bar();
+@@ -757,56 +604,6 @@ static void do_new_flat_view_with_new_bar()
+   p->destroy();
+ }
+ 
+-static void do_new_tag_view_with_new_bar()
+-{
+-  vs_progress_ref p = gen_progress_bar();
+-
+-  pkg_grouppolicy_factory *grp = NULL;
+-  string grpstr = "tag";
+-  grp = parse_grouppolicy(grpstr);
+-
+-  pkg_tree_ref tree = pkg_tree::create(grpstr.c_str(), grp);
+-
+-  add_main_widget(make_default_view(tree,
+-				    &tree->selected_signal,
+-				    &tree->selected_desc_signal),
+-		  _("Packages"),
+-		  _("View available packages and choose actions to perform"),
+-		  _("Packages"));
+-
+-  tree->build_tree(*p.unsafe_get_ref());
+-  p->destroy();
+-}
+-
+-void do_new_hier_view(OpProgress &progress)
+-{
+-  pkg_grouppolicy_factory *grp=NULL;
+-  std::string grpstr="";
+-
+-  grpstr="hier";
+-  grp=parse_grouppolicy(grpstr);
+-
+-  pkg_tree_ref tree=pkg_tree::create(grpstr.c_str(), grp);
+-  tree->set_limit(transcode("!~v"));
+-  //tree->set_hierarchical(false);
+-
+-  add_main_widget(make_default_view(tree,
+-				    &tree->selected_signal,
+-				    &tree->selected_desc_signal),
+-		  _("Packages"),
+-		  _("View available packages and choose actions to perform"),
+-		  _("Packages"));
+-  tree->build_tree(progress);
+-}
+-
+-// For signal connections.
+-static void do_new_hier_view_with_new_bar()
+-{
+-  vs_progress_ref p=gen_progress_bar();
+-  do_new_hier_view(*p.unsafe_get_ref());
+-  p->destroy();
+-}
+-
+ vs_widget_ref make_info_screen(const pkgCache::PkgIterator &pkg,
+ 			       const pkgCache::VerIterator &ver)
+ {
+@@ -1210,65 +1007,6 @@ static void do_keep_all()
+     apt_undos->add_item(undo.release());
+ }
+ 
+-static void fixer_dialog_done()
+-{
+-  if(active_preview_tree.valid())
+-    active_preview_tree->build_tree();
+-  do_package_run_or_show_preview();
+-}
+-
+-static void install_fixer_dialog()
+-{
+-  vs_widget_ref w=make_solution_dialog();
+-  w->destroyed.connect(sigc::ptr_fun(fixer_dialog_done));
+-  popup_widget(w, true);
+-}
+-
+-// FIXME: blocks.
+-static void auto_fix_broken()
+-{
+-  undo_group *undo=new apt_undo_group;
+-
+-  try
+-    {
+-      eassert(resman != NULL);
+-      eassert(resman->resolver_exists());
+-
+-      aptitude_solution sol = resman->get_solution(resman->get_selected_solution(), 0);
+-
+-      (*apt_cache_file)->apply_solution(sol, undo);
+-
+-      vs_widget_ref d = vs_dialog_ok(fragf("%s%n%n%F",
+-					   _("Some packages were broken and have been fixed:"),
+-					   solution_fragment(sol)),
+-				     NULL);
+-
+-      popup_widget(d, true);
+-    }
+-  catch(NoMoreSolutions)
+-    {
+-      show_message(_("No solution to these dependency problems exists!"),
+-		   NULL,
+-		   get_style("Error"));
+-    }
+-  catch(NoMoreTime)
+-    {
+-      show_message(fragf(_("Ran out of time while trying to resolve dependencies (press \"%s\" to try harder)"),
+-			 global_bindings.readable_keyname("NextSolution").c_str()),
+-		   NULL,
+-		   get_style("Error"));
+-    }
+-
+-  if(!undo->empty())
+-    apt_undos->add_item(undo);
+-  else
+-    delete undo;
+-
+-  if(active_preview_tree.valid())
+-    active_preview_tree->build_tree();
+-}
+-
+-
+ //  Huge FIXME: the preview interacts badly with the menu.  This can be solved
+ // in a couple ways, including having the preview be a popup dialog -- the best
+ // thing IMO, though, would be to somehow allow particular widgets to override
+@@ -1284,14 +1022,6 @@ static void actually_do_package_run()
+ 	  // routine.
+ 	  if((*apt_cache_file)->BrokenCount()>0)
+ 	    {
+-	      if(_config->FindB(PACKAGE "::Auto-Fix-Broken", true))
+-		{
+-		  auto_fix_broken();
+-		  do_show_preview();
+-		}
+-	      else
+-		install_fixer_dialog();
+-
+ 	      return;
+ 	    }
+ 
+@@ -1299,13 +1029,9 @@ static void actually_do_package_run()
+ 	    check_package_trust();
+ 	  else
+ 	    {
+-	      popup_widget(vs_dialog_yesno(wrapbox(text_fragment(_("Installing/removing packages requires administrative privileges, which you currently do not have.  Would you like to change to the root account?"))),
+-					   arg(sigc::bind(sigc::ptr_fun(&do_su_to_root),
+-						      "-i")),
+-					   transcode(_("Become root")),
+-					   arg(sigc::ptr_fun(&check_package_trust)),
+-					   transcode(_("Don't become root")),
+-					   get_style("Error")));
++	      popup_widget(vs_dialog_ok(wrapbox(text_fragment(_("Installing/removing packages requires administrative privileges, which you currently do not have."))),
++					NULL,
++					get_style("Error")));
+ 	    }
+ 	}
+       else
+@@ -1383,17 +1109,7 @@ void do_package_run()
+     {
+       if(active_preview_tree.valid() && active_preview_tree->get_visible())
+ 	actually_do_package_run();
+-      else if((*apt_cache_file)->BrokenCount()>0)
+-	{
+-	  if(aptcfg->FindB(PACKAGE "::Auto-Fix-Broken", true))
+-	    {
+-	      auto_fix_broken();
+-	      do_package_run_or_show_preview();
+-	    }
+-	  else
+-	    install_fixer_dialog();
+-	}
+-      else
++      else if((*apt_cache_file)->BrokenCount() == 0)
+ 	do_package_run_or_show_preview();
+     }
+ }
+@@ -1428,13 +1144,9 @@ void do_update_lists()
+ 	really_do_update_lists();
+       else
+ 	{
+-	  popup_widget(vs_dialog_yesno(wrapbox(text_fragment(_("Updating the package lists requires administrative privileges, which you currently do not have.  Would you like to change to the root account?"))),
+-				       arg(sigc::bind(sigc::ptr_fun(&do_su_to_root),
+-						      "-u")),
+-				       transcode(_("Become root")),
+-				       arg(sigc::ptr_fun(&really_do_update_lists)),
+-				       transcode(_("Don't become root")),
+-				       get_style("Error")));
++	  popup_widget(vs_dialog_ok(wrapbox(text_fragment(_("Updating the package lists requires administrative privileges, which you currently do not have."))),
++				    NULL,
++				    get_style("Error")));
+ 	}
+     }
+   else
+@@ -1590,320 +1302,6 @@ static void do_reload_cache()
+ }
+ #endif
+ 
+-static void start_solution_calculation(bool blocking = true);
+-
+-class interactive_continuation : public resolver_manager::background_continuation
+-{
+-  /** The manager associated with this continuation; usually resman. */
+-  resolver_manager *manager;
+-
+-  /** Indicate that a new solution is available by invoking the
+-   *  selection_changed signal.
+-   */
+-  class success_event : public vscreen_event
+-  {
+-    resolver_manager *manager;
+-  public:
+-    success_event(resolver_manager *_manager)
+-      :manager(_manager)
+-    {
+-    }
+-
+-    void dispatch()
+-    {
+-      manager->state_changed();
+-    }
+-  };
+-
+-  class no_more_solutions_event : public vscreen_event
+-  {
+-    resolver_manager *manager;
+-  public:
+-    no_more_solutions_event(resolver_manager *_manager)
+-      :manager(_manager)
+-    {
+-    }
+-
+-    void dispatch()
+-    {
+-      resolver_manager::state st = manager->state_snapshot();
+-
+-      if(st.selected_solution == st.generated_solutions)
+-	manager->select_previous_solution();
+-      show_message(_("No more solutions."));
+-
+-      manager->state_changed();
+-    }
+-  };
+-public:
+-  interactive_continuation(resolver_manager *_manager)
+-    :manager(_manager)
+-  {
+-  }
+-
+-  void success(const aptitude_solution &sol)
+-  {
+-    vscreen_post_event(new success_event(manager));
+-  }
+-
+-  void no_more_solutions()
+-  {
+-    vscreen_post_event(new no_more_solutions_event(manager));
+-  }
+-
+-  void no_more_time()
+-  {
+-    start_solution_calculation(false);
+-  }
+-
+-  void interrupted()
+-  {
+-  }
+-};
+-
+-// If the current solution pointer is past the end of the solution
+-// list, queue up a calculation for it in the background thread.  If
+-// "blocking" is true, then the calling thread will wait for the
+-// background resolver thread to finish its calculation before
+-// returning from this function.  IF THE CALLING THREAD IS THE
+-// BACKGROUND THREAD THIS WILL DEADLOCK IF BLOCKING IS TRUE! (see above for such a case)
+-static void start_solution_calculation(bool blocking)
+-{
+-  resolver_manager::state state = resman->state_snapshot();
+-
+-  if(state.resolver_exists &&
+-     state.selected_solution == state.generated_solutions &&
+-     !state.solutions_exhausted &&
+-     !state.background_thread_active)
+-    {
+-      const int selected = state.selected_solution;
+-      const int limit = aptcfg->FindI(PACKAGE "::ProblemResolver::StepLimit", 5000);
+-      const int wait_steps = aptcfg->FindI(PACKAGE "::ProblemResolver::WaitSteps", 50);
+-      interactive_continuation * const k = new interactive_continuation(resman);
+-
+-      if(blocking)
+-	resman->get_solution_background_blocking(selected, limit, wait_steps, k);
+-      else
+-	resman->get_solution_background(selected, limit, k);
+-    }
+-}
+-
+-static void do_connect_resolver_callback()
+-{
+-  resman->state_changed.connect(sigc::bind(sigc::ptr_fun(&start_solution_calculation), true));
+-  // We may have missed a signal before making the connection:
+-  start_solution_calculation();
+-  resman->state_changed.connect(sigc::ptr_fun(&vscreen_update));
+-}
+-
+-static bool do_next_solution_enabled()
+-{
+-  if(resman == NULL)
+-    return false;
+-
+-  resolver_manager::state state = resman->state_snapshot();
+-
+-  return
+-    state.selected_solution < state.generated_solutions &&
+-    !(state.selected_solution + 1 == state.generated_solutions &&
+-      state.solutions_exhausted);
+-}
+-
+-void do_next_solution()
+-{
+-  if(!do_next_solution_enabled())
+-    beep();
+-  else
+-    resman->select_next_solution();
+-}
+-
+-static bool do_previous_solution_enabled()
+-{
+-  if(resman == NULL)
+-    return false;
+-
+-  resolver_manager::state state = resman->state_snapshot();
+-
+-  return state.selected_solution > 0;
+-}
+-
+-void do_previous_solution()
+-{
+-  if(!do_previous_solution_enabled())
+-    beep();
+-  else
+-    resman->select_previous_solution();
+-}
+-
+-static bool do_first_solution_enabled()
+-{
+-  if(resman == NULL)
+-    return false;
+-
+-  resolver_manager::state state = resman->state_snapshot();
+-
+-  return state.resolver_exists && state.selected_solution > 0;
+-}
+-
+-static void do_first_solution()
+-{
+-  if(!do_first_solution_enabled())
+-    beep();
+-  else
+-    resman->select_solution(0);
+-}
+-
+-static bool do_last_solution_enabled()
+-{
+-  if(resman == NULL)
+-    return false;
+-
+-  resolver_manager::state state = resman->state_snapshot();
+-
+-  return state.resolver_exists && state.selected_solution + 1 < state.generated_solutions;
+-}
+-
+-static void do_last_solution()
+-{
+-  if(resman == NULL)
+-    {
+-      beep();
+-      return;
+-    }
+-
+-  resolver_manager::state state = resman->state_snapshot();
+-
+-  if(!(state.resolver_exists && state.selected_solution + 1 < state.generated_solutions))
+-    beep();
+-  else
+-    resman->select_solution(state.generated_solutions - 1);
+-}
+-
+-static bool do_apply_solution_enabled_from_state(const resolver_manager::state &state)
+-{
+-  return
+-    state.resolver_exists &&
+-    state.selected_solution >= 0 &&
+-    state.selected_solution < state.generated_solutions;
+-}
+-
+-static bool do_apply_solution_enabled()
+-{
+-  if(resman == NULL)
+-    return false;
+-
+-  resolver_manager::state state = resman->state_snapshot();
+-  return do_apply_solution_enabled_from_state(state);
+-}
+-
+-void do_apply_solution()
+-{
+-  if(!apt_cache_file)
+-    return;
+-
+-  resolver_manager::state state = resman->state_snapshot();
+-
+-  if(!do_apply_solution_enabled_from_state(state))
+-    {
+-      beep();
+-      return;
+-    }
+-  else
+-    {
+-      undo_group *undo=new apt_undo_group;
+-      try
+-	{
+-	  (*apt_cache_file)->apply_solution(resman->get_solution(state.selected_solution, aptcfg->FindI(PACKAGE "::ProblemResolver::StepLimit", 5000)),
+-					    undo);
+-	}
+-      catch(NoMoreSolutions)
+-	{
+-	  show_message(_("Unable to find a solution to apply."),
+-		       NULL,
+-		       get_style("Error"));
+-	}
+-      catch(NoMoreTime)
+-	{
+-	  show_message(_("Ran out of time while trying to find a solution."),
+-		       NULL,
+-		       get_style("Error"));
+-	}
+-
+-      if(!undo->empty())
+-	{
+-	  apt_undos->add_item(undo);
+-	  package_states_changed();
+-	}
+-      else
+-	delete undo;
+-    }
+-}
+-
+-static void do_nullify_solver(vs_widget_ref *solver)
+-{
+-  *solver = NULL;
+-}
+-
+-static bool do_examine_solution_enabled()
+-{
+-  return resman != NULL && resman->resolver_exists();
+-}
+-
+-void do_examine_solution()
+-{
+-  if(!do_examine_solution_enabled())
+-    {
+-      beep();
+-      return;
+-    }
+-
+-  static vs_widget_ref solver;
+-
+-  if(solver.valid())
+-    solver->show();
+-  else
+-    {
+-      solver = make_solution_screen();
+-      solver->destroyed.connect(sigc::bind(sigc::ptr_fun(&do_nullify_solver),
+-					   &solver));
+-
+-      add_main_widget(solver, _("Resolve Dependencies"),
+-		      _("Search for solutions to unsatisfied dependencies"),
+-		      _("Resolve Dependencies"));
+-    }
+-}
+-
+-static void handle_dump_resolver_response(const wstring &s)
+-{
+-  if(resman != NULL && resman->resolver_exists())
+-    {
+-      ofstream out(transcode(s).c_str());
+-
+-      if(!out)
+-	_error->Errno("dump_resolver", _("Unable to open %ls"), s.c_str());
+-      else
+-	{
+-	  resman->dump(out);
+-
+-	  if(!out)
+-	    _error->Errno("dump_resolver", _("Error while dumping resolver state"));
+-	}
+-    }
+-}
+-
+-static void do_dump_resolver()
+-{
+-  static vs_editline::history_list history;
+-
+-  if(resman != NULL && resman->resolver_exists())
+-    prompt_string(_("File to which the resolver state should be dumped:"),
+-		  "",
+-		  arg(sigc::ptr_fun(handle_dump_resolver_response)),
+-		  NULL,
+-		  NULL,
+-		  &history);
+-}
+-
+ // NOTE ON TRANSLATIONS!
+ //
+ //   Implicitly translating stuff in the widget set would be ugly.  Everything
+@@ -1968,9 +1366,6 @@ vs_menu_info actions_menu[]={
+ 
+   VS_MENU_SEPARATOR,
+ 
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("^Become root"), NULL,
+-	       N_("Run 'su' to become root; this will restart the program, but your settings will be preserved"), sigc::bind(sigc::ptr_fun(do_su_to_root), ""), sigc::ptr_fun(su_to_root_enabled)),
+-
+   vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("^Quit"), "QuitProgram",
+ 	       N_("Exit the program"), sigc::ptr_fun(do_quit)),
+ 
+@@ -1995,10 +1390,6 @@ vs_menu_info package_menu[]={
+ 	       N_("Flag the currently selected package for removal"),
+ 	       sigc::hide_return(package_remove.make_slot()),
+ 	       package_menu_enabled.make_slot()),
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("^Purge"), "Purge",
+-	       N_("Flag the currently selected package and its configuration files for removal"),
+-	       sigc::hide_return(package_purge.make_slot()),
+-	       package_menu_enabled.make_slot()),
+   vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("^Keep"), "Keep",
+ 	       N_("Cancel any action on the selected package"),
+ 	       sigc::hide_return(package_keep.make_slot()),
+@@ -2024,56 +1415,6 @@ vs_menu_info package_menu[]={
+ 	       N_("Display more information about the selected package"),
+ 	       sigc::hide_return(package_information.make_slot()),
+ 	       package_information_enabled.make_slot()),
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("^Changelog"), "Changelog",
+-	       N_("Display the Debian changelog of the selected package"),
+-	       sigc::hide_return(package_changelog.make_slot()),
+-	       package_changelog_enabled.make_slot()),
+-  VS_MENU_END
+-};
+-
+-vs_menu_info resolver_menu[] = {
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("^Examine Solution"),
+-	       "ExamineSolution", N_("Examine the currently selected solution to the dependency problems."),
+-	       sigc::ptr_fun(do_examine_solution),
+-	       sigc::ptr_fun(do_examine_solution_enabled)),
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("Apply ^Solution"),
+-	       "ApplySolution", N_("Perform the actions contained in the currently selected solution."),
+-	       sigc::ptr_fun(do_apply_solution),
+-	       sigc::ptr_fun(do_apply_solution_enabled)),
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("^Next Solution"),
+-	       "NextSolution", N_("Select the next solution to the dependency problems."),
+-	       sigc::ptr_fun(do_next_solution),
+-	       sigc::ptr_fun(do_next_solution_enabled)),
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("^Previous Solution"),
+-	       "PrevSolution", N_("Select the previous solution to the dependency problems."),
+-	       sigc::ptr_fun(do_previous_solution),
+-	       sigc::ptr_fun(do_previous_solution_enabled)),
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("^First Solution"),
+-	       "FirstSolution", N_("Select the first solution to the dependency problems."),
+-	       sigc::ptr_fun(do_first_solution),
+-	       sigc::ptr_fun(do_first_solution_enabled)),
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("^Last Solution"),
+-	       "LastSolution", N_("Select the last solution to the dependency problems that has been generated so far."),
+-	       sigc::ptr_fun(do_last_solution),
+-	       sigc::ptr_fun(do_last_solution_enabled)),
+-
+-  VS_MENU_SEPARATOR,
+-
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("Toggle ^Rejected"),
+-	       "SolutionActionReject", N_("Toggle whether the currently selected action is rejected."),
+-	       sigc::hide_return(resolver_toggle_rejected.make_slot()),
+-	       resolver_toggle_rejected_enabled.make_slot()),
+-
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("Toggle ^Approved"),
+-	       "SolutionActionApprove", N_("Toggle whether the currently selected action is approved."),
+-	       sigc::hide_return(resolver_toggle_approved.make_slot()),
+-	       resolver_toggle_approved_enabled.make_slot()),
+-
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("^View Target"),
+-	       "InfoScreen", N_("View the package which will be affected by the selected action"),
+-	       sigc::hide_return(resolver_view_target.make_slot()),
+-	       resolver_view_target_enabled.make_slot()),
+-
+   VS_MENU_END
+ };
+ 
+@@ -2152,25 +1493,10 @@ vs_menu_info views_menu_info[]={
+ 	       N_("Create a new default package view"),
+ 	       sigc::ptr_fun(do_new_package_view_with_new_bar)),
+ 
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("Audit ^Recommendations"), NULL,
+-	       N_("View packages which it is recommended that you install, but which are not currently installed."),
+-	       sigc::ptr_fun(do_new_recommendations_view)),
+-
+   vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("New ^Flat Package List"), NULL,
+ 	       N_("View all the packages on the system in a single uncategorized list"),
+ 	       sigc::ptr_fun(do_new_flat_view_with_new_bar)),
+ 
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("New ^Debtags Browser"),
+-	       NULL,
+-	       N_("Browse packages using Debtags data"),
+-	       sigc::ptr_fun(do_new_tag_view_with_new_bar)),
+-
+-  vs_menu_info(vs_menu_info::VS_MENU_ITEM, N_("New Categorical ^Browser"),
+-	       NULL,
+-	       N_("Browse packages by category"),
+-	       sigc::ptr_fun(do_new_hier_view_with_new_bar)),
+-
+-  VS_MENU_SEPARATOR,
+   VS_MENU_END
+ };
+ 
+@@ -2323,12 +1649,6 @@ void ui_init()
+ 
+   cache_closed.connect(sigc::ptr_fun(do_show_reload_message));
+   cache_reloaded.connect(sigc::ptr_fun(do_hide_reload_message));
+-  cache_reloaded.connect(sigc::ptr_fun(do_connect_resolver_callback));
+-  if(apt_cache_file)
+-    {
+-      do_connect_resolver_callback();
+-      start_solution_calculation();
+-    }
+   cache_reload_failed.connect(sigc::ptr_fun(do_hide_reload_message));
+ 
+   cache_reloaded.connect(sigc::ptr_fun(do_connect_read_only_callbacks));
+@@ -2338,7 +1658,6 @@ void ui_init()
+   add_menu(actions_menu, _("Actions"), menu_description);
+   add_menu(undo_menu, _("Undo"), menu_description);
+   add_menu(package_menu, _("Package"), menu_description);
+-  add_menu(resolver_menu, _("Resolver"), menu_description);
+   add_menu(search_menu, _("Search"), menu_description);
+   add_menu(options_menu, _("Options"), menu_description);
+   views_menu=add_menu(views_menu_info, _("Views"), menu_description);
+@@ -2374,27 +1693,6 @@ void ui_init()
+   main_stacked->connect_key_post("Undo",
+ 				 &global_bindings,
+ 				 sigc::hide_return(undo_undo.make_slot()));
+-  main_stacked->connect_key_post("NextSolution",
+-				 &global_bindings,
+-				 sigc::ptr_fun(do_next_solution));
+-  main_stacked->connect_key_post("PrevSolution",
+-				 &global_bindings,
+-				 sigc::ptr_fun(do_previous_solution));
+-  main_stacked->connect_key_post("FirstSolution",
+-				 &global_bindings,
+-				 sigc::ptr_fun(do_first_solution));
+-  main_stacked->connect_key_post("LastSolution",
+-				 &global_bindings,
+-				 sigc::ptr_fun(do_last_solution));
+-  main_stacked->connect_key_post("ApplySolution",
+-				 &global_bindings,
+-				 sigc::ptr_fun(do_apply_solution));
+-  main_stacked->connect_key_post("ExamineSolution",
+-				 &global_bindings,
+-				 sigc::ptr_fun(do_examine_solution));
+-  main_stacked->connect_key_post("DumpResolver",
+-				 &global_bindings,
+-				 sigc::ptr_fun(do_dump_resolver));
+ 
+   main_table=vs_table::create();
+   main_stacked->add_widget(main_table);
+@@ -2429,11 +1727,6 @@ void ui_init()
+ 			      vs_table::EXPAND | vs_table::FILL | vs_table::SHRINK);
+   main_multiplex->show();
+ 
+-  vs_widget_ref b=make_broken_indicator();
+-  main_table->add_widget_opts(b, 2, 0, 1, 1,
+-			      vs_table::EXPAND | vs_table::FILL | vs_table::SHRINK,
+-			      vs_table::ALIGN_CENTER);
+-
+   main_status_multiplex=vs_multiplex::create();
+   main_status_multiplex->set_bg_style(get_style("Status"));
+   main_table->add_widget_opts(main_status_multiplex, 3, 0, 1, 1,
+@@ -2459,16 +1752,6 @@ void ui_init()
+   //       to setup_columns?
+   pkg_item::pkg_columnizer::setup_columns();
+ 
+-  // Make sure the broken indicator doesn't annoyingly pop up for a
+-  // moment. (hack?)
+-  //
+-  // Note that it *should* be visible if we enter this code from the
+-  // command-line (i.e., with the cache already loaded).  More hack?
+-  if(resman != NULL && resman->resolver_exists())
+-    b->show();
+-  else
+-    b->hide();
+-
+   maybe_show_old_tmpdir_message();
+ }
+ 
+diff --git a/src/ui.h b/src/ui.h
+index d60049f..4135574 100644
+--- a/src/ui.h
++++ b/src/ui.h
+@@ -25,7 +25,6 @@ class OpProgress;
+ 
+ class download_signal_log;
+ class fragment;
+-class pkg_hier;
+ class vs_progress;
+ class vscreen_widget;
+ template<class T> class ref_ptr;
+@@ -68,9 +67,6 @@ extern sigc::signal0<bool, accumulate_or> package_install;
+ /** Emitted for Package -> Remove. */
+ extern sigc::signal0<bool, accumulate_or> package_remove;
+ 
+-/** Emitted for Package -> Purge. */
+-extern sigc::signal0<bool, accumulate_or> package_purge;
+-
+ /** Emitted for Package -> Hold. */
+ extern sigc::signal0<bool, accumulate_or> package_hold;
+ 
+@@ -95,30 +91,6 @@ extern sigc::signal0<bool, accumulate_or> package_information_enabled;
+ /** Emitted for Package -> Package Information. */
+ extern sigc::signal0<bool, accumulate_or> package_information;
+ 
+-/** Tests whether Package -> Changelog is enabled. */
+-extern sigc::signal0<bool, accumulate_or> package_changelog_enabled;
+-
+-/** Emitted for Package -> Changelog. */
+-extern sigc::signal0<bool, accumulate_or> package_changelog;
+-
+-
+-/** Emitted for Resolver -> Toggle Rejected. */
+-extern sigc::signal0<bool, accumulate_or> resolver_toggle_rejected;
+-
+-/** Tests whether Resolver -> Reject/Unreject Action is enabled. */
+-extern sigc::signal0<bool, accumulate_or> resolver_toggle_rejected_enabled;
+-
+-/** Emitted for Resolver -> Toggle Approved. */
+-extern sigc::signal0<bool, accumulate_or> resolver_toggle_approved;
+-
+-/** Tests whether Resolver -> Toggle Approved is enabled. */
+-extern sigc::signal0<bool, accumulate_or> resolver_toggle_approved_enabled;
+-/** Emitted for Resolver -> View Target */
+-extern sigc::signal0<bool, accumulate_or> resolver_view_target;
+-
+-/** Tests whether Resolver -> View Target is enabled. */
+-extern sigc::signal0<bool, accumulate_or> resolver_view_target_enabled;
+-
+ 
+ /** Tests whether Search -> Find is enabled. */
+ extern sigc::signal0<bool, accumulate_or> find_search_enabled;
+diff --git a/src/view_changelog.cc b/src/view_changelog.cc
+deleted file mode 100644
+index 7932fc8..0000000
+--- a/src/view_changelog.cc
++++ /dev/null
+@@ -1,228 +0,0 @@
+-// view_changelog.cc
+-//
+-//   Copyright (C) 2004-2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-#include <vscreen/config/colors.h>
+-#include <vscreen/config/keybindings.h>
+-#include <vscreen/transcode.h>
+-#include <vscreen/vs_pager.h>
+-#include <vscreen/vs_scrollbar.h>
+-#include <vscreen/vs_table.h>
+-#include <vscreen/vs_text_layout.h>
+-
+-#include "changelog_parse.h"
+-#include "download_bar.h"
+-#include "menu_redirect.h"
+-#include "menu_text_layout.h"
+-#include "ui.h"
+-#include "ui_download_manager.h"
+-
+-#include <generic/apt/apt.h>
+-#include <generic/apt/pkg_changelog.h>
+-#include <generic/apt/config_signal.h>
+-#include <generic/apt/download_signal_log.h>
+-
+-#include <generic/util/util.h>
+-
+-#include <sigc++/adaptors/bind.h>
+-#include <sigc++/functors/mem_fun.h>
+-
+-using namespace std;
+-
+-class pkg_changelog_screen : public vs_file_pager, public menu_redirect
+-{
+-  bool last_search_forwards;
+-
+-  void do_search()
+-  {
+-    last_search_forwards = true;
+-
+-    prompt_string(transcode(_("Search for: ")),
+-		  L"",
+-		  arg(sigc::mem_fun(*this, &vs_pager::search_for)),
+-		  NULL,
+-		  NULL,
+-		  NULL);
+-  }
+-
+-  void do_search_back()
+-  {
+-    last_search_forwards = false;
+-
+-    prompt_string(transcode(_("Search backwards for: ")),
+-		  L"",
+-		  arg(sigc::mem_fun(*this, &vs_pager::search_back_for)),
+-		  NULL,
+-		  NULL,
+-		  NULL);
+-  }
+-
+-  void do_repeat_search()
+-  {
+-    if(last_search_forwards)
+-      search_for(L"");
+-    else
+-      search_back_for(L"");
+-  }
+-
+-protected:
+-  pkg_changelog_screen(const temp::name &filename,
+-		       int x = 0, int y = 0,
+-		       int width = 0, int height = 0):
+-    vs_file_pager(filename.get_name()), last_search_forwards(true)
+-  {
+-    connect_key("Search", &global_bindings,
+-		sigc::mem_fun(*this, &pkg_changelog_screen::do_search));
+-    connect_key("SearchBack", &global_bindings,
+-		sigc::mem_fun(*this, &pkg_changelog_screen::do_search_back));
+-    connect_key("ReSearch", &global_bindings,
+-		sigc::mem_fun(*this, &pkg_changelog_screen::do_repeat_search));
+-  }
+-
+-public:
+-  static ref_ptr<pkg_changelog_screen>
+-  create(const temp::name &filename,
+-	 int x = 0, int y = 0, int width = 0, int height = 0)
+-  {
+-    ref_ptr<pkg_changelog_screen>
+-      rval(new pkg_changelog_screen(filename, x, y, width, height));
+-    rval->decref();
+-    return rval;
+-  }
+-
+-  bool find_search_enabled()
+-  {
+-    return true;
+-  }
+-
+-  bool find_search()
+-  {
+-    do_search();
+-    return true;
+-  }
+-
+-  bool find_search_back_enabled()
+-  {
+-    return true;
+-  }
+-
+-  bool find_search_back()
+-  {
+-    do_search_back();
+-    return true;
+-  }
+-
+-  bool find_research_enabled()
+-  {
+-    return !get_last_search().empty();
+-  }
+-
+-  bool find_research()
+-  {
+-    do_repeat_search();
+-    return true;
+-  }
+-};
+-typedef ref_ptr<pkg_changelog_screen> pkg_changelog_screen_ref;
+-
+-
+-static void do_view_changelog(temp::name n,
+-			      string pkgname,
+-			      string curverstr)
+-{
+-  string menulabel =
+-    ssprintf(_("ChangeLog of %s"), pkgname.c_str());
+-  string tablabel = ssprintf(_("%s changes"), pkgname.c_str());
+-  string desclabel = _("View the list of changes made to this Debian package.");
+-
+-  fragment *f = make_changelog_fragment(n, curverstr);
+-
+-  vs_table_ref           t = vs_table::create();
+-  if(f != NULL)
+-    {
+-      vs_scrollbar_ref   s = vs_scrollbar::create(vs_scrollbar::VERTICAL);
+-      menu_text_layout_ref l = menu_text_layout::create();
+-
+-
+-      l->location_changed.connect(sigc::mem_fun(s.unsafe_get_ref(), &vs_scrollbar::set_slider));
+-      s->scrollbar_interaction.connect(sigc::mem_fun(l.unsafe_get_ref(), &vs_text_layout::scroll));
+-      l->set_fragment(f);
+-
+-      t->add_widget_opts(l, 0, 0, 1, 1,
+-			 vs_table::EXPAND|vs_table::SHRINK, vs_table::EXPAND);
+-      t->add_widget_opts(s, 0, 1, 1, 1, 0,
+-			 vs_table::EXPAND | vs_table::FILL);
+-
+-      create_menu_bindings(l.unsafe_get_ref(), t);
+-    }
+-  else
+-    {
+-      pkg_changelog_screen_ref cs = pkg_changelog_screen::create(n);
+-      vs_scrollbar_ref          s = vs_scrollbar::create(vs_scrollbar::VERTICAL);
+-
+-      cs->line_changed.connect(sigc::mem_fun(s.unsafe_get_ref(), &vs_scrollbar::set_slider));
+-      s->scrollbar_interaction.connect(sigc::mem_fun(cs.unsafe_get_ref(), &pkg_changelog_screen::scroll_page));
+-      cs->scroll_top();
+-
+-      t->add_widget_opts(cs, 0, 0, 1, 1,
+-			 vs_table::EXPAND|vs_table::SHRINK, vs_table::EXPAND);
+-      t->add_widget_opts(s, 0, 1, 1, 1, 0,
+-			 vs_table::EXPAND | vs_table::FILL);
+-
+-      create_menu_bindings(cs.unsafe_get_ref(), t);
+-    }
+-
+-  t->show_all();
+-
+-  insert_main_widget(t, menulabel, desclabel, tablabel);
+-}
+-
+-void view_changelog(pkgCache::VerIterator ver)
+-{
+-  bool in_debian=false;
+-
+-  string pkgname = ver.ParentPkg().Name();
+-
+-  pkgCache::VerIterator curver = ver.ParentPkg().CurrentVer();
+-  string curverstr;
+-  if(!curver.end() && curver.VerStr() != NULL)
+-    curverstr = curver.VerStr();
+-
+-  // TODO: add a configurable association between origins and changelog URLs.
+-  for(pkgCache::VerFileIterator vf=ver.FileList();
+-      !vf.end() && !in_debian; ++vf)
+-    if(!vf.File().end() && vf.File().Origin()!=NULL &&
+-       strcmp(vf.File().Origin(), "Debian")==0)
+-      in_debian=true;
+-
+-  if(!in_debian)
+-    {
+-      show_message(_("You can only view changelogs of official Debian packages."),
+-		   NULL, get_style("Error"));
+-      return;
+-    }
+-
+-  download_manager *manager = get_changelog(ver,
+-					    sigc::bind(sigc::ptr_fun(&do_view_changelog), pkgname, curverstr));
+-
+-  if(manager != NULL)
+-    (new ui_download_manager(manager, true, false, false,
+-			     _("Downloading Changelog"),
+-			     "",
+-			     _("Download Changelog")))->start();
+-}
+diff --git a/src/view_changelog.h b/src/view_changelog.h
+deleted file mode 100644
+index 77309a8..0000000
+--- a/src/view_changelog.h
++++ /dev/null
+@@ -1,15 +0,0 @@
+-// view_changelog.h
+-//
+-//   Copyright 2004 Daniel Burrows
+-//
+-// A utility function to view a package's changelog.  Inserts widgets
+-// into the main UI as appropriate.
+-
+-#ifndef VIEW_CHANGELOG_H
+-#define VIEW_CHANGELOG_H
+-
+-#include <apt-pkg/pkgcache.h>
+-
+-void view_changelog(pkgCache::VerIterator ver);
+-
+-#endif
+diff --git a/src/vscreen/curses++.cc b/src/vscreen/curses++.cc
+index 7b9fdc1..b4fa33d 100644
+--- a/src/vscreen/curses++.cc
++++ b/src/vscreen/curses++.cc
+@@ -235,11 +235,7 @@ void resize()
+       struct winsize w;
+       if(ioctl(fd, TIOCGWINSZ, &w)!=-1)
+ 	{
+-	  resize_term(w.ws_row,w.ws_col);
+-	  rootwin=newwin(w.ws_row, w.ws_col, 0, 0);
+-	  eassert(rootwin);
+-	  //eassert(rootwin.getmaxy()==w.ws_row);
+-	  //eassert(rootwin.getmaxx()==w.ws_col);
++	  resizeterm(w.ws_row,w.ws_col);
+ 	  return;
+ 	}
+       else
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index 43b31d2..87fb916 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -1,7 +1,7 @@
+ MAINTAINERCLEANFILES = Makefile.in
+ 
+ INCLUDES = -Wall @WERROR@ -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/src -I$(srcdir)
+-LDADD = $(top_builddir)/src/generic/apt/libgeneric-apt.a $(top_builddir)/src/generic/problemresolver/dummy_universe.o $(top_builddir)/src/generic/util/libgeneric-util.a $(top_builddir)/src/vscreen/libvscreen.a -lcppunit
++LDADD = $(top_builddir)/src/generic/apt/libgeneric-apt.a $(top_builddir)/src/generic/util/libgeneric-util.a $(top_builddir)/src/vscreen/libvscreen.a -lcppunit
+ 
+ check_PROGRAMS = test
+ 
+@@ -21,9 +21,7 @@ test_SOURCES = \
+ 	test_dense_setset.cc \
+ 	test_eassert.cc \
+ 	test_misc.cc \
+-	test_resolver.cc \
+ 	test_setset.cc \
+-	test_tags.cc \
+ 	test_temp.cc \
+ 	test_threads.cc \
+ 	test_wtree.cc
+diff --git a/tests/test_resolver.cc b/tests/test_resolver.cc
+deleted file mode 100644
+index 2b14423..0000000
+--- a/tests/test_resolver.cc
++++ /dev/null
+@@ -1,361 +0,0 @@
+-// test_resolver.cc                       -*-c++-*-
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-//
+-// A test of the generic resolver layer.
+-
+-#include <generic/problemresolver/dummy_universe.h>
+-#include <generic/problemresolver/problemresolver.h>
+-
+-#include <cppunit/extensions/HelperMacros.h>
+-
+-#include <sstream>
+-
+-using namespace std;
+-
+-typedef generic_solution<dummy_universe_ref> dummy_solution;
+-
+-const char *dummy_universe_1 = "\
+-UNIVERSE [ \
+-  PACKAGE a < v1 v2 v3 > v1 \
+-  PACKAGE b < v1 v2 v3 > v1 \
+-  PACKAGE c < v1 v2 v3 > v1 \
+-\
+-  DEP a v1 -> < b v2 > \
+-  DEP b v2 -> < c v2 > \
+-\
+-  DEP a v2 -> < > \
+-  DEP a v3 -> < > \
+-]";
+-
+-const char *dummy_universe_2 = "\
+-UNIVERSE [ \
+-  PACKAGE a < v1 v2 > v1 \
+-  PACKAGE b < v1 v2 > v1 \
+-  PACKAGE c < v1 v2 > v1 \
+-\
+-  DEP a v1 -> < b v2 > \
+-  DEP a v1 -> < c v2 > \
+-]";
+-
+-// Done this way so meaningful line numbers are generated.
+-#define assertEqEquivalent(x1, x2) \
+-do { \
+-    CPPUNIT_ASSERT((x1) == (x2)); \
+-    CPPUNIT_ASSERT((x2) == (x1)); \
+-    CPPUNIT_ASSERT(!((x1) != (x2))); \
+-    CPPUNIT_ASSERT(!((x2) != (x1))); \
+-    CPPUNIT_ASSERT(!((x1) < (x2))); \
+-    CPPUNIT_ASSERT(!((x2) < (x1))); \
+-} while(0)
+-
+-#define assertEqInequivalent(x1, x2) \
+-do { \
+-    CPPUNIT_ASSERT((x1) != (x2)); \
+-    CPPUNIT_ASSERT((x2) != (x1)); \
+-    CPPUNIT_ASSERT(!((x1) == (x2))); \
+-    CPPUNIT_ASSERT(!((x2) == (x1))); \
+-    CPPUNIT_ASSERT((x1) < (x2) || (x2) < (x1)); \
+-    CPPUNIT_ASSERT(!((x1) < (x2) && (x2) < (x1))); \
+-} while(0)
+-
+-#define assertLtEquivalent(x1, x2, lt) \
+-do { \
+-    CPPUNIT_ASSERT(!(lt((x1), (x2)))); \
+-    CPPUNIT_ASSERT(!(lt((x2), (x1)))); \
+-} while(0)
+-
+-#define assertLtInequivalent(x1, x2, lt) \
+-do { \
+-    CPPUNIT_ASSERT(lt((x1), (x2)) || lt((x2), (x1))); \
+-    CPPUNIT_ASSERT(!(lt((x1), (x2)) && lt((x2), (x1)))); \
+-} while(0)
+-
+-class ResolverTest : public CppUnit::TestFixture
+-{
+-  CPPUNIT_TEST_SUITE(ResolverTest);
+-
+-  CPPUNIT_TEST(testActionCompare);
+-  CPPUNIT_TEST(testSolutionCompare);
+-  CPPUNIT_TEST(testRejections);
+-  CPPUNIT_TEST(testDropSolutionSupersets);
+-
+-  CPPUNIT_TEST_SUITE_END();
+-
+-private:
+-  static dummy_universe_ref parseUniverse(const std::string &s)
+-  {
+-    std::istringstream in(s);
+-
+-    return parse_universe(in);
+-  }
+-
+-  /** Test that the comparison operators on actions work. */
+-  void testActionCompare()
+-  {
+-    dummy_universe_ref u = parseUniverse(dummy_universe_1);
+-
+-    // Grab two arbitrary deps.
+-    dummy_universe::dep_iterator di = u.deps_begin();
+-    CPPUNIT_ASSERT(!di.end());
+-    dummy_universe::dep d1 = *di;
+-    ++di;
+-    CPPUNIT_ASSERT(!di.end());
+-    dummy_universe::dep d2 = *di;
+-
+-    dummy_solution::action a1(u.find_package("a").version_from_name("v1"),
+-			      d1, false, 49);
+-    dummy_solution::action a2(u.find_package("a").version_from_name("v1"),
+-			      d2, false, 21);
+-
+-    assertEqEquivalent(a1, a1);
+-    assertEqEquivalent(a1, a2);
+-
+-    dummy_solution::action a3(u.find_package("a").version_from_name("v2"),
+-			      d1, false, 49);
+-
+-    assertEqEquivalent(a2, a2);
+-    assertEqEquivalent(a3, a3);
+-
+-    assertEqInequivalent(a1, a3);
+-    assertEqInequivalent(a2, a3);
+-
+-    dummy_solution::action a4(u.find_package("c").version_from_name("v3"),
+-			      d2, false, 21);
+-
+-    assertEqEquivalent(a4, a4);
+-    assertEqInequivalent(a1, a4);
+-    assertEqInequivalent(a2, a4);
+-    assertEqInequivalent(a3, a4);
+-  }
+-
+-  /** Generate a successor solution that just contains the given
+-   *  information by using internal constructors of the solution
+-   *  class.  Used when testing the solution class itself.
+-   */
+-  template<class a_iter, class u_iter>
+-  dummy_solution unsafe_successor(const dummy_solution &parent,
+-				  a_iter abegin, a_iter aend,
+-				  u_iter ubegin, u_iter uend)
+-  {
+-    imm::map<dummy_universe::package, dummy_solution::action> actions = parent.get_actions();
+-    imm::set<dummy_universe::dep> unresolved = parent.get_unresolved_soft_deps();
+-
+-    for(a_iter ai = abegin; ai != aend; ++ai)
+-      actions.put((*ai).ver.get_package(), *ai);
+-
+-    for(u_iter ui = ubegin; ui != uend; ++ui)
+-      unresolved.insert(*ui);
+-
+-    return dummy_solution(new dummy_solution::solution_rep(actions,
+-							   parent.get_broken(),
+-							   unresolved,
+-							   parent.get_forbidden_versions(),
+-							   parent.get_score(),
+-							   parent.get_action_score()));
+-  }
+-
+-  /** Tests that the comparison operations on solutions work. */
+-  void testSolutionCompare()
+-  {
+-    dummy_universe_ref u = parseUniverse(dummy_universe_1);
+-
+-    // Grab two arbitrary deps.
+-    dummy_universe::dep_iterator di = u.deps_begin();
+-    CPPUNIT_ASSERT(!di.end());
+-    dummy_universe::dep d1 = *di;
+-    ++di;
+-    CPPUNIT_ASSERT(!di.end());
+-    dummy_universe::dep d2 = *di;
+-
+-    solution_weights weights(0, 0, 0, 0, u.get_version_count());
+-
+-    imm::set<dummy_universe::dep> u_broken;
+-    for(dummy_universe::broken_dep_iterator bi = u.broken_begin();
+-	!bi.end(); ++bi)
+-      u_broken.insert(*bi);
+-
+-    dummy_solution::action a1(u.find_package("a").version_from_name("v1"),
+-			      d1, false, 49);
+-    dummy_solution::action a2(u.find_package("a").version_from_name("v1"),
+-			      d2, false, 21);
+-    dummy_solution::action a3(u.find_package("a").version_from_name("v2"),
+-			      d1, false, 49);
+-
+-    dummy_solution::action a4(u.find_package("c").version_from_name("v3"),
+-			      d2, false, 21);
+-
+-
+-    // Generate some meaningless solutions to check that equivalency
+-    // is correctly calculated according to the version mappings and
+-    // the set of unsolved soft deps.
+-    dummy_solution s0 = dummy_solution::root_node(u_broken,
+-						  u, weights);
+-    dummy_solution s1
+-      = unsafe_successor(s0, &a1, &a1+1,
+-			 (dummy_universe::dep *) 0,
+-			 (dummy_universe::dep *) 0);
+-    dummy_solution s2
+-      = unsafe_successor(s0, &a2, &a2+1,
+-			 (dummy_universe::dep *) 0,
+-			 (dummy_universe::dep *) 0);
+-    dummy_solution s3
+-      = unsafe_successor(s0, &a3, &a3+1,
+-			 (dummy_universe::dep *) 0,
+-			 (dummy_universe::dep *) 0);
+-    dummy_solution s4
+-      = unsafe_successor(s0, &a4, &a4+1,
+-			 (dummy_universe::dep *) 0,
+-			 (dummy_universe::dep *) 0);
+-
+-    // the following two should be equal.
+-    dummy_solution s5
+-      = unsafe_successor(s1, &a4, &a4+1,
+-			 (dummy_universe::dep *) 0,
+-			 (dummy_universe::dep *) 0);
+-    dummy_solution s6
+-      = unsafe_successor(s4, &a1, &a1+1,
+-			 (dummy_universe::dep *) 0,
+-			 (dummy_universe::dep *) 0);
+-
+-    // and this should not equal any other solution.
+-    dummy_solution s7
+-      = unsafe_successor(s0,
+-			 (dummy_solution::action *) 0,
+-			 (dummy_solution::action *) 0,
+-			 &d1, &d1+1);
+-
+-    dummy_resolver::solution_contents_compare solcmp;
+-
+-    assertLtEquivalent(s0, s0, solcmp);
+-    assertLtInequivalent(s0, s1, solcmp);
+-    assertLtInequivalent(s0, s2, solcmp);
+-    assertLtInequivalent(s0, s3, solcmp);
+-    assertLtInequivalent(s0, s4, solcmp);
+-    assertLtInequivalent(s0, s5, solcmp);
+-    assertLtInequivalent(s0, s6, solcmp);
+-    assertLtInequivalent(s0, s7, solcmp);
+-
+-    assertLtEquivalent(s1, s1, solcmp);
+-    assertLtEquivalent(s1, s2, solcmp);
+-    assertLtInequivalent(s1, s3, solcmp);
+-    assertLtInequivalent(s1, s4, solcmp);
+-    assertLtInequivalent(s1, s5, solcmp);
+-    assertLtInequivalent(s1, s6, solcmp);
+-    assertLtInequivalent(s1, s7, solcmp);
+-
+-    assertLtEquivalent(s2, s2, solcmp);
+-    assertLtInequivalent(s2, s3, solcmp);
+-    assertLtInequivalent(s2, s4, solcmp);
+-    assertLtInequivalent(s2, s5, solcmp);
+-    assertLtInequivalent(s2, s6, solcmp);
+-    assertLtInequivalent(s2, s7, solcmp);
+-
+-    assertLtEquivalent(s3, s3, solcmp);
+-    assertLtInequivalent(s3, s4, solcmp);
+-    assertLtInequivalent(s3, s5, solcmp);
+-    assertLtInequivalent(s3, s6, solcmp);
+-    assertLtInequivalent(s3, s7, solcmp);
+-
+-    assertLtEquivalent(s4, s4, solcmp);
+-    assertLtInequivalent(s4, s5, solcmp);
+-    assertLtInequivalent(s4, s6, solcmp);
+-    assertLtInequivalent(s4, s7, solcmp);
+-
+-    assertLtEquivalent(s5, s5, solcmp);
+-    assertLtEquivalent(s5, s6, solcmp);
+-    assertLtInequivalent(s5, s7, solcmp);
+-
+-    assertLtEquivalent(s6, s6, solcmp);
+-    assertLtInequivalent(s6, s7, solcmp);
+-
+-    assertLtEquivalent(s7, s7, solcmp);
+-  }
+-
+-  // Check that rejections of versions don't block out all versions of
+-  // the package (this actually happened once).  As installing version
+-  // 2 of everything is a solution, rejecting the third versions
+-  // should be OK.
+-  void testRejections()
+-  {
+-    dummy_universe_ref u = parseUniverse(dummy_universe_1);
+-    dummy_resolver r(10, -300, -100, 100000, 0, 50000, u);
+-
+-    r.reject_version(u.find_package("a").version_from_name("v3"));
+-    r.reject_version(u.find_package("b").version_from_name("v3"));
+-    r.reject_version(u.find_package("c").version_from_name("v3"));
+-
+-    try
+-      {
+-	r.find_next_solution(1000000);
+-      }
+-    catch(NoMoreSolutions)
+-      {
+-	CPPUNIT_FAIL("Expected at least one solution, got none.");
+-      }
+-  }
+-
+-  // Test that the resolver ignores already-generated solutions when
+-  // generating successors.  Also tests that the resolver generates
+-  // solutions in the expected order in a simple situation.
+-  void testDropSolutionSupersets()
+-  {
+-    dummy_universe_ref u = parseUniverse(dummy_universe_2);
+-    dummy_resolver r(10, -300, -100, 100000, 0, 50000, u);
+-
+-    dummy_universe::package a = u.find_package("a");
+-    dummy_universe::version av1 = a.version_from_name("v1");
+-    dummy_universe::version av2 = a.version_from_name("v2");
+-
+-    r.add_version_score(av2, 100);
+-
+-    dummy_solution s;
+-
+-    try
+-      {
+-	s = r.find_next_solution(100);
+-      }
+-    catch(NoMoreSolutions)
+-      {
+-	CPPUNIT_FAIL("Expected at least one solution, got none.");
+-      }
+-
+-    CPPUNIT_ASSERT(s.version_of(a) == av2);
+-    CPPUNIT_ASSERT_EQUAL(s.get_actions().size(), 1U);
+-
+-    try
+-      {
+-	s = r.find_next_solution(100);
+-      }
+-    catch(NoMoreSolutions)
+-      {
+-	CPPUNIT_FAIL("Expected at least two solutions, got only one.");
+-      }
+-
+-    // Note that the only solutions to this problem are (a) install
+-    // a:v2 and do anything else, or (b) leave a:v1 installed and
+-    // install b:v2 and c:v2.  The search algorithm will "see" the
+-    // option of installing a:v2 to resolve the second dep of a:v1
+-    // after seeing the solution <a:=v2>.  If the bug we're testing
+-    // for is present, it'll try to install a:v2 again; otherwise
+-    // it'll reject that solution as containing a conflict.
+-    CPPUNIT_ASSERT(s.version_of(a) != av2);
+-  }
+-};
+-
+-CPPUNIT_TEST_SUITE_REGISTRATION(ResolverTest);
+diff --git a/tests/test_tags.cc b/tests/test_tags.cc
+deleted file mode 100644
+index ea11ddc..0000000
+--- a/tests/test_tags.cc
++++ /dev/null
+@@ -1,237 +0,0 @@
+-// Tester for the tag parser.
+-//
+-//   Copyright (C) 2005 Daniel Burrows
+-//
+-//   This program is free software; you can redistribute it and/or
+-//   modify it under the terms of the GNU General Public License as
+-//   published by the Free Software Foundation; either version 2 of
+-//   the License, or (at your option) any later version.
+-//
+-//   This program is distributed in the hope that it will be useful,
+-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-//   General Public License for more details.
+-//
+-//   You should have received a copy of the GNU General Public License
+-//   along with this program; see the file COPYING.  If not, write to
+-//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+-//   Boston, MA 02111-1307, USA.
+-
+-
+-#include <cppunit/extensions/HelperMacros.h>
+-
+-#include <generic/apt/tags.h>
+-
+-#include <string.h>
+-
+-#include <sstream>
+-
+-std::ostream &operator<<(std::ostream &out, const tag &t)
+-{
+-  return out << t.str();
+-}
+-
+-#define CPPUNIT_ASSERT_GT(a, b) \
+-  do { if(!((a) > (b))) \
+-         {std::ostringstream out; \
+-          out << "comparison assertion failed" << std::endl; \
+-          out << "\"" << (a) << "\" is not > \"" << (b) << "\"" << std::endl; \
+-          CppUnit :: Asserter :: fail(out.str()); } } while(0)
+-
+-#define CPPUNIT_ASSERT_LT(a, b) \
+-  do { if(!((a) < (b))) \
+-         {std::ostringstream out; \
+-          out << "comparison assertion failed" << std::endl; \
+-          out << "\"" << (a) << "\" is not < \"" << (b) << "\"" << std::endl; \
+-          CppUnit :: Asserter :: fail(out.str()); } } while(0)
+-
+-#define CPPUNIT_ASSERT_LTEQUAL(a, b) \
+-  do { if(!((a) <= (b))) \
+-         {std::ostringstream out; \
+-          out << "comparison assertion failed" << std::endl; \
+-          out << "\"" << (a) << "\" is not <= \"" << (b) << "\"" << std::endl; \
+-          CppUnit :: Asserter :: fail(out.str()); } } while(0)
+-
+-#define CPPUNIT_ASSERT_GTEQUAL(a, b) \
+-  do { if(!((a) >= (b))) \
+-         {std::ostringstream out; \
+-          out << "comparison assertion failed" << std::endl; \
+-          out << "\"" << (a) << "\" is not >= \"" << (b) << "\"" << std::endl; \
+-          CppUnit :: Asserter :: fail(out.str()); } } while(0)
+-
+-class TagTest : public CppUnit::TestFixture {
+-  CPPUNIT_TEST_SUITE(TagTest);
+-
+-  CPPUNIT_TEST(testTagTraverse);
+-  CPPUNIT_TEST(testTagStr);
+-  CPPUNIT_TEST(testTagEqual);
+-  CPPUNIT_TEST(testTagOrder);
+-  CPPUNIT_TEST(testTagListTraverse);
+-
+-  CPPUNIT_TEST_SUITE_END();
+-private:
+-  static tag parseTag(const std::string &s)
+-  {
+-    return tag(s.begin(), s.end());
+-  }
+-
+-  // These should all parse to (tag1, tag2, tag3):
+-  static const char *basicTagEntries[];
+-  // Erroneous entries.  Should parse as having no tags at all.
+-  static const char *badEntry1;
+-  static const char *badEntry2;
+-  static const char *badEntry3;
+-  static const char *badEntry4;
+-
+-  // Tag order checks.  The tag ordering function should say that
+-  // forall n . tagorder[n]<tagorder[n+1]
+-  static const char *tagorder[];
+-  // Tag list checks.
+-  static const char *tagLists[];
+-  // One more test.
+-  static const char *tagListLast;
+-
+-  // Checks that the given tag is "tag1::tag2::tag3".
+-  void testTag123(const tag &t)
+-  {
+-    tag::const_iterator ti = t.begin();
+-
+-    CPPUNIT_ASSERT(ti != t.end());
+-    CPPUNIT_ASSERT_EQUAL(string("tag1"), *ti);
+-
+-    ++ti;
+-
+-
+-    CPPUNIT_ASSERT(ti != t.end());
+-    CPPUNIT_ASSERT_EQUAL(string("tag2"), *ti);
+-
+-    ++ti;
+-
+-
+-    CPPUNIT_ASSERT(ti != t.end());
+-    CPPUNIT_ASSERT_EQUAL(string("tag3"), *ti);
+-
+-    ++ti;
+-
+-    CPPUNIT_ASSERT(ti == t.end());
+-  }
+-
+-  void testTagTraverse()
+-  {
+-    const char **s=basicTagEntries;
+-    while(*s)
+-      {
+-	tag parsed = parseTag(*s);
+-	testTag123(parsed);
+-	++s;
+-      }
+-  }
+-
+-  void testTagStr()
+-  {
+-    const char **s=basicTagEntries;
+-    while(*s)
+-      {
+-	tag parsed=parseTag(*s);
+-	CPPUNIT_ASSERT_EQUAL(string("tag1::tag2::tag3"), parsed.str());
+-	++s;
+-      }
+-  }
+-
+-  void testTagEqual()
+-  {
+-    for(const char **s=basicTagEntries; *s; ++s)
+-      for(const char **t=basicTagEntries; *t; ++t)
+-	CPPUNIT_ASSERT_EQUAL(parseTag(*s), parseTag(*t));
+-  }
+-
+-  void testTagOrder()
+-  {
+-    for(const char **s = tagorder; *s; ++s)
+-      {
+-	tag ps = parseTag(*s);
+-
+-	CPPUNIT_ASSERT_EQUAL(ps, ps);
+-
+-	for(const char **t = s; *t; ++t)
+-	  {
+-	    tag pt = parseTag(*t);
+-
+-	    CPPUNIT_ASSERT_LTEQUAL(ps, pt);
+-	    CPPUNIT_ASSERT_GTEQUAL(pt, ps);
+-
+-	    if(t != s)
+-	      {
+-		CPPUNIT_ASSERT_LT(ps, pt);
+-		CPPUNIT_ASSERT_GT(pt, ps);
+-	      }
+-	  }
+-      }
+-  }
+-
+-  void testTagListTraverse()
+-  {
+-    for(const char **l = tagLists; *l; ++l)
+-      {
+-	tag_list lp(*l, (*l)+strlen(*l));
+-
+-	tag_list :: const_iterator i = lp.begin();
+-
+-	CPPUNIT_ASSERT(i != lp.end());
+-	CPPUNIT_ASSERT_EQUAL(string("a::b"), (*i).str());
+-
+-	++i;
+-
+-	CPPUNIT_ASSERT(i != lp.end());
+-	CPPUNIT_ASSERT_EQUAL(string("c::d"), (*i).str());
+-
+-	++i;
+-
+-	CPPUNIT_ASSERT(i != lp.end());
+-	CPPUNIT_ASSERT_EQUAL(string("e::f"), (*i).str());
+-
+-	++i;
+-
+-	CPPUNIT_ASSERT(i == lp.end());
+-      }
+-  }
+-};
+-
+-const char *TagTest::basicTagEntries[]={
+-  "tag1::tag2::tag3",
+-  "  tag1::tag2::tag3",
+-  "tag1::tag2::tag3  ",
+-  "  tag1::tag2::tag3  ",
+-  0
+-};
+-
+-// Erroneous entries.  Should parse as having no tags at all.
+-const char *TagTest::badEntry1="";
+-const char *TagTest::badEntry2=0;
+-const char *TagTest::badEntry3="   ";
+-const char *TagTest::badEntry4="   ::    ";
+-
+-// Tag order checks.  The tag ordering function should say that
+-// forall n . tagorder[n]<tagorder[n+1]
+-const char *TagTest::tagorder[]={
+-  "tag1::tag2::tag3  ",
+-  "  tag1::tag3::tag3",
+-  "tag2::tag1::tag1",
+-  " tag3::tag2::tag2",
+-  "tag3::tag2::tag3",
+-  0
+-};
+-
+-// Tag list checks.
+-const char *TagTest::tagLists[] = {
+-  "a::b,c::d,e::f",
+-  "a::b, c::d, e::f",
+-  "  a::b,c::d,    e::f",
+-  "a::b   ,   c::d   ,   e::f",
+-  0
+-};
+-
+-// One more test.
+-const char *TagTest::tagListLast="  a  :: b";
+-
+-CPPUNIT_TEST_SUITE_REGISTRATION(TagTest);

Added: trunk/rpms/aptitude/aptitude-0.4.4-xsl-stylesheets.patch
===================================================================
--- trunk/rpms/aptitude/aptitude-0.4.4-xsl-stylesheets.patch	                        (rev 0)
+++ trunk/rpms/aptitude/aptitude-0.4.4-xsl-stylesheets.patch	2008-10-31 00:09:09 UTC (rev 6529)
@@ -0,0 +1,61 @@
+--- aptitude-0.4.4/doc/cs/Makefile.am.bak	2007-04-07 12:41:22.333523353 +0200
++++ aptitude-0.4.4/doc/cs/Makefile.am	2007-04-07 15:51:38.670874812 +0200
+@@ -59,7 +59,7 @@
+ 
+ 	mkdir output-html/images/
+ 	ln -f $(srcdir)/images/*.png output-html/images/
+-	for x in caution important note tip warning; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
+-	for x in home next prev up; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
++	for x in caution important note tip warning; do cp -p /usr/share/sgml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
++	for x in home next prev up; do cp -p /usr/share/sgml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
+ 
+ 	touch doc-html-stamp
+--- aptitude-0.4.4/doc/de/Makefile.am.bak	2007-04-07 12:41:22.333523353 +0200
++++ aptitude-0.4.4/doc/de/Makefile.am	2007-04-07 15:51:38.754875476 +0200
+@@ -61,8 +61,8 @@
+ 
+ 	mkdir output-html/images/
+ 	ln -f $(srcdir)/images/*.png output-html/images/
+-	for x in caution important note tip warning; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
+-	for x in home next prev up; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
++	for x in caution important note tip warning; do cp -p /usr/share/sgml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
++	for x in home next prev up; do cp -p /usr/share/sgml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
+ 
+ 	touch doc-html-stamp
+ 
+--- aptitude-0.4.4/doc/en/Makefile.am.bak	2007-04-07 12:41:22.345523481 +0200
++++ aptitude-0.4.4/doc/en/Makefile.am	2007-04-07 15:51:38.794875792 +0200
+@@ -67,7 +67,7 @@
+ 
+ 	mkdir output-html/images/
+ 	ln -f $(srcdir)/images/*.png output-html/images/
+-	for x in caution important note tip warning; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
+-	for x in home next prev up; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
++	for x in caution important note tip warning; do cp -p /usr/share/sgml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
++	for x in home next prev up; do cp -p /usr/share/sgml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
+ 
+ 	touch doc-html-stamp
+--- aptitude-0.4.4/doc/fi/Makefile.am.bak	2007-04-07 12:41:22.345523481 +0200
++++ aptitude-0.4.4/doc/fi/Makefile.am	2007-04-07 15:51:38.894876583 +0200
+@@ -58,7 +58,7 @@
+ 
+ 	mkdir output-html/images/
+ 	ln -f $(srcdir)/images/*.png output-html/images/
+-	for x in caution important note tip warning; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
+-	for x in home next prev up; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
++	for x in caution important note tip warning; do cp -p /usr/share/sgml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
++	for x in home next prev up; do cp -p /usr/share/sgml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
+ 
+ 	touch doc-html-stamp
+--- aptitude-0.4.4/doc/fr/Makefile.am.bak	2007-04-07 12:41:22.349523524 +0200
++++ aptitude-0.4.4/doc/fr/Makefile.am	2007-04-07 15:51:38.926876836 +0200
+@@ -68,7 +68,7 @@
+ 
+ 	mkdir output-html/images/
+ 	ln -f $(srcdir)/images/*.png output-html/images/
+-	for x in caution important note tip warning; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
+-	for x in home next prev up; do cp -p /usr/share/xml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
++	for x in caution important note tip warning; do cp -p /usr/share/sgml/docbook/xsl-stylesheets/images/$$x.png output-html/images/; done
++	for x in home next prev up; do cp -p /usr/share/sgml/docbook/xsl-stylesheets/images/$$x.gif output-html/images/; done
+ 
+ 	touch doc-html-stamp

Added: trunk/rpms/aptitude/aptitude.spec
===================================================================
--- trunk/rpms/aptitude/aptitude.spec	                        (rev 0)
+++ trunk/rpms/aptitude/aptitude.spec	2008-10-31 00:09:09 UTC (rev 6529)
@@ -0,0 +1,80 @@
+# $Id$
+# Authority: dag
+# Upstream: Daniel Burrows <Daniel_Burrows at alumni.brown.edu>
+
+%define real_version 0.4.4.orig
+
+Summary: Curses-based apt frontend
+Name: aptitude
+Version: 0.4.4
+Release: 1
+License: GPL
+Group: Applications/System
+URL: http://algebraicthunk.net/~dburrows/projects/aptitude/
+
+Source: http://http.us.debian.org/debian/pool/main/a/aptitude/aptitude_%{version}.orig.tar.gz
+Patch0: aptitude-0.4.4-alt1.patch
+Patch1: aptitude-0.4.4-xsl-stylesheets.patch
+Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root
+
+BuildRequires: apt-devel
+BuildRequires: cppunit-devel
+BuildRequires: docbook-dtd42-xml
+BuildRequires: docbook-style-xsl
+BuildRequires: gettext-devel
+BuildRequires: html2text
+BuildRequires: libsigc++20-devel
+BuildRequires: libxslt-devel
+BuildRequires: po4a
+
+%description
+Aptitude is a curses-based apt frontend with a number of useful extended 
+features, including: a mutt-like syntax for matching packages in a flexible 
+manner, persistence of user actions, and extreme flexibility and customization. 
+
+%prep
+%setup -n %{name}-%{real_version}
+%patch0 -p1 -b .apt-rpm-altlinux
+%patch1 -p1 -b .sgml
+
+### Filter out languages that go below the minimal translation barrier
+%{__perl} -pi -e 's|^SUBDIRS=cs de en fi fr ja po4a$|SUBDIRS=cs de en fi po4a|' doc/Makefile.am
+
+%build
+### Remove some generated files as in original altlinux patch but keep mkinstalldirs
+%{__rm} -f INSTALL Makefile.in aclocal.m4 config.guess config.h.in config.sub \
+  configure depcomp install-sh missing po/stamp-po \
+  src/Makefile.in src/cmdline/Makefile.in src/generic/Makefile.in \
+  src/generic/apt/Makefile.in src/generic/problemresolver/Makefile.in \
+  src/generic/util/Makefile.in src/mine/Makefile.in src/vscreen/Makefile.in \
+  src/vscreen/config/Makefile.in tests/Makefile.in
+libtoolize --copy --force
+aclocal -I m4
+autoheader
+automake -a -c
+autoconf
+export CPPFLAGS="-DRPM_VERSION=0x040406"
+%configure --disable-werror
+%{__make} %{?_smp_mflags}
+
+%install
+%{__rm} -rf %{buildroot}
+%{__make} install DESTDIR="%{buildroot}" STATEDIR="%{_localstatedir}/aptitude"
+%find_lang %{name}
+
+%clean
+%{__rm} -rf %{buildroot}
+
+%files -f %{name}.lang
+%defattr(-, root, root, 0775)
+%doc %{_docdir}/aptitude
+%doc %{_mandir}/man8/aptitude.8.*
+%doc %{_mandir}/*/man8/aptitude.8.*
+%dir %{_datadir}/aptitude
+%{_bindir}/aptitude
+%{_datadir}/aptitude/
+%dir %{_localstatedir}/aptitude/
+
+%changelog
+* Wed Oct 29 2008 Dag Wieers <dag at wieers.com> - 0.4.4-1
+- Initial package. (using DAR)


Property changes on: trunk/rpms/aptitude/aptitude.spec
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Modified: trunk/rpms/fail2ban/fail2ban.spec
===================================================================
--- trunk/rpms/fail2ban/fail2ban.spec	2008-10-28 23:31:51 UTC (rev 6528)
+++ trunk/rpms/fail2ban/fail2ban.spec	2008-10-31 00:09:09 UTC (rev 6529)
@@ -7,9 +7,9 @@
 Summary: Scan logfiles and ban ip addresses with too many password failures
 Name: fail2ban
 Version: 0.8.2
-Release: 2
+Release: 3
 License: GPL
-Group: ystem Environment/Daemons
+Group: System Environment/Daemons
 URL: http://fail2ban.sourceforge.net/
 
 Source: http://dl.sf.net/fail2ban/fail2ban-%{version}.tar.bz2
@@ -93,6 +93,9 @@
 %dir %{_var}/run/fail2ban
 
 %changelog
+* Wed Oct 29 2008 Dag Wieers <dag at wieers.com> - 0.8.2-3
+- Fix group.
+
 * Sat Apr 12 2008 Dries Verachtert <dries at ulyssis.org> - 0.8.2-2
 - Fix location of fail2ban.sock file in init script, thanks to John Thomas.
 

Added: trunk/rpms/html2text/html2text-1.3.2.spec
===================================================================
--- trunk/rpms/html2text/html2text-1.3.2.spec	                        (rev 0)
+++ trunk/rpms/html2text/html2text-1.3.2.spec	2008-10-31 00:09:09 UTC (rev 6529)
@@ -0,0 +1,49 @@
+# $Id$
+# Authority: dag
+
+# ExclusiveDist: el2 rh7
+
+Summary: Utility to convert HTML document to plain text
+Name: html2text
+Version: 1.3.2
+Release: 1
+License: GPL
+Group: Applications/Text
+URL: http://www.mbayer.de/html2text/
+
+Source: http://www.mbayer.de/html2text/downloads/html2text-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+
+BuildRequires: gcc-c++
+
+%description
+html2text is a command line utility, written in C++, that converts HTML
+documents into plain text.
+
+%prep
+%setup
+
+%build
+%configure
+%{__make} %{?_smp_mflags}
+
+%install
+%{__rm} -rf %{buildroot}
+gunzip html2text.1.gz html2textrc.5.gz
+%{__install} -Dp -m0755 html2text %{buildroot}%{_bindir}/html2text
+%{__install} -Dp -m0644 html2text.1 %{buildroot}%{_mandir}/man1/html2text.1
+%{__install} -Dp -m0644 html2textrc.5 %{buildroot}%{_mandir}/man5/html2textrc.5
+
+%clean
+%{__rm} -rf %{buildroot}
+
+%files
+%defattr(-, root, root, 0755)
+%doc CHANGES COPYING CREDITS INSTALL KNOWN_BUGS RELEASE_NOTES README TODO
+%doc %{_mandir}/man1/html2text.1*
+%doc %{_mandir}/man5/html2textrc.5*
+%{_bindir}/html2text
+
+%changelog
+* Wed Oct 29 2008 Dag Wieers <dag at wieers.com> - 1.3.2-1
+- Initial package. (using DAR)


Property changes on: trunk/rpms/html2text/html2text-1.3.2.spec
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Added: trunk/rpms/html2text/html2text.spec
===================================================================
--- trunk/rpms/html2text/html2text.spec	                        (rev 0)
+++ trunk/rpms/html2text/html2text.spec	2008-10-31 00:09:09 UTC (rev 6529)
@@ -0,0 +1,47 @@
+# $Id$
+# Authority: dag
+
+Summary: Utility to convert HTML document to plain text
+Name: html2text
+Version: 1.3.2a
+Release: 1
+License: GPL
+Group: Applications/Text
+URL: http://www.mbayer.de/html2text/
+
+Source: http://www.mbayer.de/html2text/downloads/html2text-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+
+BuildRequires: gcc-c++
+
+%description
+html2text is a command line utility, written in C++, that converts HTML
+documents into plain text.
+
+%prep
+%setup
+
+%build
+%configure
+%{__make} %{?_smp_mflags}
+
+%install
+%{__rm} -rf %{buildroot}
+gunzip html2text.1.gz html2textrc.5.gz
+%{__install} -Dp -m0755 html2text %{buildroot}%{_bindir}/html2text
+%{__install} -Dp -m0644 html2text.1 %{buildroot}%{_mandir}/man1/html2text.1
+%{__install} -Dp -m0644 html2textrc.5 %{buildroot}%{_mandir}/man5/html2textrc.5
+
+%clean
+%{__rm} -rf %{buildroot}
+
+%files
+%defattr(-, root, root, 0755)
+%doc CHANGES COPYING CREDITS INSTALL KNOWN_BUGS RELEASE_NOTES README TODO
+%doc %{_mandir}/man1/html2text.1*
+%doc %{_mandir}/man5/html2textrc.5*
+%{_bindir}/html2text
+
+%changelog
+* Wed Oct 29 2008 Dag Wieers <dag at wieers.com> - 1.3.2a-1
+- Initial package. (using DAR)


Property changes on: trunk/rpms/html2text/html2text.spec
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Modified: trunk/rpms/htmldoc/htmldoc.spec
===================================================================
--- trunk/rpms/htmldoc/htmldoc.spec	2008-10-28 23:31:51 UTC (rev 6528)
+++ trunk/rpms/htmldoc/htmldoc.spec	2008-10-31 00:09:09 UTC (rev 6529)
@@ -1,13 +1,12 @@
 # $Id$
-# Authority: 
 
 Summary: HTMLDOC html to pdf converter
 Name: htmldoc
 Version: 1.8.27
-Release: 1
+Release: 2
 License: GPL
-Group: System Tools
-URL: http://www.htmldoc.org
+Group: Applications/Text
+URL: http://www.htmldoc.org/
 
 Source: http://ftp.easysw.com/pub/htmldoc/%{version}/htmldoc-%{version}-source.tar.bz2
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
@@ -19,7 +18,7 @@
 BuildRequires: automake, libtool
 
 %description
-This package allows you to convert html pages to pdf format.
+htmldoc allows you to convert html pages to pdf format.
 
 %prep
 %setup
@@ -30,7 +29,10 @@
 
 %install
 %{__rm} -rf %{buildroot}
-%{__make} DESTDIR="%{buildroot}" install bindir="%{buildroot}%{_bindir}" datadir="%{buildroot}%{_datadir}" mandir="%{buildroot}%{_mandir}"
+%{__make} install DESTDIR="%{buildroot}" \
+    bindir="%{buildroot}%{_bindir}" \
+    datadir="%{buildroot}%{_datadir}" \
+    mandir="%{buildroot}%{_mandir}"
 %{__mv} %{buildroot}%{_datadir}/doc/htmldoc _rpmdocs
 
 %clean
@@ -42,7 +44,10 @@
 %doc %{_mandir}/man1/htmldoc.1*
 %{_bindir}/htmldoc
 %{_datadir}/htmldoc/
-   
+
 %changelog
+* Wed Oct 29 2008 Dag Wieers <dag at wieers.com> - 1.8.27-2
+- Fixed Group.
+
 * Thu Apr 17 2008 - Jim Nelson <jim.nelson at neteasyinc.com> - 1.8.27-1
 - initial package

Modified: trunk/rpms/icmptx/icmptx.spec
===================================================================
--- trunk/rpms/icmptx/icmptx.spec	2008-10-28 23:31:51 UTC (rev 6528)
+++ trunk/rpms/icmptx/icmptx.spec	2008-10-31 00:09:09 UTC (rev 6529)
@@ -5,9 +5,9 @@
 Summary: Tunneling IP over ICMP
 Name: icmptx
 Version: 0.01
-Release: 1
+Release: 2
 License: GPL
-Group: Applications/Networking
+Group: Applications/Internet
 URL: http://thomer.com/icmptx/
 
 Source: http://thomer.com/icmptx/icmptx-%{version}.tar.gz
@@ -36,5 +36,8 @@
 %{_bindir}/icmptx
 
 %changelog
+* Wed Oct 29 2008 Dag Wieers <dag at wieers.com> - 0.01-2
+- Fix Group.
+
 * Tue Oct 14 2008 Dag Wieers <dag at wieers.com> - 0.01-1
 - Initial package. (using DAR)

Added: trunk/rpms/po4a/po4a.spec
===================================================================
--- trunk/rpms/po4a/po4a.spec	                        (rev 0)
+++ trunk/rpms/po4a/po4a.spec	2008-10-31 00:09:09 UTC (rev 6529)
@@ -0,0 +1,72 @@
+# $Id$
+# Authority: dag
+
+%define real_version 0.33
+
+Summary: Tool to maintain translations anywhere
+Name: po4a
+Version: 0.33.2
+Release: 1
+License: GPL
+Group: Applications/System
+URL: http://alioth.debian.org/projects/po4a/
+
+Source: http://alioth.debian.org/frs/download.php/2376/po4a-%{version}.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+
+BuildArch: noarch
+BuildRequires: gettext
+BuildRequires: perl(Locale::gettext) >= 1.01
+BuildRequires: perl(Module::Build)
+BuildRequires: perl(SGMLS) >= 1.03ii
+BuildRequires: perl(Term::ReadKey)
+BuildRequires: perl(Text::WrapI18N)
+Requires: gettext
+
+%description
+The po4a (po for anything) project goal is to ease translations (and
+more interestingly, the maintenance of translations) using gettext
+tools on areas where they were not expected like documentation.
+
+%prep
+%setup -n %{name}-%{real_version}
+
+%build
+%{__perl} Build.PL --installdirs vendor
+./Build
+
+%install
+%{__rm} -rf %{buildroot}
+%{__make} install DESTDIR="%{buildroot}"
+%find_lang %{name}
+
+### Clean up buildroot
+find %{buildroot} -name .packlist -exec %{__rm} {} \;
+
+### Ugly fix to get the translated man pages in utf-8
+for file in  %{buildroot}%{_mandir}/*/man*/*.gz; do
+    gunzip -c $file | iconv -f latin1 -t utf8 | gzip -c > $file.new
+    mv -f $file.new $file
+done
+
+%clean
+%{__rm} -rf %{buildroot}
+
+%files -f %{name}.lang
+%defattr(-, root, root, 0755)
+%doc COPYING README* TODO
+%doc %{_mandir}/man1/msguntypot.1*
+%doc %{_mandir}/man1/po4a*.1*
+%doc %{_mandir}/man3/Locale::Po4a::*.3pm*
+%doc %{_mandir}/man7/po4a.7*
+%doc %{_mandir}/*/man1/msguntypot.1*
+%doc %{_mandir}/*/man1/po4a*.1*
+%doc %{_mandir}/*/man3/Locale::Po4a::*.3pm*
+%doc %{_mandir}/*/man7/po4a.7*
+%{_bindir}/po4a*
+%{_bindir}/msguntypot
+%{perl_vendorlib}/Locale/
+
+%changelog
+* Wed Oct 29 2008 Dag Wieers <dag at wieers.com> - 0.33.2-1
+- Initial package. (using DAR)


Property changes on: trunk/rpms/po4a/po4a.spec
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Added: trunk/rpms/pychecker/pychecker-0.8.17-root.patch
===================================================================
--- trunk/rpms/pychecker/pychecker-0.8.17-root.patch	                        (rev 0)
+++ trunk/rpms/pychecker/pychecker-0.8.17-root.patch	2008-10-31 00:09:09 UTC (rev 6529)
@@ -0,0 +1,12 @@
+--- pychecker-0.8.17/setup.py.root	2006-02-04 04:57:49.000000000 +0100
++++ pychecker-0.8.17/setup.py	2006-02-04 04:59:00.000000000 +0100
+@@ -134,6 +134,9 @@
+          script_path = get_script_path(self.build_dir)
+          if script_path in scripts:
+             package_path = os.path.join(install_lib, "pychecker")
++            root = self.distribution.get_command_obj("install").root
++            if root:
++               package_path = package_path[len(root):]
+             self.execute(func=create_script, 
+                          args=[script_path, package_path], 
+                          msg="filling in script %s" % script_path)

Added: trunk/rpms/pychecker/pychecker-0.8.17-spe.patch
===================================================================
--- trunk/rpms/pychecker/pychecker-0.8.17-spe.patch	                        (rev 0)
+++ trunk/rpms/pychecker/pychecker-0.8.17-spe.patch	2008-10-31 00:09:09 UTC (rev 6529)
@@ -0,0 +1,70 @@
+diff -up pychecker-0.8.17/pychecker2/main.py_old pychecker-0.8.17/pychecker2/main.py
+--- pychecker-0.8.17/pychecker2/main.py_old	2002-09-02 00:36:21.000000000 +0200
++++ pychecker-0.8.17/pychecker2/main.py	2008-04-29 11:41:35.000000000 +0200
+@@ -1,5 +1,29 @@
+ import sys
+ from os.path import dirname, realpath
++
++#---Patched by Stani http://pythonide.stani.be (begin)
++import os
++def userPath(dirname=''):
++    """'safer' function to find user path."""
++    # 'safer' function to find user path: look for one of these directories
++    try:
++        path = os.path.expanduser("~")
++        if os.path.isdir(path):
++            return os.path.join(path, dirname)
++    except:
++        pass
++    for evar in ('HOME', 'USERPROFILE', 'TMP'):
++        try:
++            path = os.environ[evar]
++            if os.path.isdir(path):
++                return os.path.join(path, dirname)
++        except:
++            pass
++    #if no match found, use module directory
++    return os.path.join(os.path.dirname(os.path.abspath(__file__)), dirname)
++
++CACHE_FILE = userPath(".pychecker_cache")
++#Patched by Stani http://pythonide.stani.be (end)
+ sys.path.append(dirname(dirname(realpath(sys.argv[0]))))
+ 
+ from pychecker2.Check import CheckList
+@@ -16,7 +40,6 @@ from pychecker2 import ReturnChecks
+ from pychecker2 import ConditionalChecks
+ from pychecker2 import FormatStringChecks
+ 
+-CACHE_FILE = '/tmp/t'
+ 
+ def print_warnings(f, out):
+     if not f.warnings:
+@@ -69,7 +92,8 @@ def main():
+     options = Options.Options()
+     try:
+         checker = cPickle.load(open(CACHE_FILE, 'rb'))
+-    except (EOFError, IOError):
++    #---Patched by Stani http://pythonide.stani.be (added ImportError)
++    except (EOFError, IOError, ImportError):
+         checker = create_checklist(options)
+ 
+     try:
+@@ -79,10 +103,18 @@ def main():
+         options.usage(sys.argv[0], sys.stderr)
+         return 1
+ 
++    #---Patched by Stani http://pythonide.stani.be (begin)
++    sys_path    = sys.path[:]
+     for f in files:
++        f_dir   = dirname(f.name)
++        sys.path= sys_path[:]
++        if f_dir not in sys.path:
++            sys.path.insert(0,f_dir)
+         checker.check_file(f)
+         if options.incremental and not options.profile:
+             print_warnings(f, sys.stdout)
++    sys.path    = sys_path
++    #Patched by Stani http://pythonide.stani.be (end)
+ 
+     result = 0
+     if not options.incremental and not options.profile:

Modified: trunk/rpms/pychecker/pychecker.spec
===================================================================
--- trunk/rpms/pychecker/pychecker.spec	2008-10-28 23:31:51 UTC (rev 6528)
+++ trunk/rpms/pychecker/pychecker.spec	2008-10-31 00:09:09 UTC (rev 6529)
@@ -7,12 +7,14 @@
 Summary: Find common bugs in Python source code
 Name: pychecker
 Version: 0.8.17
-Release: 2.2
+Release: 3
 License: BSD
 Group: Development/Tools
 URL: http://pychecker.sourceforge.net/
 
 Source: http://dl.sf.net/pychecker/pychecker-%{version}.tar.gz
+Patch0: pychecker-0.8.17-root.patch
+Patch1: pychecker-0.8.17-spe.patch
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 
 Buildarch: noarch
@@ -28,6 +30,8 @@
 
 %prep
 %setup
+%patch0 -p1 -b .root
+%patch1 -p1 -b .spe
 
 %build
 %{__python} setup.py build
@@ -57,8 +61,8 @@
 %exclude %{python_sitelib}/pychecker/VERSION
 
 %changelog
-* Sat Apr 08 2006 Dries Verachtert <dries at ulyssis.org> - 0.8.17-2.2
-- Rebuild for Fedora Core 5.
+* Fri Oct 31 2008 Dag Wieers <dag at wieers.com> - 0.8.17-3
+- Added Fedora patches.
 
 * Fri Mar 10 2006 Dag Wieers <dag at wieers.com> - 0.8.17-2
 - Added .pyo ghost files, renamed to pychecker.

Modified: trunk/rpms/synaptic/synaptic.spec
===================================================================
--- trunk/rpms/synaptic/synaptic.spec	2008-10-28 23:31:51 UTC (rev 6528)
+++ trunk/rpms/synaptic/synaptic.spec	2008-10-31 00:09:09 UTC (rev 6529)
@@ -5,7 +5,7 @@
 Summary: Graphical package management program using apt
 Name: synaptic
 Version: 0.57.2
-Release: 4
+Release: 5
 License: GPL
 Group: Applications/System
 URL: http://www.nongnu.org/synaptic/
@@ -119,6 +119,9 @@
 %{_sbindir}/synaptic
 
 %changelog
+* Wed Oct 29 2008 Dag Wieers <dag at wieers.com> - 0.57.2-5
+- Rebuild against apt-0.5.15lorg3.94a.
+
 * Thu Jun 12 2008 Dag Wieers <dag at wieers.com> - 0.57.2-4
 - Rebuild against apt-0.5.15lorg3.2.
 

Modified: trunk/rpms/wine/wine.spec
===================================================================
--- trunk/rpms/wine/wine.spec	2008-10-28 23:31:51 UTC (rev 6528)
+++ trunk/rpms/wine/wine.spec	2008-10-31 00:09:09 UTC (rev 6529)
@@ -48,7 +48,7 @@
 
 Summary: Windows 16/32/64 bit emulator
 Name: wine
-Version: 1.0
+Version: 1.0.1
 Release: 1
 License: LGPL
 Group: Applications/Emulators
@@ -884,6 +884,9 @@
 %{_libdir}/wine/*.def
 
 %changelog
+* Fri Oct 31 2008 Dag Wieers <dag at wieers.com> - 1.0.1-1
+- Updated to release 1.0.1.
+
 * Tue Jun 17 2008 Dag Wieers <dag at wieers.com> - 1.0-1
 - Updated to release 1.0.
 




More information about the commits mailing list