class ServiceTalkThreadContextMap implements ReadOnlyThreadContextMap, CleanableThreadContextMap {

    @Nullable
    @Override
    public Map<String, String> getImmutableMapOrNull() {
        Map<String, String> storage = getStorage();
        if (storage.isEmpty()) {
            return null;
        }
        // We use a ConcurrentMap for the storage. So we make a best effort check to avoid a copy first, but it is
        // possible that the map was modified after this check. Then we make a copy and check if the copy is actually
        // empty before returning the unmodifiable map.
        final Map<String, String> copy = getCopyOrNull(storage, true);
        return copy == null ? null : unmodifiableMap(copy);
    }

}