<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -23,7 +23,6 @@
 #include &lt;paludis/util/attributes.hh&gt;
 #include &lt;paludis/util/sequence-fwd.hh&gt;
 #include &lt;tr1/memory&gt;
-#include &lt;iosfwd&gt;
 
 namespace paludis
 {
@@ -32,8 +31,6 @@ namespace paludis
         struct Arrow;
 
         typedef Sequence&lt;std::tr1::shared_ptr&lt;Arrow&gt; &gt; ArrowSequence;
-
-        std::ostream &amp; operator&lt;&lt; (std::ostream &amp; s, const Arrow &amp;) PALUDIS_VISIBLE;
     }
 }
 </diff>
      <filename>paludis/resolver/arrow-fwd.hh</filename>
    </modified>
    <modified>
      <diff>@@ -26,16 +26,6 @@
 using namespace paludis;
 using namespace paludis::resolver;
 
-std::ostream &amp;
-paludis::resolver::operator&lt;&lt; (std::ostream &amp; s, const Arrow &amp; a)
-{
-    s &lt;&lt; &quot;Arrow(-&gt; &quot; &lt;&lt; a.to_qpn_s();
-    if (0 != a.ignorable_pass())
-        s &lt;&lt; &quot;, ignorable pass &quot; &lt;&lt; a.ignorable_pass();
-    s &lt;&lt; &quot;)&quot;;
-    return s;
-}
-
 void
 Arrow::serialise(Serialiser &amp; s) const
 {</diff>
      <filename>paludis/resolver/arrow.cc</filename>
    </modified>
    <modified>
      <diff>@@ -23,7 +23,6 @@
 #include &lt;paludis/util/attributes.hh&gt;
 #include &lt;paludis/util/sequence-fwd.hh&gt;
 #include &lt;tr1/memory&gt;
-#include &lt;iosfwd&gt;
 
 namespace paludis
 {
@@ -31,8 +30,6 @@ namespace paludis
     {
         struct Constraint;
         struct Constraints;
-
-        std::ostream &amp; operator&lt;&lt; (std::ostream &amp; s, const Constraint &amp; c) PALUDIS_VISIBLE;
     }
 }
 </diff>
      <filename>paludis/resolver/constraint-fwd.hh</filename>
    </modified>
    <modified>
      <diff>@@ -31,22 +31,6 @@
 using namespace paludis;
 using namespace paludis::resolver;
 
-std::ostream &amp;
-paludis::resolver::operator&lt;&lt; (std::ostream &amp; s, const Constraint &amp; c)
-{
-    std::stringstream ss;
-    ss &lt;&lt; &quot;Constraint(spec: &quot; &lt;&lt; c.spec();
-    if (c.nothing_is_fine_too())
-        ss &lt;&lt; &quot;; nothing is fine too&quot;;
-    ss
-        &lt;&lt; &quot;; use_installed: &quot; &lt;&lt; stringify(c.use_installed())
-        &lt;&lt; &quot;; reason: &quot; &lt;&lt; (c.reason() ? stringify(*c.reason()) : &quot;none&quot;)
-        &lt;&lt; &quot;)&quot;;
-    s &lt;&lt; ss.str();
-
-    return s;
-}
-
 namespace paludis
 {
     template &lt;&gt;</diff>
      <filename>paludis/resolver/constraint.cc</filename>
    </modified>
    <modified>
      <diff>@@ -21,15 +21,12 @@
 #define PALUDIS_GUARD_PALUDIS_RESOLVER_DECISION_FWD_HH 1
 
 #include &lt;paludis/util/attributes.hh&gt;
-#include &lt;iosfwd&gt;
 
 namespace paludis
 {
     namespace resolver
     {
         struct Decision;
-
-        std::ostream &amp; operator&lt;&lt; (std::ostream &amp; s, const Decision &amp; d) PALUDIS_VISIBLE;
     }
 }
 </diff>
      <filename>paludis/resolver/decision-fwd.hh</filename>
    </modified>
    <modified>
      <diff>@@ -25,35 +25,6 @@
 using namespace paludis;
 using namespace paludis::resolver;
 
-std::ostream &amp;
-paludis::resolver::operator&lt;&lt; (std::ostream &amp; s, const Decision &amp; d)
-{
-    std::stringstream ss;
-
-    ss &lt;&lt; &quot;Decision(&quot;;
-
-    if (d.if_package_id())
-        ss &lt;&lt; *d.if_package_id();
-    else
-        ss &lt;&lt; &quot;(nothing)&quot;;
-
-    if (d.is_best())
-        ss &lt;&lt; &quot;, is best&quot;;
-    if (d.is_installed())
-        ss &lt;&lt; &quot;, is installed&quot;;
-    if (d.is_nothing())
-        ss &lt;&lt; &quot;, is nothing&quot;;
-    if (d.is_same())
-        ss &lt;&lt; &quot;, is same&quot;;
-    if (d.is_same_version())
-        ss &lt;&lt; &quot;, is same version&quot;;
-
-    ss &lt;&lt; &quot;)&quot;;
-
-    s &lt;&lt; ss.str();
-    return s;
-}
-
 void
 Decision::serialise(Serialiser &amp; s) const
 {</diff>
      <filename>paludis/resolver/decision.cc</filename>
    </modified>
    <modified>
      <diff>@@ -21,7 +21,6 @@
 #define PALUDIS_GUARD_PALUDIS_RESOLVER_DESTINATIONS_FWD_HH 1
 
 #include &lt;paludis/util/attributes.hh&gt;
-#include &lt;iosfwd&gt;
 
 namespace paludis
 {
@@ -29,9 +28,6 @@ namespace paludis
     {
         struct Destination;
         struct Destinations;
-
-        std::ostream &amp; operator&lt;&lt; (std::ostream &amp;, const Destination &amp;) PALUDIS_VISIBLE;
-        std::ostream &amp; operator&lt;&lt; (std::ostream &amp;, const Destinations &amp;) PALUDIS_VISIBLE;
     }
 }
 </diff>
      <filename>paludis/resolver/destinations-fwd.hh</filename>
    </modified>
    <modified>
      <diff>@@ -31,33 +31,6 @@
 using namespace paludis;
 using namespace paludis::resolver;
 
-std::ostream &amp;
-paludis::resolver::operator&lt;&lt; (std::ostream &amp; s, const Destination &amp; d)
-{
-    std::stringstream ss;
-    ss &lt;&lt; &quot;Destination(&quot; &lt;&lt; d.repository();
-    if (! d.replacing()-&gt;empty())
-        ss &lt;&lt; &quot; replacing &quot; &lt;&lt; join(indirect_iterator(d.replacing()-&gt;begin()),
-                indirect_iterator(d.replacing()-&gt;end()), &quot;, &quot;);
-    ss &lt;&lt; &quot;)&quot;;
-
-    s &lt;&lt; ss.str();
-    return s;
-}
-
-std::ostream &amp;
-paludis::resolver::operator&lt;&lt; (std::ostream &amp; s, const Destinations &amp; d)
-{
-    std::stringstream ss;
-    ss &lt;&lt; &quot;Destinations(&quot;;
-    if (d.slash())
-        ss &lt;&lt; &quot;slash: &quot; &lt;&lt; *d.slash();
-    ss &lt;&lt; &quot;)&quot;;
-
-    s &lt;&lt; ss.str();
-    return s;
-}
-
 void
 Destinations::serialise(Serialiser &amp; s) const
 {</diff>
      <filename>paludis/resolver/destinations.cc</filename>
    </modified>
    <modified>
      <diff>@@ -21,7 +21,6 @@
 #define PALUDIS_GUARD_PALUDIS_RESOLVER_REASON_FWD_HH 1
 
 #include &lt;paludis/util/attributes.hh&gt;
-#include &lt;iosfwd&gt;
 
 namespace paludis
 {
@@ -32,8 +31,6 @@ namespace paludis
         struct TargetReason;
         struct PresetReason;
         struct SetReason;
-
-        std::ostream &amp; operator&lt;&lt; (std::ostream &amp; s, const Reason &amp;) PALUDIS_VISIBLE;
     }
 }
 </diff>
      <filename>paludis/resolver/reason-fwd.hh</filename>
    </modified>
    <modified>
      <diff>@@ -27,23 +27,10 @@
 using namespace paludis;
 using namespace paludis::resolver;
 
-std::ostream &amp;
-paludis::resolver::operator&lt;&lt; (std::ostream &amp; s, const Reason &amp; r)
-{
-    s &lt;&lt; r.as_string();
-    return s;
-}
-
 Reason::~Reason()
 {
 }
 
-std::string
-TargetReason::as_string() const
-{
-    return &quot;Target()&quot;;
-}
-
 void
 TargetReason::serialise(Serialiser &amp; s) const
 {
@@ -89,12 +76,6 @@ DependencyReason::sanitised_dependency() const
     return _imp-&gt;dep;
 }
 
-std::string
-DependencyReason::as_string() const
-{
-    return &quot;Dependency(package: &quot; + stringify(*_imp-&gt;from_id) + &quot; dep: &quot; + stringify(_imp-&gt;dep) + &quot;)&quot;;
-}
-
 void
 DependencyReason::serialise(Serialiser &amp; s) const
 {
@@ -104,12 +85,6 @@ DependencyReason::serialise(Serialiser &amp; s) const
         ;
 }
 
-std::string
-PresetReason::as_string() const
-{
-    return &quot;Preset()&quot;;
-}
-
 void
 PresetReason::serialise(Serialiser &amp; s) const
 {
@@ -154,12 +129,6 @@ SetReason::reason_for_set() const
     return _imp-&gt;reason_for_set;
 }
 
-std::string
-SetReason::as_string() const
-{
-    return &quot;Set(set: &quot; + stringify(_imp-&gt;set_name) + &quot; because: &quot; + stringify(*_imp-&gt;reason_for_set) + &quot;)&quot;;
-}
-
 void
 SetReason::serialise(Serialiser &amp; s) const
 {</diff>
      <filename>paludis/resolver/reason.cc</filename>
    </modified>
    <modified>
      <diff>@@ -41,7 +41,6 @@ namespace paludis
         {
             public:
                 virtual ~Reason() = 0;
-                virtual std::string as_string() const = 0;
 
                 virtual void serialise(Serialiser &amp;) const = 0;
 
@@ -54,8 +53,6 @@ namespace paludis
             public ImplementAcceptMethods&lt;Reason, TargetReason&gt;
         {
             public:
-                virtual std::string as_string() const;
-
                 virtual void serialise(Serialiser &amp;) const;
         };
 
@@ -74,8 +71,6 @@ namespace paludis
                 const std::tr1::shared_ptr&lt;const PackageID&gt; from_id() const;
                 const SanitisedDependency &amp; sanitised_dependency() const;
 
-                virtual std::string as_string() const;
-
                 virtual void serialise(Serialiser &amp;) const;
         };
 
@@ -84,8 +79,6 @@ namespace paludis
             public ImplementAcceptMethods&lt;Reason, PresetReason&gt;
         {
             public:
-                virtual std::string as_string() const;
-
                 virtual void serialise(Serialiser &amp;) const;
         };
 
@@ -101,8 +94,6 @@ namespace paludis
                 const SetName set_name() const PALUDIS_ATTRIBUTE((warn_unused_result));
                 const std::tr1::shared_ptr&lt;const Reason&gt; reason_for_set() const PALUDIS_ATTRIBUTE((warn_unused_result));
 
-                virtual std::string as_string() const;
-
                 virtual void serialise(Serialiser &amp;) const;
         };
     }</diff>
      <filename>paludis/resolver/reason.hh</filename>
    </modified>
    <modified>
      <diff>@@ -22,15 +22,12 @@
 
 #include &lt;paludis/util/attributes.hh&gt;
 #include &lt;paludis/resolver/serialise-fwd.hh&gt;
-#include &lt;iosfwd&gt;
 
 namespace paludis
 {
     namespace resolver
     {
         struct Resolution;
-
-        std::ostream &amp; operator&lt;&lt; (std::ostream &amp; s, const Resolution &amp; r) PALUDIS_VISIBLE;
     }
 }
 </diff>
      <filename>paludis/resolver/resolution-fwd.hh</filename>
    </modified>
    <modified>
      <diff>@@ -34,21 +34,6 @@
 using namespace paludis;
 using namespace paludis::resolver;
 
-std::ostream &amp;
-paludis::resolver::operator&lt;&lt; (std::ostream &amp; s, const Resolution &amp; r)
-{
-    std::stringstream ss;
-    ss &lt;&lt;  &quot;Resolution(&quot;
-        &lt;&lt; &quot;constraints: &quot; &lt;&lt; join(indirect_iterator(r.constraints()-&gt;begin()), indirect_iterator(r.constraints()-&gt;end()), &quot;, &quot;)
-        &lt;&lt; &quot;; decision: &quot; &lt;&lt; (r.decision() ? stringify(*r.decision()) : &quot;none&quot;)
-        &lt;&lt; &quot;; arrows: &quot; &lt;&lt; join(indirect_iterator(r.arrows()-&gt;begin()), indirect_iterator(r.arrows()-&gt;end()), &quot;, &quot;)
-        &lt;&lt; &quot;; already_ordered: &quot; &lt;&lt; stringify(r.already_ordered()) &lt;&lt; &quot;)&quot;
-        &lt;&lt; &quot;; destinations: &quot; &lt;&lt; (r.destinations() ? stringify(*r.destinations()) : &quot;unknown&quot;)
-        &lt;&lt; &quot;)&quot;;
-    s &lt;&lt; ss.str();
-    return s;
-}
-
 void
 Resolution::serialise(Serialiser &amp; s) const
 {</diff>
      <filename>paludis/resolver/resolution.cc</filename>
    </modified>
    <modified>
      <diff>@@ -196,7 +196,8 @@ Resolver::_make_slash_destination_for(const QPN_S &amp; qpn_s,
     }
 
     if (! repo)
-        throw InternalError(PALUDIS_HERE, &quot;no valid destination for &quot; + stringify(*resolution));
+        throw InternalError(PALUDIS_HERE, &quot;no valid destination for &quot; +
+                stringify(*resolution-&gt;decision()-&gt;if_package_id()));
 
     return make_shared_ptr(new Destination(make_named_values&lt;Destination&gt;(
                     value_for&lt;n::replacing&gt;(_find_replacing(resolution-&gt;decision()-&gt;if_package_id(), repo)),
@@ -257,7 +258,8 @@ Resolver::_same_slot(const std::tr1::shared_ptr&lt;const PackageID&gt; &amp; a,
 void
 Resolver::add_target_with_reason(const PackageDepSpec &amp; spec, const std::tr1::shared_ptr&lt;const Reason&gt; &amp; reason)
 {
-    Context context(&quot;When adding target '&quot; + stringify(spec) + &quot;' with reason '&quot; + stringify(*reason) + &quot;':&quot;);
+    Context context(&quot;When adding target '&quot; + stringify(spec) + &quot;':&quot;);
+
     _imp-&gt;env-&gt;trigger_notifier_callback(NotifierCallbackResolverStepEvent());
 
     const std::tr1::shared_ptr&lt;const QPN_S_Sequence&gt; qpn_s_s(_imp-&gt;fns.get_qpn_s_s_for_fn()(spec, reason));
@@ -479,11 +481,17 @@ Resolver::_made_wrong_decision(const QPN_S &amp; qpn_s,
             /* we've not already locked this to something. yes! */
             _suggest_restart_with(qpn_s, resolution, constraint, decision);
         }
-        else
+        else if (decision-&gt;if_package_id())
         {
             /* we can restart if we've selected the same or a newer version
              * than before. but we don't support that yet. */
-            throw InternalError(PALUDIS_HERE, &quot;should have selected &quot; + stringify(*decision));
+            throw InternalError(PALUDIS_HERE, &quot;should have selected &quot; + stringify(*decision-&gt;if_package_id()));
+        }
+        else
+        {
+            /* probably possible if we can fix a block either by upgrading or
+             * removing, and we're later forced to remove */
+            throw InternalError(PALUDIS_HERE, &quot;should have selected nothing&quot;);
         }
     }
     else
@@ -522,8 +530,7 @@ Resolver::_make_constraint_for_preloading(
 void
 Resolver::_decide(const QPN_S &amp; qpn_s, const std::tr1::shared_ptr&lt;Resolution&gt; &amp; resolution)
 {
-    Context context(&quot;When deciding upon an origin ID to use for '&quot; + stringify(qpn_s) + &quot;' with '&quot;
-            + stringify(*resolution) + &quot;':&quot;);
+    Context context(&quot;When deciding upon an origin ID to use for '&quot; + stringify(qpn_s) + &quot;':&quot;);
 
     std::tr1::shared_ptr&lt;Decision&gt; decision(_try_to_find_decision_for(qpn_s, resolution));
     if (decision)
@@ -535,12 +542,12 @@ Resolver::_decide(const QPN_S &amp; qpn_s, const std::tr1::shared_ptr&lt;Resolution&gt; &amp;
 void
 Resolver::_add_dependencies(const QPN_S &amp; our_qpn_s, const std::tr1::shared_ptr&lt;Resolution&gt; &amp; our_resolution)
 {
-    Context context(&quot;When adding dependencies for '&quot; + stringify(our_qpn_s) + &quot;' with '&quot;
-            + stringify(*our_resolution) + &quot;':&quot;);
-
     if (! our_resolution-&gt;decision()-&gt;if_package_id())
         throw InternalError(PALUDIS_HERE, &quot;not decided. shouldn't happen.&quot;);
 
+    Context context(&quot;When adding dependencies for '&quot; + stringify(our_qpn_s) + &quot;' with '&quot;
+            + stringify(*our_resolution-&gt;decision()-&gt;if_package_id()) + &quot;':&quot;);
+
     const std::tr1::shared_ptr&lt;SanitisedDependencies&gt; deps(new SanitisedDependencies);
     deps-&gt;populate(*this, our_resolution-&gt;decision()-&gt;if_package_id());
     our_resolution-&gt;sanitised_dependencies() = deps;
@@ -548,7 +555,7 @@ Resolver::_add_dependencies(const QPN_S &amp; our_qpn_s, const std::tr1::shared_ptr&lt;
     for (SanitisedDependencies::ConstIterator s(deps-&gt;begin()), s_end(deps-&gt;end()) ;
             s != s_end ; ++s)
     {
-        Context context_2(&quot;When handling dependency '&quot; + stringify(*s) + &quot;':&quot;);
+        Context context_2(&quot;When handling dependency '&quot; + stringify(s-&gt;spec()) + &quot;':&quot;);
 
         if (! _care_about_dependency_spec(our_qpn_s, our_resolution, *s))
             continue;
@@ -567,7 +574,8 @@ Resolver::_add_dependencies(const QPN_S &amp; our_qpn_s, const std::tr1::shared_ptr&lt;
         {
             if (our_resolution-&gt;decision()-&gt;is_installed())
                 Log::get_instance()-&gt;message(&quot;resolver.cannot_find_installed_dep&quot;, ll_warning, lc_context)
-                    &lt;&lt; &quot;Installed package '&quot; &lt;&lt; *our_resolution-&gt;decision() &lt;&lt; &quot;' dependency '&quot; &lt;&lt; *s &lt;&lt; &quot; cannot be met&quot;;
+                    &lt;&lt; &quot;Installed package '&quot; &lt;&lt; *our_resolution-&gt;decision()-&gt;if_package_id()
+                    &lt;&lt; &quot;' dependency '&quot; &lt;&lt; s-&gt;spec() &lt;&lt; &quot;' cannot be met&quot;;
             else
                 throw InternalError(PALUDIS_HERE, &quot;not implemented: no slot for &quot; + stringify(s-&gt;spec()));
         }
@@ -592,7 +600,7 @@ Resolver::_care_about_dependency_spec(const QPN_S &amp; qpn_s,
         if (dep.spec().if_block()-&gt;blocked_spec()-&gt;package_ptr()-&gt;category() == CategoryNamePart(&quot;virtual&quot;))
         {
             Log::get_instance()-&gt;message(&quot;resolver.virtual_haxx&quot;, ll_warning, lc_context)
-                &lt;&lt; &quot;Ignoring &quot; &lt;&lt; dep &lt;&lt; &quot; from &quot; &lt;&lt; qpn_s &lt;&lt; &quot; for now&quot;;
+                &lt;&lt; &quot;Ignoring &quot; &lt;&lt; dep.spec() &lt;&lt; &quot; from &quot; &lt;&lt; qpn_s &lt;&lt; &quot; for now&quot;;
             return false;
         }
 
@@ -839,7 +847,8 @@ Resolver::_unable_to_order_more() const
         if (i-&gt;second-&gt;already_ordered())
             continue;
 
-        std::cout &lt;&lt; &quot;  * &quot; &lt;&lt; *i-&gt;second-&gt;decision() &lt;&lt; &quot; because of cycle &quot; &lt;&lt; _find_cycle(i-&gt;first, true)
+        std::cout &lt;&lt; &quot;  * &quot; &lt;&lt; *i-&gt;second-&gt;decision()-&gt;if_package_id() &lt;&lt; &quot; because of cycle &quot;
+            &lt;&lt; _find_cycle(i-&gt;first, true)
             &lt;&lt; std::endl;
     }
 
@@ -873,7 +882,7 @@ Resolver::end_resolutions_by_qpn_s() const
 int
 Resolver::find_any_score(const QPN_S &amp; our_qpn_s, const SanitisedDependency &amp; dep) const
 {
-    Context context(&quot;When working out whether we'd like '&quot; + stringify(dep) + &quot;' because of '&quot;
+    Context context(&quot;When working out whether we'd like '&quot; + stringify(dep.spec()) + &quot;' because of '&quot;
             + stringify(our_qpn_s) + &quot;':&quot;);
 
     if (dep.spec().if_block())
@@ -1041,13 +1050,7 @@ Resolver::_find_cycle(const QPN_S &amp; start_qpn_s, const int ignorable_pass) const
         }
 
         if (! ok)
-            throw InternalError(PALUDIS_HERE, &quot;why did that happen? start is &quot; + stringify(start_qpn_s)
-                    + &quot;, current is &quot; + stringify(current) + &quot;, seen is { &quot;
-                    + join(seen.begin(), seen.end(), &quot;, &quot;) + &quot; }, result is &quot;
-                    + result.str() + &quot;, resolution-&gt;arrows is { &quot;
-                    + join(indirect_iterator(resolution-&gt;arrows()-&gt;begin()),
-                        indirect_iterator(resolution-&gt;arrows()-&gt;end()), &quot;, &quot;) + &quot;}&quot;
-                    );
+            throw InternalError(PALUDIS_HERE, &quot;why did that happen?&quot;);
     }
 
     return result.str();</diff>
      <filename>paludis/resolver/resolver.cc</filename>
    </modified>
    <modified>
      <diff>@@ -32,7 +32,6 @@ namespace paludis
 
         struct PackageOrBlockDepSpec;
 
-        std::ostream &amp; operator&lt;&lt; (std::ostream &amp; s, const SanitisedDependency &amp; d) PALUDIS_VISIBLE;
         std::ostream &amp; operator&lt;&lt; (std::ostream &amp; s, const PackageOrBlockDepSpec &amp; d) PALUDIS_VISIBLE;
     }
 }</diff>
      <filename>paludis/resolver/sanitised_dependencies-fwd.hh</filename>
    </modified>
    <modified>
      <diff>@@ -374,31 +374,6 @@ SanitisedDependencies::end() const
 }
 
 std::ostream &amp;
-paludis::resolver::operator&lt;&lt; (std::ostream &amp; s, const SanitisedDependency &amp; d)
-{
-    std::stringstream ss;
-    ss &lt;&lt; &quot;Dep(&quot; &lt;&lt; d.spec();
-
-    if (! d.active_dependency_labels()-&gt;system_labels()-&gt;empty())
-        ss &lt;&lt; &quot; system { &quot; &lt;&lt; join(indirect_iterator(d.active_dependency_labels()-&gt;system_labels()-&gt;begin()),
-                indirect_iterator(d.active_dependency_labels()-&gt;system_labels()-&gt;end()), &quot;, &quot;) &lt;&lt; &quot; }&quot;;
-    if (! d.active_dependency_labels()-&gt;type_labels()-&gt;empty())
-        ss &lt;&lt; &quot; type { &quot; &lt;&lt; join(indirect_iterator(d.active_dependency_labels()-&gt;type_labels()-&gt;begin()),
-                indirect_iterator(d.active_dependency_labels()-&gt;type_labels()-&gt;end()), &quot;, &quot;) &lt;&lt; &quot; }&quot;;
-    if (! d.active_dependency_labels()-&gt;abi_labels()-&gt;empty())
-        ss &lt;&lt; &quot; abi { &quot; &lt;&lt; join(indirect_iterator(d.active_dependency_labels()-&gt;abi_labels()-&gt;begin()),
-                indirect_iterator(d.active_dependency_labels()-&gt;abi_labels()-&gt;end()), &quot;, &quot;) &lt;&lt; &quot; }&quot;;
-    if (! d.active_dependency_labels()-&gt;suggest_labels()-&gt;empty())
-        ss &lt;&lt; &quot; suggest { &quot; &lt;&lt; join(indirect_iterator(d.active_dependency_labels()-&gt;suggest_labels()-&gt;begin()),
-                indirect_iterator(d.active_dependency_labels()-&gt;suggest_labels()-&gt;end()), &quot;, &quot;) &lt;&lt; &quot; }&quot;;
-
-    ss &lt;&lt; &quot;)&quot;;
-
-    s &lt;&lt; ss.str();
-    return s;
-}
-
-std::ostream &amp;
 paludis::resolver::operator&lt;&lt; (std::ostream &amp; s, const PackageOrBlockDepSpec &amp; d)
 {
     if (d.if_package())</diff>
      <filename>paludis/resolver/sanitised_dependencies.cc</filename>
    </modified>
    <modified>
      <diff>@@ -19,6 +19,7 @@
 
 #include &lt;paludis/resolver/suggest_restart.hh&gt;
 #include &lt;paludis/resolver/qpn_s.hh&gt;
+#include &lt;paludis/resolver/constraint.hh&gt;
 #include &lt;paludis/util/private_implementation_pattern-impl.hh&gt;
 #include &lt;paludis/util/stringify.hh&gt;
 
@@ -59,7 +60,7 @@ SuggestRestart::SuggestRestart(const QPN_S &amp; q,
         const std::tr1::shared_ptr&lt;const Constraint&gt; &amp; nc
         ) throw () :
     PrivateImplementationPattern&lt;SuggestRestart&gt;(new Implementation&lt;SuggestRestart&gt;(q, pd, pc, nd, nc)),
-    Exception(&quot;Suggesting restart with &quot; + stringify(*nc) + &quot; for &quot; + stringify(q))
+    Exception(&quot;Suggesting restart with &quot; + stringify(nc-&gt;spec()) + &quot; for &quot; + stringify(q))
 {
 }
 </diff>
      <filename>paludis/resolver/suggest_restart.cc</filename>
    </modified>
    <modified>
      <diff>@@ -379,7 +379,8 @@ namespace
 
         void visit(const DependencyReason &amp; reason)
         {
-            std::cout &lt;&lt; &quot;of dependency &quot; &lt;&lt; reason.sanitised_dependency() &lt;&lt; &quot; from &quot; &lt;&lt; *reason.from_id();
+            std::cout &lt;&lt; &quot;of dependency &quot; &lt;&lt; reason.sanitised_dependency().spec()
+                &lt;&lt; &quot; from &quot; &lt;&lt; *reason.from_id();
         }
 
         void visit(const PresetReason &amp;)</diff>
      <filename>src/clients/cave/cmd_display_resolution.cc</filename>
    </modified>
    <modified>
      <diff>@@ -679,20 +679,19 @@ ResolveCommand::run(
     {
         while (true)
         {
+            DisplayCallback display_callback;
+            ScopedNotifierCallback display_callback_holder(env.get(),
+                    NotifierCallbackFunction(std::tr1::cref(display_callback)));
+
             try
             {
-                DisplayCallback display_callback;
-                ScopedNotifierCallback display_callback_holder(env.get(),
-                        NotifierCallbackFunction(std::tr1::cref(display_callback)));
                 add_resolver_targets(env, resolver, cmdline);
                 resolver-&gt;resolve();
                 break;
             }
             catch (const SuggestRestart &amp; e)
             {
-                std::cout &lt;&lt; &quot;Restarting: for '&quot; &lt;&lt; e.qpn_s() &lt;&lt; &quot;' we had chosen '&quot; &lt;&lt; *e.previous_decision()
-                    &lt;&lt; &quot;' but new constraint '&quot; &lt;&lt; *e.problematic_constraint() &lt;&lt; &quot;' means we now want '&quot;
-                    &lt;&lt; *e.new_decision() &lt;&lt; &quot;' instead&quot; &lt;&lt; std::endl;
+                display_callback(ResolverRestart());
                 initial_constraints.insert(std::make_pair(e.qpn_s(), make_initial_constraints_for(
                                 env.get(), cmdline, e.qpn_s()))).first-&gt;second-&gt;add(
                         e.suggested_preset());</diff>
      <filename>src/clients/cave/cmd_resolve.cc</filename>
    </modified>
    <modified>
      <diff>@@ -62,6 +62,14 @@ DisplayCallback::operator() (const NotifierCallbackEvent &amp; event) const
 }
 
 void
+DisplayCallback::operator() (const ResolverRestart &amp;) const
+{
+    Lock lock(_imp-&gt;mutex);
+    ++_imp-&gt;steps.insert(std::make_pair(&quot;restarts&quot;, 0)).first-&gt;second;
+    update();
+}
+
+void
 DisplayCallback::visit(const NotifierCallbackGeneratingMetadataEvent &amp; e) const
 {
     Lock lock(_imp-&gt;mutex);</diff>
      <filename>src/clients/cave/cmd_resolve_display_callback.cc</filename>
    </modified>
    <modified>
      <diff>@@ -28,7 +28,11 @@ namespace paludis
 {
     namespace cave
     {
-        struct DisplayCallback :
+        struct ResolverRestart
+        {
+        };
+
+        class DisplayCallback :
             private PrivateImplementationPattern&lt;DisplayCallback&gt;
         {
             private:
@@ -40,6 +44,8 @@ namespace paludis
 
                 void operator() (const NotifierCallbackEvent &amp; event) const;
 
+                void operator() (const ResolverRestart &amp;) const;
+
                 void visit(const NotifierCallbackGeneratingMetadataEvent &amp;) const;
 
                 void visit(const NotifierCallbackResolverStepEvent &amp;) const;</diff>
      <filename>src/clients/cave/cmd_resolve_display_callback.hh</filename>
    </modified>
    <modified>
      <diff>@@ -22,15 +22,239 @@
 #include &lt;paludis/resolver/qpn_s.hh&gt;
 #include &lt;paludis/resolver/sanitised_dependencies.hh&gt;
 #include &lt;paludis/resolver/resolution.hh&gt;
+#include &lt;paludis/resolver/constraint.hh&gt;
+#include &lt;paludis/resolver/decision.hh&gt;
+#include &lt;paludis/resolver/destinations.hh&gt;
+#include &lt;paludis/resolver/reason.hh&gt;
+#include &lt;paludis/resolver/arrow.hh&gt;
+#include &lt;paludis/util/indirect_iterator-impl.hh&gt;
+#include &lt;paludis/util/join.hh&gt;
+#include &lt;paludis/util/stringify.hh&gt;
+#include &lt;paludis/util/wrapped_forward_iterator.hh&gt;
 #include &lt;iostream&gt;
+#include &lt;sstream&gt;
 
 using namespace paludis;
 using namespace cave;
 using namespace paludis::resolver;
 
+namespace
+{
+    std::ostream &amp;
+    operator&lt;&lt; (std::ostream &amp; s, const Decision &amp; d)
+    {
+        std::stringstream ss;
+
+        ss &lt;&lt; &quot;Decision(&quot;;
+
+        if (d.if_package_id())
+            ss &lt;&lt; *d.if_package_id();
+        else
+            ss &lt;&lt; &quot;(nothing)&quot;;
+
+        if (d.is_best())
+            ss &lt;&lt; &quot;, is best&quot;;
+        if (d.is_installed())
+            ss &lt;&lt; &quot;, is installed&quot;;
+        if (d.is_nothing())
+            ss &lt;&lt; &quot;, is nothing&quot;;
+        if (d.is_same())
+            ss &lt;&lt; &quot;, is same&quot;;
+        if (d.is_same_version())
+            ss &lt;&lt; &quot;, is same version&quot;;
+
+        ss &lt;&lt; &quot;)&quot;;
+
+        s &lt;&lt; ss.str();
+        return s;
+    }
+
+    std::ostream &amp;
+    operator&lt;&lt; (std::ostream &amp; s, const Destination &amp; d)
+    {
+        std::stringstream ss;
+        ss &lt;&lt; &quot;Destination(&quot; &lt;&lt; d.repository();
+        if (! d.replacing()-&gt;empty())
+            ss &lt;&lt; &quot; replacing &quot; &lt;&lt; join(indirect_iterator(d.replacing()-&gt;begin()),
+                    indirect_iterator(d.replacing()-&gt;end()), &quot;, &quot;);
+        ss &lt;&lt; &quot;)&quot;;
+
+        s &lt;&lt; ss.str();
+        return s;
+    }
+
+    std::ostream &amp;
+    operator&lt;&lt; (std::ostream &amp; s, const Destinations &amp; d)
+    {
+        std::stringstream ss;
+        ss &lt;&lt; &quot;Destinations(&quot;;
+        if (d.slash())
+            ss &lt;&lt; &quot;slash: &quot; &lt;&lt; *d.slash();
+        ss &lt;&lt; &quot;)&quot;;
+
+        s &lt;&lt; ss.str();
+        return s;
+    }
+
+    std::ostream &amp;
+    operator&lt;&lt; (std::ostream &amp; s, const SanitisedDependency &amp; d)
+    {
+        std::stringstream ss;
+        ss &lt;&lt; &quot;Dep(&quot; &lt;&lt; d.spec();
+
+        if (! d.active_dependency_labels()-&gt;system_labels()-&gt;empty())
+            ss &lt;&lt; &quot; system { &quot; &lt;&lt; join(indirect_iterator(d.active_dependency_labels()-&gt;system_labels()-&gt;begin()),
+                    indirect_iterator(d.active_dependency_labels()-&gt;system_labels()-&gt;end()), &quot;, &quot;) &lt;&lt; &quot; }&quot;;
+        if (! d.active_dependency_labels()-&gt;type_labels()-&gt;empty())
+            ss &lt;&lt; &quot; type { &quot; &lt;&lt; join(indirect_iterator(d.active_dependency_labels()-&gt;type_labels()-&gt;begin()),
+                    indirect_iterator(d.active_dependency_labels()-&gt;type_labels()-&gt;end()), &quot;, &quot;) &lt;&lt; &quot; }&quot;;
+        if (! d.active_dependency_labels()-&gt;abi_labels()-&gt;empty())
+            ss &lt;&lt; &quot; abi { &quot; &lt;&lt; join(indirect_iterator(d.active_dependency_labels()-&gt;abi_labels()-&gt;begin()),
+                    indirect_iterator(d.active_dependency_labels()-&gt;abi_labels()-&gt;end()), &quot;, &quot;) &lt;&lt; &quot; }&quot;;
+        if (! d.active_dependency_labels()-&gt;suggest_labels()-&gt;empty())
+            ss &lt;&lt; &quot; suggest { &quot; &lt;&lt; join(indirect_iterator(d.active_dependency_labels()-&gt;suggest_labels()-&gt;begin()),
+                    indirect_iterator(d.active_dependency_labels()-&gt;suggest_labels()-&gt;end()), &quot;, &quot;) &lt;&lt; &quot; }&quot;;
+
+        ss &lt;&lt; &quot;)&quot;;
+
+        s &lt;&lt; ss.str();
+        return s;
+    }
+
+    struct ReasonFinder
+    {
+        std::string str;
+
+        ReasonFinder() :
+            str(&quot;none&quot;)
+        {
+        }
+
+        void visit(const TargetReason &amp;)
+        {
+            str = &quot;Target&quot;;
+        }
+
+        void visit(const PresetReason &amp;)
+        {
+            str = &quot;Preset&quot;;
+        }
+
+        void visit(const SetReason &amp; r)
+        {
+            ReasonFinder f;
+            if (r.reason_for_set())
+                r.reason_for_set()-&gt;accept(f);
+            str = &quot;Set(&quot; + stringify(r.set_name()) + &quot; &quot; + f.str + &quot;)&quot;;
+        }
+
+        void visit(const DependencyReason &amp; r)
+        {
+            std::stringstream s;
+            s &lt;&lt; r.sanitised_dependency();
+            str = &quot;Dependency(&quot; + s.str() + &quot;)&quot;;
+        }
+    };
+
+    std::ostream &amp;
+    operator&lt;&lt; (std::ostream &amp; s, const Constraint &amp; c)
+    {
+        std::stringstream ss;
+        ss &lt;&lt; &quot;Constraint(spec: &quot; &lt;&lt; c.spec();
+        if (c.nothing_is_fine_too())
+            ss &lt;&lt; &quot;; nothing is fine too&quot;;
+        ss
+            &lt;&lt; &quot;; use_installed: &quot; &lt;&lt; stringify(c.use_installed())
+            &lt;&lt; &quot;; reason: &quot;;
+
+        ReasonFinder r;
+        if (c.reason())
+            c.reason()-&gt;accept(r);
+        ss
+            &lt;&lt; r.str &lt;&lt; &quot;)&quot;;
+        s &lt;&lt; ss.str();
+
+        return s;
+    }
+
+    std::ostream &amp;
+    operator&lt;&lt; (std::ostream &amp; s, const Arrow &amp; a)
+    {
+        s &lt;&lt; &quot;Arrow(-&gt; &quot; &lt;&lt; a.to_qpn_s();
+        if (0 != a.ignorable_pass())
+            s &lt;&lt; &quot;, ignorable pass &quot; &lt;&lt; a.ignorable_pass();
+        s &lt;&lt; &quot;)&quot;;
+        return s;
+    }
+
+    std::string stringify_constraint(const Constraint &amp; c)
+    {
+        std::stringstream s;
+        s &lt;&lt; c;
+        return s.str();
+    }
+
+    std::string stringify_arrow(const Arrow &amp; a)
+    {
+        std::stringstream s;
+        s &lt;&lt; a;
+        return s.str();
+    }
+
+    std::ostream &amp;
+    operator&lt;&lt; (std::ostream &amp; s, const Resolution &amp; r)
+    {
+        std::stringstream ss;
+        ss &lt;&lt;  &quot;Resolution(&quot;
+            &lt;&lt; &quot;constraints: &quot; &lt;&lt; join(indirect_iterator(r.constraints()-&gt;begin()),
+                    indirect_iterator(r.constraints()-&gt;end()), &quot;, &quot;, stringify_constraint)
+            &lt;&lt; &quot;; decision: &quot;;
+        if (r.decision())
+            ss &lt;&lt; *r.decision();
+        else
+            ss &lt;&lt; &quot;none&quot;;
+        ss
+            &lt;&lt; &quot;; arrows: &quot; &lt;&lt; join(indirect_iterator(r.arrows()-&gt;begin()),
+                    indirect_iterator(r.arrows()-&gt;end()), &quot;, &quot;, stringify_arrow)
+            &lt;&lt; &quot;; already_ordered: &quot; &lt;&lt; stringify(r.already_ordered()) &lt;&lt; &quot;)&quot;
+            &lt;&lt; &quot;; destinations: &quot;;
+        if (r.destinations())
+            ss &lt;&lt; *r.destinations();
+        else
+            ss &lt;&lt; &quot;unknown&quot;;
+        ss
+            &lt;&lt; &quot;)&quot;;
+        s &lt;&lt; ss.str();
+        return s;
+    }
+
+    void dump(
+            const std::tr1::shared_ptr&lt;Environment&gt; &amp;,
+            const std::tr1::shared_ptr&lt;Resolver&gt; &amp; resolver,
+            const ResolveCommandLine &amp; cmdline)
+    {
+        std::cout &lt;&lt; &quot;Dumping resolutions by QPN:S:&quot; &lt;&lt; std::endl &lt;&lt; std::endl;
+
+        for (Resolver::ResolutionsByQPN_SConstIterator c(resolver-&gt;begin_resolutions_by_qpn_s()),
+                c_end(resolver-&gt;end_resolutions_by_qpn_s()) ;
+                c != c_end ; ++c)
+        {
+            std::cout &lt;&lt; c-&gt;first &lt;&lt; std::endl;
+            std::cout &lt;&lt; &quot;  = &quot; &lt;&lt; *c-&gt;second &lt;&lt; std::endl;
+            if (cmdline.resolution_options.a_dump_dependencies.specified() &amp;&amp; c-&gt;second-&gt;sanitised_dependencies())
+                for (SanitisedDependencies::ConstIterator d(c-&gt;second-&gt;sanitised_dependencies()-&gt;begin()),
+                        d_end(c-&gt;second-&gt;sanitised_dependencies()-&gt;end()) ;
+                        d != d_end ; ++d)
+                    std::cout &lt;&lt; &quot;  -&gt; &quot; &lt;&lt; *d &lt;&lt; std::endl;
+        }
+
+        std::cout &lt;&lt; std::endl;
+    }
+}
+
 void
 paludis::cave::dump_if_requested(
-        const std::tr1::shared_ptr&lt;Environment&gt; &amp;,
+        const std::tr1::shared_ptr&lt;Environment&gt; &amp; env,
         const std::tr1::shared_ptr&lt;Resolver&gt; &amp; resolver,
         const ResolveCommandLine &amp; cmdline)
 {
@@ -39,21 +263,6 @@ paludis::cave::dump_if_requested(
     if (! cmdline.resolution_options.a_dump.specified())
         return;
 
-    std::cout &lt;&lt; &quot;Dumping resolutions by QPN:S:&quot; &lt;&lt; std::endl &lt;&lt; std::endl;
-
-    for (Resolver::ResolutionsByQPN_SConstIterator c(resolver-&gt;begin_resolutions_by_qpn_s()),
-            c_end(resolver-&gt;end_resolutions_by_qpn_s()) ;
-            c != c_end ; ++c)
-    {
-        std::cout &lt;&lt; c-&gt;first &lt;&lt; std::endl;
-        std::cout &lt;&lt; &quot;  = &quot; &lt;&lt; *c-&gt;second &lt;&lt; std::endl;
-        if (cmdline.resolution_options.a_dump_dependencies.specified() &amp;&amp; c-&gt;second-&gt;sanitised_dependencies())
-            for (SanitisedDependencies::ConstIterator d(c-&gt;second-&gt;sanitised_dependencies()-&gt;begin()),
-                    d_end(c-&gt;second-&gt;sanitised_dependencies()-&gt;end()) ;
-                    d != d_end ; ++d)
-                std::cout &lt;&lt; &quot;  -&gt; &quot; &lt;&lt; *d &lt;&lt; std::endl;
-    }
-
-    std::cout &lt;&lt; std::endl;
+    dump(env, resolver, cmdline);
 }
 </diff>
      <filename>src/clients/cave/cmd_resolve_dump.cc</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>8939f5a4b07bd4f1fe044d4bb7b6a48c7c76097c</id>
    </parent>
  </parents>
  <author>
    <name>Ciaran McCreesh</name>
    <email>ciaran.mccreesh@googlemail.com</email>
  </author>
  <url>http://github.com/ciaranm/paludis-ciaranm/commit/44dd3df4741f11942e580036f6589054ac42d551</url>
  <id>44dd3df4741f11942e580036f6589054ac42d551</id>
  <committed-date>2009-09-06T13:45:18-07:00</committed-date>
  <authored-date>2009-09-06T13:45:00-07:00</authored-date>
  <message>Don't make internals stringifiable</message>
  <tree>9597f1cb83fc94c861d308186444b306174adad7</tree>
  <committer>
    <name>Ciaran McCreesh</name>
    <email>ciaran.mccreesh@googlemail.com</email>
  </committer>
</commit>
