@Override
 public void done(
     ConstraintSystemSolution solution, Set<TypeParameterDescriptor> typeParameterDescriptors) {
   if (!ResolutionDebugInfo.isResolutionDebugEnabled()) return;
   debugInfo.putByKey(SOLUTION, candidateCall, solution);
   debugInfo.putByKey(UNKNOWNS, candidateCall, typeParameterDescriptors);
 }
 @Override
 public void constraintsForKnownType(JetType type, BoundsOwner typeValue) {
   if (!ResolutionDebugInfo.isResolutionDebugEnabled()) return;
   Map<JetType, BoundsOwner> map = debugInfo.getByKey(BOUNDS_FOR_KNOWNS, candidateCall);
   if (map == null) {
     map = Maps.newLinkedHashMap();
     debugInfo.putByKey(BOUNDS_FOR_KNOWNS, candidateCall, map);
   }
   map.put(type, typeValue);
 }
 @Override
 public void constraintsForUnknown(
     TypeParameterDescriptor typeParameterDescriptor, BoundsOwner typeValue) {
   if (!ResolutionDebugInfo.isResolutionDebugEnabled()) return;
   Map<TypeParameterDescriptor, BoundsOwner> map =
       debugInfo.getByKey(BOUNDS_FOR_UNKNOWNS, candidateCall);
   if (map == null) {
     map = Maps.newLinkedHashMap();
     debugInfo.putByKey(BOUNDS_FOR_UNKNOWNS, candidateCall, map);
   }
   map.put(typeParameterDescriptor, typeValue);
 }
 @Override
 public void error(Object... messageFragments) {
   if (!ResolutionDebugInfo.isResolutionDebugEnabled()) return;
   StringBuilder stringBuilder = debugInfo.getByKey(ERRORS, candidateCall);
   if (stringBuilder == null) {
     stringBuilder = new StringBuilder();
     debugInfo.putByKey(ERRORS, candidateCall, stringBuilder);
   }
   for (Object m : messageFragments) {
     stringBuilder.append(m);
   }
   stringBuilder.append("\n");
 }