code: public Integer cache(Object value) {
          synchronized (this) {
              Integer key = keys.get(value);
              // Already cached?
              if (key != null) return key;
              key = next;
              cache.put(key, value);
              keys.put(value, key);
              next++;
              return key;
          }
      }
docs: Caches an object, returning its key.
  <p>
  If the object has already been cached, its existing key is returned.
  </p>
  
  @param value {@link Object} to cache
  @return Non-null {@link Integer}