docs: public static Object getValueOrCachedValue(Record record, SerializationService serializationService) {
          Object cachedValue = record.getCachedValueUnsafe();
          if (cachedValue == NOT_CACHED) {
              //record does not support caching at all
              return record.getValue();
          }
          for (; ; ) {
              if (cachedValue == null) {
                  Object valueBeforeCas = record.getValue();
                  if (!shouldCache(valueBeforeCas)) {
                      //it's either a null or value which we do not want to cache. let's just return it.
                      return valueBeforeCas;
                  }
                  Object fromCache = tryStoreIntoCache(record, valueBeforeCas, serializationService);
                  if (fromCache != null) {
                      return fromCache;
                  }
              } else if (cachedValue instanceof Thread) {
                  //the cachedValue is either locked by another thread or it contains a wrapped thread
                  cachedValue = ThreadWrapper.unwrapOrNull(cachedValue);
                  if (cachedValue != null) {
                      //exceptional case: the cachedValue is not locked, it just contains an instance of Thread.
                      //this can happen when user put an instance of Thread into a map
                      //(=it should never happen, but never say never...)
                      return cachedValue;
                  }
                  //it looks like some other thread actually locked the cachedValue. let's give it another try (iteration)
              } else {
                  //it's not the 'in-progress' marker/lock && it's not a null -> it has to be the actual cachedValue
                  return cachedValue;
              }
              Thread.yield();
              cachedValue = record.getCachedValueUnsafe();
          }
      }