Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / solver / detail / SATResolver.cc
index 1a3c92d..31dff06 100644 (file)
@@ -29,8 +29,7 @@ extern "C"
 #include <solv/queue.h>
 }
 
-#define ZYPP_USE_RESOLVER_INTERNALS
-
+#include "zypp/solver/detail/Helper.h"
 #include "zypp/base/String.h"
 #include "zypp/Product.h"
 #include "zypp/Capability.h"
@@ -46,22 +45,15 @@ extern "C"
 #include "zypp/sat/Pool.h"
 #include "zypp/sat/WhatProvides.h"
 #include "zypp/sat/WhatObsoletes.h"
-#include "zypp/solver/detail/Resolver.h"
 #include "zypp/solver/detail/SATResolver.h"
 #include "zypp/solver/detail/ProblemSolutionCombi.h"
 #include "zypp/solver/detail/ProblemSolutionIgnore.h"
 #include "zypp/solver/detail/SolverQueueItemInstall.h"
 #include "zypp/solver/detail/SolverQueueItemDelete.h"
 #include "zypp/solver/detail/SystemCheck.h"
-#include "zypp/solver/detail/SolutionAction.h"
-#include "zypp/solver/detail/SolverQueueItem.h"
 #include "zypp/sat/Transaction.h"
 #include "zypp/sat/Queue.h"
 
-#include "zypp/sat/detail/PoolImpl.h"
-
-#define XDEBUG(x) do { if (base::logger::isExcessive()) XXX << x << std::endl;} while (0)
-
 /////////////////////////////////////////////////////////////////////////
 namespace zypp
 { ///////////////////////////////////////////////////////////////////////
@@ -101,7 +93,7 @@ IMPL_PTR_TYPE(SATResolver);
 // Callbacks for SAT policies
 //---------------------------------------------------------------------------
 
-int vendorCheck( sat::detail::CPool *pool, Solvable *solvable1, Solvable *solvable2 )
+int vendorCheck( Pool *pool, Solvable *solvable1, Solvable *solvable2 )
 {
   return VendorAttr::instance().equivalent( IdString(solvable1->vendor),
                                             IdString(solvable2->vendor) ) ? 0 : 1;
@@ -138,8 +130,8 @@ std::ostream &
 SATResolver::dumpOn( std::ostream & os ) const
 {
     os << "<resolver>" << endl;
-    if (_satSolver) {
-#define OUTS(X) os << "  " << #X << "\t= " << solver_get_flag(_satSolver, SOLVER_FLAG_##X) << endl
+    if (_solv) {
+#define OUTS(X) os << "  " << #X << "\t= " << solver_get_flag(_solv, SOLVER_FLAG_##X) << endl
        OUTS( ALLOW_DOWNGRADE );
        OUTS( ALLOW_ARCHCHANGE );
        OUTS( ALLOW_VENDORCHANGE );
@@ -175,15 +167,19 @@ SATResolver::dumpOn( std::ostream & os ) const
 
 //---------------------------------------------------------------------------
 
-SATResolver::SATResolver (const ResPool & pool, sat::detail::CPool *satPool)
-    : _pool(pool)
-    , _satPool(satPool)
-    , _satSolver(NULL)
+SATResolver::SATResolver (const ResPool & pool, Pool *SATPool)
+    : _pool (pool)
+    , _SATPool (SATPool)
+    , _solv(NULL)
     , _fixsystem(false)
     , _allowdowngrade(false)
     , _allowarchchange(false)
     , _allowvendorchange(ZConfig::instance().solver_allowVendorChange())
     , _allowuninstall(false)
+    , _dup_allowdowngrade( true )
+    , _dup_allownamechange( true )
+    , _dup_allowarchchange( true )
+    , _dup_allowvendorchange( true )
     , _updatesystem(false)
     , _noupdateprovide(false)
     , _dosplitprovides(true)
@@ -191,10 +187,6 @@ SATResolver::SATResolver (const ResPool & pool, sat::detail::CPool *satPool)
     , _ignorealreadyrecommended(true)
     , _distupgrade(false)
     , _distupgrade_removeunsupported(false)
-    , _dup_allowdowngrade      ( ZConfig::instance().solver_dupAllowDowngrade() )
-    , _dup_allownamechange     ( ZConfig::instance().solver_dupAllowNameChange() )
-    , _dup_allowarchchange     ( ZConfig::instance().solver_dupAllowArchChange() )
-    , _dup_allowvendorchange   ( ZConfig::instance().solver_dupAllowVendorChange() )
     , _solveSrcPackages(false)
     , _cleandepsOnRemove(ZConfig::instance().solver_cleandepsOnRemove())
 {
@@ -214,6 +206,102 @@ SATResolver::pool (void) const
     return _pool;
 }
 
+void
+SATResolver::resetItemTransaction (PoolItem item)
+{
+    bool found = false;
+    for (PoolItemList::const_iterator iter = _items_to_remove.begin();
+        iter != _items_to_remove.end(); ++iter) {
+       if (*iter == item) {
+           _items_to_remove.remove(*iter);
+           found = true;
+           break;
+       }
+    }
+    if (!found) {
+       for (PoolItemList::const_iterator iter = _items_to_install.begin();
+            iter != _items_to_install.end(); ++iter) {
+           if (*iter == item) {
+               _items_to_install.remove(*iter);
+               found = true;
+               break;
+           }
+       }
+    }
+    if (!found) {
+       for (PoolItemList::const_iterator iter = _items_to_keep.begin();
+            iter != _items_to_keep.end(); ++iter) {
+           if (*iter == item) {
+               _items_to_keep.remove(*iter);
+               found = true;
+               break;
+           }
+       }
+    }
+    if (!found) {
+       for (PoolItemList::const_iterator iter = _items_to_lock.begin();
+            iter != _items_to_lock.end(); ++iter) {
+           if (*iter == item) {
+               _items_to_lock.remove(*iter);
+               found = true;
+               break;
+           }
+       }
+    }
+}
+
+
+void
+SATResolver::addPoolItemToInstall (PoolItem item)
+{
+    resetItemTransaction (item);
+    _items_to_install.push_back (item);
+    _items_to_install.unique ();
+}
+
+
+void
+SATResolver::addPoolItemsToInstallFromList (PoolItemList & rl)
+{
+    for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
+       addPoolItemToInstall (*iter);
+    }
+}
+
+
+void
+SATResolver::addPoolItemToRemove (PoolItem item)
+{
+    resetItemTransaction (item);
+    _items_to_remove.push_back (item);
+    _items_to_remove.unique ();
+}
+
+
+void
+SATResolver::addPoolItemsToRemoveFromList (PoolItemList & rl)
+{
+    for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
+       addPoolItemToRemove (*iter);
+    }
+}
+
+void
+SATResolver::addPoolItemToLock (PoolItem item)
+{
+    resetItemTransaction (item);
+    _items_to_lock.push_back (item);
+    _items_to_lock.unique ();
+}
+
+void
+SATResolver::addPoolItemToKeep (PoolItem item)
+{
+    resetItemTransaction (item);
+    _items_to_keep.push_back (item);
+    _items_to_keep.unique ();
+}
+
 //---------------------------------------------------------------------------
 
 // copy marked item from solution back to pool
@@ -231,15 +319,15 @@ SATSolutionToPool (PoolItem item, const ResStatus & status, const ResStatus::Tra
     // installation/deletion
     if (status.isToBeInstalled()) {
        r = item.status().setToBeInstalled (causer);
-       XDEBUG("SATSolutionToPool install returns " << item << ", " << r);
+       _XDEBUG("SATSolutionToPool install returns " << item << ", " << r);
     }
     else if (status.isToBeUninstalledDueToUpgrade()) {
        r = item.status().setToBeUninstalledDueToUpgrade (causer);
-       XDEBUG("SATSolutionToPool upgrade returns " << item << ", " <<  r);
+       _XDEBUG("SATSolutionToPool upgrade returns " << item << ", " <<  r);
     }
     else if (status.isToBeUninstalled()) {
        r = item.status().setToBeUninstalled (causer);
-       XDEBUG("SATSolutionToPool remove returns " << item << ", " <<  r);
+       _XDEBUG("SATSolutionToPool remove returns " << item << ", " <<  r);
     }
 
     return;
@@ -250,71 +338,65 @@ SATSolutionToPool (PoolItem item, const ResStatus & status, const ResStatus::Tra
 // resolvePool
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
-/////////////////////////////////////////////////////////////////////////
-/// \class SATCollectTransact
-/// \brief Commit helper functor distributing PoolItem by status into lists
-///
-/// On the fly it clears all PoolItem bySolver/ByApplLow status.
-/// The lists are cleared in the Ctor, populated by \ref operator().
-/////////////////////////////////////////////////////////////////////////
+
+//----------------------------------------------------------------------------
+// Helper functions for the ZYPP-Pool
+//----------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------------------------------------
+//  This function loops over the pool and grabs all items
+//  It clears all previous bySolver() states also
+//
+//  Every toBeInstalled is passed to zypp::solver:detail::Resolver.addPoolItemToInstall()
+//  Every toBeUninstalled is passed to zypp::solver:detail::Resolver.addPoolItemToRemove()
+//
+//  Solver results must be written back to the pool.
+//------------------------------------------------------------------------------------------------------------
+
+
 struct SATCollectTransact : public resfilter::PoolItemFilterFunctor
 {
-  SATCollectTransact( PoolItemList & items_to_install_r,
-                     PoolItemList & items_to_remove_r,
-                     PoolItemList & items_to_lock_r,
-                     PoolItemList & items_to_keep_r,
-                     bool solveSrcPackages_r )
-  : _items_to_install( items_to_install_r )
-  , _items_to_remove( items_to_remove_r )
-  , _items_to_lock( items_to_lock_r )
-  , _items_to_keep( items_to_keep_r )
-  , _solveSrcPackages( solveSrcPackages_r )
-  {
-    _items_to_install.clear();
-    _items_to_remove.clear();
-    _items_to_lock.clear();
-    _items_to_keep.clear();
-  }
+    SATResolver & resolver;
 
-  bool operator()( const PoolItem & item_r )
-  {
-
-    ResStatus & itemStatus( item_r.status() );
-    bool by_solver = ( itemStatus.isBySolver() || itemStatus.isByApplLow() );
+    SATCollectTransact (SATResolver & r)
+       : resolver (r)
+    { }
 
-    if ( by_solver )
+    bool operator()( PoolItem item )           // only transacts() items go here
     {
-      // Clear former solver/establish resultd
-      itemStatus.resetTransact( ResStatus::APPL_LOW );
-      return true;     // -> back out here, don't re-queue former results
-    }
+       ResStatus status = item.status();
+       bool by_solver = (status.isBySolver() || status.isByApplLow());
 
-    if ( !_solveSrcPackages && item_r.isKind<SrcPackage>() )
-    {
-      // Later we may continue on a per source package base.
-      return true; // dont process this source package.
-    }
+       if (by_solver) {
+           item.status().resetTransact( ResStatus::APPL_LOW );// clear any solver/establish transactions
+           return true;                                // back out here, dont re-queue former solver result
+       }
 
-    switch ( itemStatus.getTransactValue() )
-    {
-      case ResStatus::TRANSACT:
-       itemStatus.isUninstalled() ?    _items_to_install.push_back( item_r )
-                                  :    _items_to_remove.push_back( item_r );   break;
-      case ResStatus::LOCKED:          _items_to_lock.push_back( item_r );     break;
-      case ResStatus::KEEP_STATE:      _items_to_keep.push_back( item_r );     break;
-    }
-    return true;
-  }
+       if ( item.satSolvable().isKind<SrcPackage>() && ! resolver.solveSrcPackages() )
+       {
+         // Later we may continue on a per source package base.
+         return true; // dont process this source package.
+       }
 
-private:
-  PoolItemList & _items_to_install;
-  PoolItemList & _items_to_remove;
-  PoolItemList & _items_to_lock;
-  PoolItemList & _items_to_keep;
-  bool _solveSrcPackages;
+       if (status.isToBeInstalled()) {
+           resolver.addPoolItemToInstall(item);        // -> install!
+       }
+       else if (status.isToBeUninstalled()) {
+           resolver.addPoolItemToRemove(item);         // -> remove !
+       }
+        else if (status.isLocked()
+                && !by_solver) {
+           resolver.addPoolItemToLock (item);
+        }
+        else if (status.isKept()
+                && !by_solver) {
+           resolver.addPoolItemToKeep (item);
+        }
 
+       return true;
+    }
 };
-/////////////////////////////////////////////////////////////////////////
 
 
 //----------------------------------------------------------------------------
@@ -328,20 +410,22 @@ class CheckIfUpdate : public resfilter::PoolItemFilterFunctor
 {
   public:
     bool is_updated;
+    bool multiversion;
     sat::Solvable _installed;
 
-    CheckIfUpdate( const sat::Solvable & installed_r )
-    : is_updated( false )
-    , _installed( installed_r )
+    CheckIfUpdate( sat::Solvable installed_r )
+       : is_updated( false )
+        , multiversion( installed_r.multiversionInstall() )
+        , _installed( installed_r )
     {}
 
     // check this item will be updated
 
-    bool operator()( const PoolItem & item )
+    bool operator()( PoolItem item )
     {
        if ( item.status().isToBeInstalled() )
         {
-          if ( ! item.multiversionInstall() || sameNVRA( _installed, item ) )
+          if ( ! multiversion || sameNVRA( _installed, item ) )
           {
             is_updated = true;
             return false;
@@ -374,8 +458,8 @@ bool
 SATResolver::solving(const CapabilitySet & requires_caps,
                     const CapabilitySet & conflict_caps)
 {
-    _satSolver = solver_create( _satPool );
-    ::pool_set_custom_vendorcheck( _satPool, &vendorCheck );
+    _solv = solver_create( _SATPool );
+    ::pool_set_custom_vendorcheck( _SATPool, &vendorCheck );
     if (_fixsystem) {
        queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL);
        queue_push( &(_jobQueue), 0 );
@@ -392,32 +476,32 @@ SATResolver::solving(const CapabilitySet & requires_caps,
        queue_push( &(_jobQueue), SOLVER_DROP_ORPHANED|SOLVER_SOLVABLE_ALL);
        queue_push( &(_jobQueue), 0 );
     }
-    solver_set_flag(_satSolver, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended);
-    solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade);
-    solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
-    solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange);
-    solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange);
-    solver_set_flag(_satSolver, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
-    solver_set_flag(_satSolver, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
-    solver_set_flag(_satSolver, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
-    solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_DOWNGRADE,       _dup_allowdowngrade );
-    solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_NAMECHANGE,      _dup_allownamechange );
-    solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE,      _dup_allowarchchange );
-    solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE,    _dup_allowvendorchange );
+    solver_set_flag(_solv, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended);
+    solver_set_flag(_solv, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade);
+    solver_set_flag(_solv, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
+    solver_set_flag(_solv, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange);
+    solver_set_flag(_solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange);
+    solver_set_flag(_solv, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
+    solver_set_flag(_solv, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
+    solver_set_flag(_solv, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
+    solver_set_flag(_solv, SOLVER_FLAG_DUP_ALLOW_DOWNGRADE,    _dup_allowdowngrade );
+    solver_set_flag(_solv, SOLVER_FLAG_DUP_ALLOW_NAMECHANGE,   _dup_allownamechange );
+    solver_set_flag(_solv, SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE,   _dup_allowarchchange );
+    solver_set_flag(_solv, SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE, _dup_allowvendorchange );
 #if 1
-#define HACKENV(X,D) solver_set_flag(_satSolver, X, env::HACKENV( #X, D ) );
+#define HACKENV(X,D) solver_set_flag(_solv, X, env::HACKENV( #X, D ) );
     HACKENV( SOLVER_FLAG_DUP_ALLOW_DOWNGRADE,  _dup_allowdowngrade );
     HACKENV( SOLVER_FLAG_DUP_ALLOW_NAMECHANGE, _dup_allownamechange );
     HACKENV( SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE, _dup_allowarchchange );
     HACKENV( SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE,_dup_allowvendorchange );
 #undef HACKENV
 #endif
-    sat::Pool::instance().prepare();
+    sat::Pool::instance().prepareForSolving();
 
     // Solve !
     MIL << "Starting solving...." << endl;
     MIL << *this;
-    solver_solve( _satSolver, &(_jobQueue) );
+    solver_solve( _solv, &(_jobQueue) );
     MIL << "....Solver end" << endl;
 
     // copying solution back to zypp pool
@@ -428,7 +512,7 @@ SATResolver::solving(const CapabilitySet & requires_caps,
     /*  solvables to be installed */
     Queue decisionq;
     queue_init(&decisionq);
-    solver_get_decisionqueue(_satSolver, &decisionq);
+    solver_get_decisionqueue(_solv, &decisionq);
     for ( int i = 0; i < decisionq.count; ++i )
     {
       sat::Solvable slv( decisionq.elements[i] );
@@ -437,7 +521,7 @@ SATResolver::solving(const CapabilitySet & requires_caps,
 
       PoolItem poolItem( slv );
       SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER);
-      _result_items_to_install.push_back( poolItem );
+      _result_items_to_install.push_back (poolItem);
     }
     queue_free(&decisionq);
 
@@ -448,7 +532,7 @@ SATResolver::solving(const CapabilitySet & requires_caps,
       bool mustCheckObsoletes = false;
       for_( it, systemRepo.solvablesBegin(), systemRepo.solvablesEnd() )
       {
-       if (solver_get_decisionlevel(_satSolver, it->id()) > 0)
+       if (solver_get_decisionlevel(_solv, it->id()) > 0)
          continue;
 
        // Check if this is an update
@@ -489,9 +573,9 @@ SATResolver::solving(const CapabilitySet & requires_caps,
     queue_init(&suggestions);
     queue_init(&orphaned);
     queue_init(&unneeded);
-    solver_get_recommendations(_satSolver, &recommendations, &suggestions, 0);
-    solver_get_orphaned(_satSolver, &orphaned);
-    solver_get_unneeded(_satSolver, &unneeded, 1);
+    solver_get_recommendations(_solv, &recommendations, &suggestions, 0);
+    solver_get_orphaned(_solv, &orphaned);
+    solver_get_unneeded(_solv, &unneeded, 1);
     /*  solvables which are recommended */
     for ( int i = 0; i < recommendations.count; ++i )
     {
@@ -537,20 +621,20 @@ SATResolver::solving(const CapabilitySet & requires_caps,
     invokeOnEach( _pool.begin(),
                  _pool.end(),
                  functor::functorRef<bool,PoolItem> (collectPseudoInstalled) );
-    solver_trivial_installable(_satSolver, &solvableQueue, &flags );
+    solver_trivial_installable(_solv, &solvableQueue, &flags );
     for (int i = 0; i < solvableQueue.count; i++) {
        PoolItem item = _pool.find (sat::Solvable(solvableQueue.elements[i]));
        item.status().setUndetermined();
 
        if (flags.elements[i] == -1) {
            item.status().setNonRelevant();
-           XDEBUG("SATSolutionToPool(" << item << " ) nonRelevant !");
+           _XDEBUG("SATSolutionToPool(" << item << " ) nonRelevant !");
        } else if (flags.elements[i] == 1) {
            item.status().setSatisfied();
-           XDEBUG("SATSolutionToPool(" << item << " ) satisfied !");
+           _XDEBUG("SATSolutionToPool(" << item << " ) satisfied !");
        } else if (flags.elements[i] == 0) {
            item.status().setBroken();
-           XDEBUG("SATSolutionToPool(" << item << " ) broken !");
+           _XDEBUG("SATSolutionToPool(" << item << " ) broken !");
        }
     }
     queue_free(&(solvableQueue));
@@ -581,7 +665,7 @@ SATResolver::solving(const CapabilitySet & requires_caps,
        }
     }
 
-    if (solver_problem_count(_satSolver) > 0 )
+    if (solver_problem_count(_solv) > 0 )
     {
        ERR << "Solverrun finished with an ERROR" << endl;
        return false;
@@ -594,18 +678,21 @@ SATResolver::solving(const CapabilitySet & requires_caps,
 void
 SATResolver::solverInit(const PoolItemList & weakItems)
 {
+    SATCollectTransact info (*this);
 
     MIL << "SATResolver::solverInit()" << endl;
 
     // remove old stuff
     solverEnd();
+
     queue_init( &_jobQueue );
+    _items_to_install.clear();
+    _items_to_remove.clear();
+    _items_to_lock.clear();
+    _items_to_keep.clear();
 
-    // clear and rebuild: _items_to_install, _items_to_remove, _items_to_lock, _items_to_keep
-    {
-      SATCollectTransact collector( _items_to_install, _items_to_remove, _items_to_lock, _items_to_keep, solveSrcPackages() );
-      invokeOnEach ( _pool.begin(), _pool.end(), functor::functorRef<bool,PoolItem>( collector ) );
-    }
+    invokeOnEach ( _pool.begin(), _pool.end(),
+                  functor::functorRef<bool,PoolItem>(info) );
 
     for (PoolItemList::const_iterator iter = weakItems.begin(); iter != weakItems.end(); iter++) {
        Id id = (*iter)->satSolvable().id();
@@ -617,28 +704,14 @@ SATResolver::solverInit(const PoolItemList & weakItems)
         queue_push( &(_jobQueue), id );
     }
 
-    // Ad rules for changed requestedLocales
-    const auto & trackedLocaleIds( myPool().trackedLocaleIds() );
-    for ( const auto & locale : trackedLocaleIds.added() )
-    {
-      queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
-      queue_push( &(_jobQueue), Capability( ResolverNamespace::language, IdString(locale) ).id() );
-    }
-
-    for ( const auto & locale : trackedLocaleIds.removed() )
-    {
-      queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | SOLVER_CLEANDEPS );  // needs uncond. SOLVER_CLEANDEPS!
-      queue_push( &(_jobQueue), Capability( ResolverNamespace::language, IdString(locale) ).id() );
-    }
-
     // Add rules for parallel installable resolvables with different versions
-    for ( const sat::Solvable & solv : myPool().multiversionList() )
+    for_( it, sat::Pool::instance().multiversionBegin(), sat::Pool::instance().multiversionEnd() )
     {
-      queue_push( &(_jobQueue), SOLVER_NOOBSOLETES | SOLVER_SOLVABLE );
-      queue_push( &(_jobQueue), solv.id() );
+      queue_push( &(_jobQueue), SOLVER_NOOBSOLETES | SOLVER_SOLVABLE_NAME );
+      queue_push( &(_jobQueue), it->id() );
     }
 
-    ::pool_add_userinstalled_jobs(_satPool, sat::Pool::instance().autoInstalled(), &(_jobQueue), GET_USERINSTALLED_NAMES|GET_USERINSTALLED_INVERTED);
+    ::pool_add_userinstalled_jobs(_SATPool, sat::Pool::instance().autoInstalled(), &(_jobQueue), GET_USERINSTALLED_NAMES|GET_USERINSTALLED_INVERTED);
 
     if ( _distupgrade )
     {
@@ -677,10 +750,10 @@ void
 SATResolver::solverEnd()
 {
   // cleanup
-  if ( _satSolver )
+  if ( _solv )
   {
-    solver_free(_satSolver);
-    _satSolver = NULL;
+    solver_free(_solv);
+    _solv = NULL;
     queue_free( &(_jobQueue) );
   }
 }
@@ -811,8 +884,8 @@ void SATResolver::doUpdate()
     // set locks for the solver
     setLocks();
 
-    _satSolver = solver_create( _satPool );
-    ::pool_set_custom_vendorcheck( _satPool, &vendorCheck );
+    _solv = solver_create( _SATPool );
+    ::pool_set_custom_vendorcheck( _SATPool, &vendorCheck );
     if (_fixsystem) {
        queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL);
        queue_push( &(_jobQueue), 0 );
@@ -829,21 +902,21 @@ void SATResolver::doUpdate()
        queue_push( &(_jobQueue), SOLVER_DROP_ORPHANED|SOLVER_SOLVABLE_ALL);
        queue_push( &(_jobQueue), 0 );
     }
-    solver_set_flag(_satSolver, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended);
-    solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade);
-    solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
-    solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange);
-    solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange);
-    solver_set_flag(_satSolver, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
-    solver_set_flag(_satSolver, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
-    solver_set_flag(_satSolver, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
+    solver_set_flag(_solv, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended);
+    solver_set_flag(_solv, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade);
+    solver_set_flag(_solv, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
+    solver_set_flag(_solv, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange);
+    solver_set_flag(_solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange);
+    solver_set_flag(_solv, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
+    solver_set_flag(_solv, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
+    solver_set_flag(_solv, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
 
-    sat::Pool::instance().prepare();
+    sat::Pool::instance().prepareForSolving();
 
     // Solve !
     MIL << "Starting solving for update...." << endl;
     MIL << *this;
-    solver_solve( _satSolver, &(_jobQueue) );
+    solver_solve( _solv, &(_jobQueue) );
     MIL << "....Solver end" << endl;
 
     // copying solution back to zypp pool
@@ -852,14 +925,14 @@ void SATResolver::doUpdate()
     /*  solvables to be installed */
     Queue decisionq;
     queue_init(&decisionq);
-    solver_get_decisionqueue(_satSolver, &decisionq);
+    solver_get_decisionqueue(_solv, &decisionq);
     for (int i = 0; i < decisionq.count; i++)
     {
       Id p;
       p = decisionq.elements[i];
       if (p < 0 || !sat::Solvable(p))
        continue;
-      if (sat::Solvable(p).repository().get() == _satSolver->pool->installed)
+      if (sat::Solvable(p).repository().get() == _solv->pool->installed)
        continue;
 
       PoolItem poolItem = _pool.find (sat::Solvable(p));
@@ -872,9 +945,9 @@ void SATResolver::doUpdate()
     queue_free(&decisionq);
 
     /* solvables to be erased */
-    for (int i = _satSolver->pool->installed->start; i < _satSolver->pool->installed->start + _satSolver->pool->installed->nsolvables; i++)
+    for (int i = _solv->pool->installed->start; i < _solv->pool->installed->start + _solv->pool->installed->nsolvables; i++)
     {
-      if (solver_get_decisionlevel(_satSolver, i) > 0)
+      if (solver_get_decisionlevel(_solv, i) > 0)
          continue;
 
       PoolItem poolItem( _pool.find( sat::Solvable(i) ) );
@@ -958,7 +1031,7 @@ sat::Solvable SATResolver::mapSolvable ( const Id & id )
 string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreId)
 {
   string ret;
-  sat::detail::CPool *pool = _satSolver->pool;
+  Pool *pool = _solv->pool;
   Id probr;
   Id dep, source, target;
   sat::Solvable s, s2;
@@ -967,8 +1040,8 @@ string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreI
 
   // FIXME: solver_findallproblemrules to get all rules for this problem
   // (the 'most relevabt' one returned by solver_findproblemrule is embedded
-  probr = solver_findproblemrule(_satSolver, problem);
-  switch (solver_ruleinfo(_satSolver, probr, &source, &target, &dep))
+  probr = solver_findproblemrule(_solv, problem);
+  switch (solver_ruleinfo(_solv, probr, &source, &target, &dep))
   {
       case SOLVER_RULE_DISTUPGRADE:
          s = mapSolvable (source);
@@ -1050,7 +1123,7 @@ string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreI
              bool found = false;
              for_( iter2, possibleProviders.begin(), possibleProviders.end() ) {
                  PoolItem provider2 = ResPool::instance().find( *iter2 );
-                 if (compareByNVR (provider1,provider2) == 0
+                 if (compareByNVR (provider1.resolvable(),provider2.resolvable()) == 0
                      && ( (provider1.status().isInstalled() && provider2.status().isUninstalled())
                          || (provider2.status().isInstalled() && provider1.status().isUninstalled()) ))  {
                      found = true;
@@ -1077,10 +1150,8 @@ string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreI
          }
          if (providerlistUninstalled.size() > 0) {
              if (detail.size() > 0)
-                 // translators: 'uninstallable' == 'not installable'
                  detail += _("\nuninstallable providers: ");
              else
-                 // translators: 'uninstallable' == 'not installable'
                  detail = _("uninstallable providers: ");
              for (ProviderList::const_iterator iter = providerlistUninstalled.begin(); iter != providerlistUninstalled.end(); iter++) {
                  if (iter == providerlistUninstalled.begin())
@@ -1099,8 +1170,8 @@ ResolverProblemList
 SATResolver::problems ()
 {
     ResolverProblemList resolverProblems;
-    if (_satSolver && solver_problem_count(_satSolver)) {
-       sat::detail::CPool *pool = _satSolver->pool;
+    if (_solv && solver_problem_count(_solv)) {
+       Pool *pool = _solv->pool;
        int pcnt;
        Id p, rp, what;
        Id problem, solution, element;
@@ -1112,7 +1183,7 @@ SATResolver::problems ()
        MIL << "Encountered problems! Here are the solutions:\n" << endl;
        pcnt = 1;
        problem = 0;
-       while ((problem = solver_next_problem(_satSolver, problem)) != 0) {
+       while ((problem = solver_next_problem(_solv, problem)) != 0) {
            MIL << "Problem " <<  pcnt++ << ":" << endl;
            MIL << "====================================" << endl;
            string detail;
@@ -1123,10 +1194,10 @@ SATResolver::problems ()
            ResolverProblem_Ptr resolverProblem = new ResolverProblem (whatString, detail);
 
            solution = 0;
-           while ((solution = solver_next_solution(_satSolver, problem, solution)) != 0) {
+           while ((solution = solver_next_solution(_solv, problem, solution)) != 0) {
                element = 0;
-               ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi;
-               while ((element = solver_next_solutionelement(_satSolver, problem, solution, element, &p, &rp)) != 0) {
+               ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi(resolverProblem);
+               while ((element = solver_next_solutionelement(_solv, problem, solution, element, &p, &rp)) != 0) {
                    if (p == SOLVER_SOLUTION_JOB) {
                        /* job, rp is index into job queue */
                        what = _jobQueue.elements[rp];
@@ -1311,7 +1382,7 @@ SATResolver::problems ()
                            PoolItem itemTo = _pool.find (sd);
                            if (itemFrom && itemTo) {
                                problemSolution->addSingleAction (itemTo, INSTALL);
-                               int illegal = policy_is_illegal(_satSolver, s.get(), sd.get(), 0);
+                               int illegal = policy_is_illegal(_solv, s.get(), sd.get(), 0);
 
                                if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0)
                                {
@@ -1367,7 +1438,7 @@ SATResolver::problems ()
            if (ignoreId > 0) {
                // There is a possibility to ignore this error by setting weak dependencies
                PoolItem item = _pool.find (sat::Solvable(ignoreId));
-               ProblemSolutionIgnore *problemSolution = new ProblemSolutionIgnore(item);
+               ProblemSolutionIgnore *problemSolution = new ProblemSolutionIgnore(resolverProblem, item);
                resolverProblem->addSolution (problemSolution,
                                              false); // Solutions will be shown at the end
                MIL << "ignore some dependencies of " << item << endl;
@@ -1381,8 +1452,17 @@ SATResolver::problems ()
     return resolverProblems;
 }
 
-void SATResolver::applySolutions( const ProblemSolutionList & solutions )
-{ Resolver( _pool ).applySolutions( solutions ); }
+void
+SATResolver::applySolutions (const ProblemSolutionList & solutions)
+{
+    for (ProblemSolutionList::const_iterator iter = solutions.begin();
+        iter != solutions.end(); ++iter) {
+       ProblemSolution_Ptr solution = *iter;
+       Resolver dummyResolver(_pool);
+       if (!solution->apply (dummyResolver))
+           break;
+    }
+}
 
 void SATResolver::setLocks()
 {
@@ -1457,16 +1537,16 @@ void SATResolver::setSystemRequirements()
 sat::StringQueue SATResolver::autoInstalled() const
 {
   sat::StringQueue ret;
-  if ( _satSolver )
-    ::solver_get_userinstalled( _satSolver, ret, GET_USERINSTALLED_NAMES|GET_USERINSTALLED_INVERTED );
+  if ( _solv )
+    ::solver_get_userinstalled( _solv, ret, GET_USERINSTALLED_NAMES|GET_USERINSTALLED_INVERTED );
   return ret;
 }
 
 sat::StringQueue SATResolver::userInstalled() const
 {
   sat::StringQueue ret;
-  if ( _satSolver )
-    ::solver_get_userinstalled( _satSolver, ret, GET_USERINSTALLED_NAMES );
+  if ( _solv )
+    ::solver_get_userinstalled( _solv, ret, GET_USERINSTALLED_NAMES );
   return ret;
 }