public <T, P> T getParameterizedCachedValue(@NotNull UserDataHolder dataHolder,
                                              @NotNull Key<ParameterizedCachedValue<T, P>> key,
                                              @NotNull ParameterizedCachedValueProvider<T, P> provider,
                                              boolean trackValue,
                                              P parameter) {
    ParameterizedCachedValue<T, P> value;

    if (dataHolder instanceof UserDataHolderEx) {
      UserDataHolderEx dh = (UserDataHolderEx)dataHolder;
      value = dh.getUserData(key);
      if (value == null) {
        trackKeyHolder(dataHolder, key);
        value = createParameterizedCachedValue(dataHolder, provider, trackValue);
        value = dh.putUserDataIfAbsent(key, value);
      }
    }
    else {
      //noinspection SynchronizationOnLocalVariableOrMethodParameter
      synchronized (dataHolder) {
        value = dataHolder.getUserData(key);
        if (value == null) {
          trackKeyHolder(dataHolder, key);
          value = createParameterizedCachedValue(dataHolder, provider, trackValue);
          dataHolder.putUserData(key, value);
        }
      }
    }
    return value.getValue(parameter);
  }
public <T, P> T getParameterizedCachedValue(@NotNull UserDataHolder dataHolder,
                                              @NotNull Key<ParameterizedCachedValue<T, P>> key,
                                              @NotNull ParameterizedCachedValueProvider<T, P> provider,
                                              boolean trackValue,
                                              P parameter)