/**
   * Adds the given value to the embeddeds. Will skip doing so if the value is {@literal null} or
   * the content of a {@link Resource} is {@literal null}.
   *
   * @param source can be {@literal null}.
   */
  public void add(Object source) {

    EmbeddedWrapper wrapper = wrappers.wrap(source);

    if (wrapper == null) {
      return;
    }

    String collectionRel = getDefaultedRelFor(wrapper, true);
    String collectionOrItemRel = collectionRel;

    if (!embeddeds.containsKey(collectionRel)) {
      collectionOrItemRel = getDefaultedRelFor(wrapper, wrapper.isCollectionValue());
    }

    Object currentValue = embeddeds.get(collectionOrItemRel);
    Object value = wrapper.getValue();

    if (currentValue == null && !wrapper.isCollectionValue()) {
      embeddeds.put(collectionOrItemRel, value);
      return;
    }

    List<Object> list = new ArrayList<Object>();
    list.addAll(asCollection(currentValue));
    list.addAll(asCollection(wrapper.getValue()));

    embeddeds.remove(collectionOrItemRel);
    embeddeds.put(collectionRel, list);
  }
  private String getDefaultedRelFor(EmbeddedWrapper wrapper, boolean forCollection) {

    String valueRel = wrapper.getRel();

    if (StringUtils.hasText(valueRel)) {
      return valueRel;
    }

    if (provider == null) {
      return DEFAULT_REL;
    }

    Class<?> type = wrapper.getRelTargetType();

    if (type == null) {
      throw new IllegalStateException(String.format(INVALID_EMBEDDED_WRAPPER, wrapper));
    }

    String rel =
        forCollection
            ? provider.getCollectionResourceRelFor(type)
            : provider.getItemResourceRelFor(type);

    if (curieProvider != null) {
      rel = curieProvider.getNamespacedRelFor(rel);
    }

    return rel == null ? DEFAULT_REL : rel;
  }