// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.util;

import com.intellij.reference.SoftReference;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ConcurrentIntObjectMap;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.IntObjectMap;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;

public interface Iconable {
  int ICON_FLAG_VISIBILITY = 0x0001;
  int ICON_FLAG_READ_STATUS = 0x0002;

  /**
   * @deprecated unused, left for API compatibility
   */
  @Deprecated
  int ICON_FLAG_OPEN = 0x0004;

  Key<Integer> ICON_FLAG_IGNORE_MASK = new Key<>("ICON_FLAG_IGNORE_MASK");

  @MagicConstant(flags = {ICON_FLAG_VISIBILITY, ICON_FLAG_READ_STATUS})
  @interface IconFlags {}

  Icon getIcon(@IconFlags int flags);

  final class LastComputedIcon {
    private static final Key<SoftReference<IntObjectMap<Icon>>> LAST_COMPUTED_ICON = Key.create("lastComputedIcon");

    @Nullable
    public static Icon get(@NotNull UserDataHolder holder, int flags) {
      IntObjectMap<Icon> map = SoftReference.dereference(holder.getUserData(LAST_COMPUTED_ICON));
      return map == null ? null : map.get(flags);
    }

    public static void put(@NotNull UserDataHolder holder, Icon icon, int flags) {
      IntObjectMap<Icon> map = SoftReference.dereference(holder.getUserData(LAST_COMPUTED_ICON));
      if (icon == null) {
        if (map != null) {
          map.remove(flags);
        }
      }
      else {
        ConcurrentIntObjectMap<Icon> freshMap = ContainerUtil.createConcurrentIntObjectMap();
        while (map == null) {
          map = SoftReference.dereference(((UserDataHolderEx)holder).putUserDataIfAbsent(LAST_COMPUTED_ICON, new SoftReference<>(freshMap)));
        }
        ObjectUtils.reachabilityFence(freshMap);
        map.put(flags, icon);
      }
    }
  }
}

@@ -174,151 +174,8 @@
 l;%0A%0A
-import com.intellij.reference.SoftReference;%0Aimport com.intellij.util.ObjectUtils;%0Aimport com.intellij.util.containers.ConcurrentIntObjectMap;%0A
 impo
@@ -922,30 +922,16 @@
 nal Key%3C
-SoftReference%3C
 IntObjec
@@ -941,17 +941,16 @@
 p%3CIcon%3E%3E
-%3E
  LAST_CO
@@ -1117,34 +1117,8 @@
 p = 
-SoftReference.dereference(
 hold
@@ -1143,33 +1143,32 @@
 T_COMPUTED_ICON)
-)
 ;%0A      return m
@@ -1328,34 +1328,8 @@
 p = 
-SoftReference.dereference(
 hold
@@ -1362,17 +1362,16 @@
 ED_ICON)
-)
 ;%0A      
@@ -1489,107 +1489,10 @@
     
-ConcurrentIntObjectMap%3CIcon%3E freshMap = ContainerUtil.createConcurrentIntObjectMap();%0A        while
+if
  (ma
@@ -1524,34 +1524,8 @@
 p = 
-SoftReference.dereference(
 ((Us
@@ -1591,37 +1591,51 @@
 ON, 
-new SoftReference%3C%3E(freshMap)
+ContainerUtil.createConcurrentIntObjectMap(
 ));%0A
@@ -1648,57 +1648,8 @@
   %7D%0A
-        ObjectUtils.reachabilityFence(freshMap);%0A
     

Revert "hold LastComputedIcon on soft references"