private <T> CachedValue<T> saveInUserData(@NotNull UserDataHolder dataHolder, @NotNull Key<CachedValue<T>> key, CachedValue<T> value) {
    trackKeyHolder(dataHolder, key);

    if (dataHolder instanceof UserDataHolderEx) {
      return ((UserDataHolderEx)dataHolder).putUserDataIfAbsent(key, value);
    }

    //noinspection SynchronizationOnLocalVariableOrMethodParameter
    synchronized (dataHolder) {
      CachedValue<T> existing = dataHolder.getUserData(key);
      if (existing != null) {
        return existing;
      }
      dataHolder.putUserData(key, value);
      return value;
    }
  }
private <T> CachedValue<T> saveInUserData(@NotNull UserDataHolder dataHolder, @NotNull Key<CachedValue<T>> key, CachedValue<T> value)