code: public VALUETYPE getFromCache (final KEYTYPE aKey)
    {
      VALUETYPE aValue = getFromCacheNoStats (aKey);
      if (aValue == null)
      {
        // No old value in the cache
        m_aRWLock.writeLock ().lock ();
        try
        {
          // Read again, in case the value was set between the two locking
          // sections
          // Note: do not increase statistics in this second try
          aValue = getFromCacheNoStatsNotLocked (aKey);
          if (aValue == null)
          {
            // Call the abstract method to create the value to cache
            aValue = m_aCacheValueProvider.apply (aKey);
  
            // Just a consistency check
            if (aValue == null)
              throw new IllegalStateException ("The value to cache was null for key '" + aKey + "'");
  
            // Put the new value into the cache
            putInCacheNotLocked (aKey, aValue);
            m_aCacheAccessStats.cacheMiss ();
          }
          else
            m_aCacheAccessStats.cacheHit ();
        }
        finally
        {
          m_aRWLock.writeLock ().unlock ();
        }
      }
      else
        m_aCacheAccessStats.cacheHit ();
      return aValue;
    }
docs: Here Nonnull but derived class may be Nullable