@Override
 public ComputationTargetSpecification getTargetSpecification(
     final ComputationTargetReference reference) {
   final ComputationTargetSpecification resolved = _underlying.getTargetSpecification(reference);
   if (resolved != null) {
     storeResolution(reference, resolved);
   }
   return resolved;
 }
 @Override
 public Map<ComputationTargetReference, ComputationTargetSpecification> getTargetSpecifications(
     final Set<ComputationTargetReference> references) {
   final Map<ComputationTargetReference, ComputationTargetSpecification> resolveds =
       _underlying.getTargetSpecifications(references);
   for (final Map.Entry<ComputationTargetReference, ComputationTargetSpecification> resolved :
       resolveds.entrySet()) {
     storeResolution(resolved.getKey(), resolved.getValue());
   }
   return resolveds;
 }
 @Override
 public ComputedValue getComputedValue(final ValueRequirement requirement) {
   final Pair<String, Object> key =
       Pair.of(
           requirement.getValueName(),
           targetSpecKey(_resolver.getTargetSpecification(requirement.getTargetReference())));
   final ComputedValue[] values = _valuesByRequirement.get(key);
   if (values != null) {
     for (final ComputedValue value : values) {
       // Shortcut to check the properties as we already know the name and target match
       if (requirement.getConstraints().isSatisfiedBy(value.getSpecification().getProperties())) {
         return value;
       }
     }
   }
   return null;
 }
 private void targetRefKey(final ComputationTargetReference targetRef, final List<UniqueId> uids) {
   if (targetRef.getParent() != null) {
     targetRefKey(targetRef.getParent(), uids);
   }
   uids.add(_resolver.getTargetSpecification(targetRef).getUniqueId());
 }