private static @NotNull <K,V> Map<K, V> createWeakMap() {
    //noinspection deprecation
    return new ConcurrentWeakKeySoftValueHashMap<K, V>(100, 0.75f, Runtime.getRuntime().availableProcessors()) {
      @Override
      protected @NotNull ValueReference<K, V> createValueReference(@NotNull V value, @NotNull ReferenceQueue<? super V> queue) {
        ValueReference<K, V> result;
        if (value == NULL_RESULT || value instanceof Object[] && ((Object[])value).length == 0) {
          // no use in creating SoftReference to null
          result = createStrongReference(value);
        }
        else {
          result = super.createValueReference(value, queue);
        }
        return result;
      }

      @Override
      public V get(@NotNull Object key) {
        V v = super.get(key);
        return v == NULL_RESULT ? null : v;
      }

      @Override
      public V put(K key, V value) {
        // no use in creating SoftReference to null
        //noinspection unchecked
        V toStore = value == null ? (V)NULL_RESULT : value;
        return super.put(key, toStore);
      }

      @Override
      public boolean equals(Object obj) {
        // The map instance is used as the recursion prevention key.
        // Each instance is determined by several flags: physical, incomplete, poly;
        // Each instance is unique, so we don't need to store flags to check equality.
        return this == obj;
      }

      @Override
      public int hashCode() {
        return System.identityHashCode(this);
      }
    };
  }
private static @NotNull <K,V> Map<K, V> createWeakMap()