+
+              if (Counter > 1)
+              {
+                 if (Scores[I->ID] > Scores[J->Pkg->ID])                 
+                    Scores[J->Pkg->ID] = Scores[I->ID];
+              }               
+           }      
+        }
+      }      
+   }
+
+   if (Debug == true)
+      clog << "Done" << endl;
+      
+   if (Cache.BrokenCount() != 0)
+   {
+      // See if this is the result of a hold
+      pkgCache::PkgIterator I = Cache.PkgBegin();
+      for (;I.end() != true; ++I)
+      {
+        if (Cache[I].InstBroken() == false)
+           continue;
+        if ((Flags[I->ID] & Protected) != Protected)
+           return _error->Error(_("Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages."));
+      }
+      return _error->Error(_("Unable to correct problems, you have held broken packages."));
+   }
+   
+   // set the auto-flags (mvo: I'm not sure if we _really_ need this)
+   pkgCache::PkgIterator I = Cache.PkgBegin();
+   for (;I.end() != true; ++I) {
+      if (Cache[I].NewInstall() && !(Flags[I->ID] & PreInstalled)) {
+        if(_config->FindI("Debug::pkgAutoRemove",false)) {
+           std::clog << "Resolve installed new pkg: " << I.FullName(false) 
+                     << " (now marking it as auto)" << std::endl;
+        }
+        Cache[I].Flags |= pkgCache::Flag::Auto;
+      }
+   }
+
+
+   return true;
+}
+                                                                       /*}}}*/
+// ProblemResolver::BreaksInstOrPolicy - Check if the given pkg is broken/*{{{*/
+// ---------------------------------------------------------------------
+/* This checks if the given package is broken either by a hard dependency
+   (InstBroken()) or by introducing a new policy breakage e.g. new
+   unsatisfied recommends for a package that was in "policy-good" state
+
+   Note that this is not perfect as it will ignore further breakage
+   for already broken policy (recommends)
+*/
+bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I)
+{
+   // a broken install is always a problem
+   if (Cache[I].InstBroken() == true)
+   {
+      if (Debug == true)
+        std::clog << "  Dependencies are not satisfied for " << I << std::endl;
+      return true;
+   }
+
+   // a newly broken policy (recommends/suggests) is a problem
+   if (Cache[I].NowPolicyBroken() == false &&
+       Cache[I].InstPolicyBroken() == true)
+   {
+      if (Debug == true)
+        std::clog << "  Policy breaks with upgrade of " << I << std::endl;
+      return true;
+   }
+
+   return false;
+}
+                                                                       /*}}}*/
+// ProblemResolver::ResolveByKeep - Resolve problems using keep                /*{{{*/
+// ---------------------------------------------------------------------
+/* This is the work horse of the soft upgrade routine. It is very gental 
+   in that it does not install or remove any packages. It is assumed that the
+   system was non-broken previously. */
+bool pkgProblemResolver::ResolveByKeep()
+{
+   std::string const solver = _config->Find("APT::Solver", "internal");
+   if (solver != "internal") {
+      OpTextProgress Prog(*_config);
+      return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog);
+   }
+   return ResolveByKeepInternal();
+}
+                                                                       /*}}}*/
+// ProblemResolver::ResolveByKeepInternal - Resolve problems using keep        /*{{{*/
+// ---------------------------------------------------------------------
+/* This is the work horse of the soft upgrade routine. It is very gental
+   in that it does not install or remove any packages. It is assumed that the
+   system was non-broken previously. */
+bool pkgProblemResolver::ResolveByKeepInternal()
+{
+   pkgDepCache::ActionGroup group(Cache);
+
+   unsigned long Size = Cache.Head().PackageCount;
+
+   MakeScores();
+   
+   /* We have to order the packages so that the broken fixing pass 
+      operates from highest score to lowest. This prevents problems when
+      high score packages cause the removal of lower score packages that
+      would cause the removal of even lower score packages. */
+   pkgCache::Package **PList = new pkgCache::Package *[Size];
+   pkgCache::Package **PEnd = PList;
+   for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+      *PEnd++ = I;
+   This = this;
+   qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort);
+
+   if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true)
+   {
+      clog << "Show Scores" << endl;
+      for (pkgCache::Package **K = PList; K != PEnd; K++)
+         if (Scores[(*K)->ID] != 0)
+         {
+           pkgCache::PkgIterator Pkg(Cache,*K);
+           clog << Scores[(*K)->ID] << ' ' << Pkg << std::endl;
+         }
+   }
+
+   if (Debug == true)
+      clog << "Entering ResolveByKeep" << endl;
+
+   // Consider each broken package 
+   pkgCache::Package **LastStop = 0;
+   for (pkgCache::Package **K = PList; K != PEnd; K++)
+   {
+      pkgCache::PkgIterator I(Cache,*K);
+
+      if (Cache[I].InstallVer == 0)
+        continue;
+
+      if (InstOrNewPolicyBroken(I) == false)
+         continue;
+
+      /* Keep the package. If this works then great, otherwise we have
+                to be significantly more agressive and manipulate its dependencies */
+      if ((Flags[I->ID] & Protected) == 0)
+      {
+        if (Debug == true)
+           clog << "Keeping package " << I.FullName(false) << endl;
+        Cache.MarkKeep(I, false, false);
+        if (InstOrNewPolicyBroken(I) == false)
+        {
+           K = PList - 1;
+           continue;
+        }
+      }
+      
+      // Isolate the problem dependencies
+      for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false;)
+      {
+        DepIterator Start;
+        DepIterator End;
+        D.GlobOr(Start,End);
+
+        // We only worry about critical deps.
+        if (End.IsCritical() != true)
+           continue;
+        
+        // Dep is ok
+        if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
+           continue;
+
+        /* Hm, the group is broken.. I suppose the best thing to do is to
+           is to try every combination of keep/not-keep for the set, but thats
+           slow, and this never happens, just be conservative and assume the
+           list of ors is in preference and keep till it starts to work. */
+        while (true)
+        {
+           if (Debug == true)
+              clog << "Package " << I.FullName(false) << " " << Start << endl;
+
+           // Look at all the possible provides on this package
+           SPtrArray<pkgCache::Version *> VList = Start.AllTargets();
+           for (pkgCache::Version **V = VList; *V != 0; V++)