WriteOkay(Okay, output, "Forbid-New-Install: yes\n");
    if (flags & Request::FORBID_REMOVE)
       WriteOkay(Okay, output, "Forbid-Remove: yes\n");
+   auto const solver = _config->Find("APT::Solver", "internal");
+   WriteOkay(Okay, output, "Solver: ", solver, "\n");
    if (_config->FindB("APT::Solver::Strict-Pinning", true) == false)
       WriteOkay(Okay, output, "Strict-Pinning: no\n");
    string solverpref("APT::Solver::");
-   solverpref.append(_config->Find("APT::Solver", "internal")).append("::Preferences");
+   solverpref.append(solver).append("::Preferences");
    if (_config->Exists(solverpref) == true)
       WriteOkay(Okay, output, "Preferences: ", _config->Find(solverpref,""), "\n");
    return WriteOkay(Okay, output, "\n");
              "\n\n");
 }
                                                                        /*}}}*/
+static std::string findExecutable(std::vector<std::string> const &dirs, char const * const binary) {/*{{{*/
+       for (auto && dir : dirs) {
+               std::string const file = flCombine(dir, binary);
+               if (RealFileExists(file) == true)
+                       return file;
+       }
+       return "";
+}
+                                                                       /*}}}*/
 static pid_t ExecuteExternal(char const* const type, char const * const binary, char const * const configdir, int * const solver_in, int * const solver_out) {/*{{{*/
-       std::vector<std::string> const solverDirs = _config->FindVector(configdir);
-       std::string file;
-       for (std::vector<std::string>::const_iterator dir = solverDirs.begin();
-            dir != solverDirs.end(); ++dir) {
-               file = flCombine(*dir, binary);
-               if (RealFileExists(file.c_str()) == true)
-                       break;
-               file.clear();
+       auto const solverDirs = _config->FindVector(configdir);
+       auto const file = findExecutable(solverDirs, binary);
+       std::string dumper;
+       {
+               dumper = findExecutable(solverDirs, "apt-dump-solver");
+               if (dumper.empty())
+                       dumper = findExecutable(solverDirs, "dump");
        }
 
        if (file.empty() == true)
        if (Solver == 0) {
                dup2(external[0], STDIN_FILENO);
                dup2(external[3], STDOUT_FILENO);
-               const char* calling[2] = { file.c_str(), 0 };
-               execv(calling[0], (char**) calling);
+               auto const dumpfile = _config->FindFile((std::string("Dir::Log::") + type).c_str());
+               auto const dumpdir = flNotFile(dumpfile);
+               if (dumper.empty() || dumpfile.empty() || dumper == file || CreateAPTDirectoryIfNeeded(dumpdir, dumpdir) == false)
+               {
+                  char const * const calling[] = { file.c_str(), nullptr };
+                  execv(calling[0], const_cast<char**>(calling));
+               }
+               else
+               {
+                  char const * const calling[] = { dumper.c_str(), dumpfile.c_str(), file.c_str(), nullptr };
+                  execv(calling[0], const_cast<char**>(calling));
+               }
                std::cerr << "Failed to execute " << type << " '" << binary << "'!" << std::endl;
                _exit(100);
        }
 
 // System::Initialize - Setup the configuration space..                        /*{{{*/
 bool edspLikeSystem::Initialize(Configuration &Cnf)
 {
+   Cnf.Set("Dir::Log", "/dev/null");
    // state is included completely in the input files
+   Cnf.Set("Dir::Etc::preferences", "/dev/null");
    Cnf.Set("Dir::Etc::preferencesparts", "/dev/null");
    Cnf.Set("Dir::State::status","/dev/null");
+   Cnf.Set("Dir::State::extended_states","/dev/null");
    Cnf.Set("Dir::State::lists","/dev/null");
    // do not store an mmap cache
    Cnf.Set("Dir::Cache::pkgcache", "");
 
    Cnf.CndSet("Dir::Cache::archives","archives/");
    Cnf.CndSet("Dir::Cache::srcpkgcache","srcpkgcache.bin");
    Cnf.CndSet("Dir::Cache::pkgcache","pkgcache.bin");
-   
+
    // Configuration
    Cnf.CndSet("Dir::Etc","etc/apt/");
    Cnf.CndSet("Dir::Etc::sourcelist","sources.list");
    Cnf.CndSet("Dir::Bin::solvers::","/usr/lib/apt/solvers");
    Cnf.CndSet("Dir::Media::MountPath","/media/apt");
 
-   // State   
+   // State
    Cnf.CndSet("Dir::Log","var/log/apt");
    Cnf.CndSet("Dir::Log::Terminal","term.log");
    Cnf.CndSet("Dir::Log::History","history.log");
 
    else
       return false;
 
+   return true;
+}
+                                                                       /*}}}*/
+static bool addArgumentsAPTDumpSolver(std::vector<CommandLine::Args> &, char const * const)/*{{{*/
+{
    return true;
 }
                                                                        /*}}}*/
         case APT_CMD::APT_CACHE: addArgumentsAPTCache(Args, Cmd); break;
         case APT_CMD::APT_CDROM: addArgumentsAPTCDROM(Args, Cmd); break;
         case APT_CMD::APT_CONFIG: addArgumentsAPTConfig(Args, Cmd); break;
+        case APT_CMD::APT_DUMP_SOLVER: addArgumentsAPTDumpSolver(Args, Cmd); break;
         case APT_CMD::APT_EXTRACTTEMPLATES: addArgumentsAPTExtractTemplates(Args, Cmd); break;
         case APT_CMD::APT_FTPARCHIVE: addArgumentsAPTFTPArchive(Args, Cmd); break;
         case APT_CMD::APT_HELPER: addArgumentsAPTHelper(Args, Cmd); break;
       case APT_CMD::APT_CACHE: cmd = "apt-cache(8)"; break;
       case APT_CMD::APT_CDROM: cmd = "apt-cdrom(8)"; break;
       case APT_CMD::APT_CONFIG: cmd = "apt-config(8)"; break;
+      case APT_CMD::APT_DUMP_SOLVER: cmd = nullptr; break;
       case APT_CMD::APT_EXTRACTTEMPLATES: cmd = "apt-extracttemplates(1)"; break;
       case APT_CMD::APT_FTPARCHIVE: cmd = "apt-ftparchive(1)"; break;
       case APT_CMD::APT_GET: cmd = "apt-get(8)"; break;
    }
    if (cmd != nullptr)
       ioprintf(std::cout, _("See %s for more information about the available commands."), cmd);
-   std::cout << std::endl <<
-      _("Configuration options and syntax is detailed in apt.conf(5).\n"
-           "Information about how to configure sources can be found in sources.list(5).\n"
-           "Package and version choices can be expressed via apt_preferences(5).\n"
-           "Security details are available in apt-secure(8).\n");
+   if (Binary != APT_CMD::APT_DUMP_SOLVER && Binary != APT_CMD::APT_INTERNAL_SOLVER)
+      std::cout << std::endl <<
+        _("Configuration options and syntax is detailed in apt.conf(5).\n"
+              "Information about how to configure sources can be found in sources.list(5).\n"
+              "Package and version choices can be expressed via apt_preferences(5).\n"
+              "Security details are available in apt-secure(8).\n");
    if (Binary == APT_CMD::APT_GET || Binary == APT_CMD::APT)
       std::cout << std::right << std::setw(70) << _("This APT has Super Cow Powers.") << std::endl;
-   else if (Binary == APT_CMD::APT_HELPER)
+   else if (Binary == APT_CMD::APT_HELPER || Binary == APT_CMD::APT_DUMP_SOLVER)
       std::cout << std::right << std::setw(70) << _("This APT helper has Super Meep Powers.") << std::endl;
    return true;
 }
 
    APT_INTERNAL_SOLVER,
    APT_MARK,
    APT_SORTPKG,
+   APT_DUMP_SOLVER,
 };
 struct aptDispatchWithHelp
 {
 
       case APT_CMD::APT_MARK:
         textdomain("apt");
         break;
+      case APT_CMD::APT_DUMP_SOLVER:
       case APT_CMD::APT_EXTRACTTEMPLATES:
       case APT_CMD::APT_FTPARCHIVE:
       case APT_CMD::APT_INTERNAL_SOLVER:
 
    ##################################################################### */
                                                                        /*}}}*/
 // Include Files                                                       /*{{{*/
+#include <config.h>
+
+#include <apt-pkg/cmndline.h>
+#include <apt-pkg/configuration.h>
 #include <apt-pkg/edsp.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/strutl.h>
+
+#include <apt-private/private-cmndline.h>
 
-#include <string.h>
-#include <unistd.h>
 #include <cstdio>
 #include <iostream>
+#include <memory>
 #include <sstream>
 
-#include <config.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <string.h>
+#include <unistd.h>
+
+#include <apti18n.h>
                                                                        /*}}}*/
 
-// ShowHelp - Show a help screen                                       /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-static bool ShowHelp() {
-       ioprintf(std::cout, "%s %s (%s)\n", PACKAGE, PACKAGE_VERSION, COMMON_ARCH);
-       std::cout <<
-               "Usage: apt-dump-solver\n"
-               "\n"
-               "apt-dump-solver is a dummy solver who just dumps its input to the\n"
-               "file specified in the environment variable APT_EDSP_DUMP_FILENAME and\n"
-               "exists with a proper EDSP error.\n"
-               "\n"
-               "                       This dump has lost Super Cow Powers.\n";
-       return true;
+static bool ShowHelp(CommandLine &)                                    /*{{{*/
+{
+   std::cout <<
+      _("Usage: apt-dump-solver\n"
+           "\n"
+           "apt-dump-solver is an interface to store an EDSP scenario in\n"
+           "a file and optionally forwards it to another solver.\n");
+   return true;
+}
+                                                                       /*}}}*/
+static std::vector<aptDispatchWithHelp> GetCommands()                  /*{{{*/
+{
+   return {};
+}
+                                                                       /*}}}*/
+static int WriteError(char const * const uid, std::ostringstream &out, FileFd &stdoutfd, pid_t const &Solver)/*{{{*/
+{
+   _error->DumpErrors(out);
+   // ensure the solver isn't printing into "our" error message, too
+   if (Solver != 0)
+      ExecWait(Solver, "dump", true);
+   EDSP::WriteError(uid, out.str(), stdoutfd);
+   return 0;
 }
                                                                        /*}}}*/
 int main(int argc,const char *argv[])                                  /*{{{*/
 {
-       // we really don't need anything
-       DropPrivileges();
-
-       if (argc > 1 && (strcmp(argv[1], "--help") == 0 || strcmp(argv[1],"-h") == 0 ||
-           strcmp(argv[1],"-v") == 0 || strcmp(argv[1],"--version") == 0)) {
-               ShowHelp();
-               return 0;
-       }
-
-       FileFd stdoutfd;
-       if (stdoutfd.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly | FileFd::BufferedWrite, true) == false)
-          return 1;
-
-       char const * const filename = getenv("APT_EDSP_DUMP_FILENAME");
-       if (filename == NULL || strlen(filename) == 0)
-       {
-          EDSP::WriteError("ERR_NO_FILENAME", "You have to set the environment variable APT_EDSP_DUMP_FILENAME\n"
-                "to a valid filename to store the dump of EDSP solver input in.\n"
-                "For example with: export APT_EDSP_DUMP_FILENAME=/tmp/dump.edsp", stdoutfd);
-          return 0;
-       }
-
-       RemoveFile(argv[0], filename);
-       FileFd input, output;
-       if (input.OpenDescriptor(STDIN_FILENO, FileFd::ReadOnly) == false ||
-             output.Open(filename, FileFd::WriteOnly | FileFd::Create | FileFd::Exclusive, FileFd::Extension, 0600) == false ||
-             CopyFile(input, output) == false || input.Close() == false || output.Close() == false)
-       {
-          std::ostringstream out;
-          out << "Writing EDSP solver input to file '" << filename << "' failed!\n";
-          _error->DumpErrors(out);
-          EDSP::WriteError("ERR_WRITE_ERROR", out.str(), stdoutfd);
-          return 0;
-       }
-
-       EDSP::WriteError("ERR_JUST_DUMPING", "I am too dumb, i can just dump!\nPlease use one of my friends instead!", stdoutfd);
-       return 0;
+   CommandLine CmdL;
+   ParseCommandLine(CmdL, APT_CMD::APT_DUMP_SOLVER, &_config, nullptr, argc, argv, &ShowHelp, &GetCommands);
+   _config->Clear("Dir::Log");
+
+   bool const is_forwarding_dumper = (CmdL.FileSize() != 0);
+
+   FileFd stdoutfd;
+   if (stdoutfd.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly | FileFd::BufferedWrite, true) == false)
+      return 252;
+
+   FileFd dump;
+   char const * const filename = is_forwarding_dumper ? CmdL.FileList[0] : getenv("APT_EDSP_DUMP_FILENAME");
+   if (filename == nullptr || strlen(filename) == 0)
+   {
+      if (is_forwarding_dumper == false)
+      {
+        EDSP::WriteError("ERR_NO_FILENAME", "You have to set the environment variable APT_EDSP_DUMP_FILENAME\n"
+              "to a valid filename to store the dump of EDSP solver input in.\n"
+              "For example with: export APT_EDSP_DUMP_FILENAME=/tmp/dump.edsp", stdoutfd);
+        return 0;
+      }
+   }
+   else
+   {
+      // ignore errors here as logging isn't really critical
+      _error->PushToStack();
+      if (dump.Open(filename, FileFd::WriteOnly | FileFd::Exclusive | FileFd::Create, FileFd::Extension, 0644) == false &&
+           is_forwarding_dumper == false)
+      {
+        _error->MergeWithStack();
+        std::ostringstream out;
+        out << "Writing EDSP solver input to file '" << filename << "' failed as it couldn't be created!\n";
+        return WriteError("ERR_CREATE_FILE", out, stdoutfd, 0);
+      }
+      _error->RevertToStack();
+   }
+
+   pid_t Solver = 0;
+   FileFd forward;
+   if (is_forwarding_dumper)
+   {
+      int external[] = {-1, -1};
+      if (pipe(external) != 0)
+        return 250;
+      for (int i = 0; i < 2; ++i)
+        SetCloseExec(external[i], true);
+
+      Solver = ExecFork();
+      if (Solver == 0) {
+        dup2(external[0], STDIN_FILENO);
+        execv(CmdL.FileList[1], const_cast<char**>(CmdL.FileList + 1));
+        std::cerr << "Failed to execute  '" << CmdL.FileList[1] << "'!" << std::endl;
+        _exit(100);
+      }
+      close(external[0]);
+
+      if (WaitFd(external[1], true, 5) == false)
+        return 251;
+
+      if (forward.OpenDescriptor(external[1], FileFd::WriteOnly | FileFd::BufferedWrite, true) == false)
+        return 252;
+   }
+
+   DropPrivileges();
+
+   FileFd input;
+   if (input.OpenDescriptor(STDIN_FILENO, FileFd::ReadOnly) == false)
+   {
+      std::ostringstream out;
+      out << "Writing EDSP solver input to file '" << filename << "' failed as stdin couldn't be opened!\n";
+      return WriteError("ERR_READ_ERROR", out, stdoutfd, Solver);
+   }
+
+   constexpr size_t BufSize = 64 * 1024;
+   std::unique_ptr<char[]> Buf(new char[BufSize]);
+   unsigned long long ToRead = 0;
+   do {
+      if (input.Read(Buf.get(),BufSize, &ToRead) == false)
+      {
+        std::ostringstream out;
+        out << "Writing EDSP solver input to file '" << filename << "' failed as reading from stdin failed!\n";
+        return WriteError("ERR_READ_ERROR", out, stdoutfd, Solver);
+      }
+      if (ToRead == 0)
+        break;
+      if (forward.IsOpen() && forward.Failed() == false && forward.Write(Buf.get(),ToRead) == false)
+        forward.Close();
+      if (dump.IsOpen() && dump.Failed() == false && dump.Write(Buf.get(),ToRead) == false)
+        dump.Close();
+   } while (true);
+   input.Close();
+   forward.Close();
+   dump.Close();
+
+   if (_error->PendingError())
+   {
+      std::ostringstream out;
+      out << "Writing EDSP solver input to file '" << filename << "' failed due to write errors!\n";
+      return WriteError("ERR_WRITE_ERROR", out, stdoutfd, Solver);
+   }
+
+   if (is_forwarding_dumper)
+   {
+      // Wait and collect the error code
+      int Status;
+      while (waitpid(Solver, &Status, 0) != Solver)
+      {
+        if (errno == EINTR)
+           continue;
+
+        std::ostringstream out;
+        ioprintf(out, _("Waited for %s but it wasn't there"), CmdL.FileList[1]);
+        return WriteError("ERR_FORWARD", out, stdoutfd, 0);
+      }
+      if (WIFEXITED(Status))
+        return WEXITSTATUS(Status);
+      else
+        return 255;
+   }
+   else
+      EDSP::WriteError("ERR_JUST_DUMPING", "I am too dumb, i can just dump!\nPlease use one of my friends instead!", stdoutfd);
+   return 0;
 }
 
        _config->Set("APT::System", "Debian APT solver interface");
        _config->Set("APT::Solver", "internal");
        _config->Set("edsp::scenario", "/nonexistent/stdin");
+       _config->Clear("Dir::Log");
        FileFd output;
        if (output.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly | FileFd::BufferedWrite, true) == false)
           DIE("stdout couldn't be opened");
 
 
 # This just dumps out the state
 PROGRAM=apt-dump-solver
-SLIBS = -lapt-pkg $(INTLLIBS)
-LIB_MAKES = apt-pkg/makefile
+SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
+LIB_MAKES = apt-pkg/makefile apt-private/makefile
 SOURCE = apt-dump-solver.cc
 include $(PROGRAM_H)
 
 
 
 setupaptarchive
 
+testsuccess aptget install --solver apt coolstuff -s
+testempty find -name 'edsp.last.*'
+echo 'Dir::Log::Solver "edsp.last.xz";' > rootdir/etc/apt/apt.conf.d/log-edsp.conf
+
 testfailure aptget install --solver dump coolstuff -s
-testsuccess grep ERR_NO_FILENAME rootdir/tmp/testfailure.output
+testsuccess grep 'ERR_NO_FILENAME' rootdir/tmp/testfailure.output
+testfailure test -s rootdir/var/log/apt/edsp.last.xz
 export APT_EDSP_DUMP_FILENAME="/nonexistent/apt/edsp.dump"
 testfailure aptget install --solver dump coolstuff -s
-testsuccess grep ERR_WRITE_ERROR rootdir/tmp/testfailure.output
+testsuccess grep 'ERR_CREATE_FILE' rootdir/tmp/testfailure.output
+testfailure test -s rootdir/var/log/apt/edsp.last.xz
 export APT_EDSP_DUMP_FILENAME="${TMPWORKINGDIRECTORY}/downloaded/dump.edsp"
 
 testfailureequal 'Reading package lists...
 Please use one of my friends instead!
 
 E: External solver failed with: I am too dumb, i can just dump!' aptget install --solver dump coolstuff -s
+testfailure test -s rootdir/var/log/apt/edsp.last.xz
 testsuccess test -s "$APT_EDSP_DUMP_FILENAME"
-rm -f "$APT_EDSP_DUMP_FILENAME"
 
 testsuccessequal 'Reading package lists...
 Building dependency tree...
 0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
 Inst coolstuff (2 unstable [amd64])
 Conf coolstuff (2 unstable [amd64])' aptget install --solver apt coolstuff -s
+testsuccess test -s rootdir/var/log/apt/edsp.last.xz
+sed -i -e 's#^Solver: dump$#Solver: apt#' "$APT_EDSP_DUMP_FILENAME"
+testequal "$(cat "$APT_EDSP_DUMP_FILENAME")
+" apthelper cat-file rootdir/var/log/apt/edsp.last.xz
+cp rootdir/var/log/apt/edsp.last.xz rootdir/var/log/apt/edsp.last.xz.1
+rm -f "$APT_EDSP_DUMP_FILENAME"
 
 testsuccessequal 'Reading package lists...
 Building dependency tree...
 0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
 Inst coolstuff (3 experimental [amd64])
 Conf coolstuff (3 experimental [amd64])' aptget install --solver apt coolstuff -s -t experimental
+testfailure cmp rootdir/var/log/apt/edsp.last.xz rootdir/var/log/apt/edsp.last.xz.1
 
 testsuccessequal "Reading package lists...
 Building dependency tree...