public static @NotNull ColorKey createColorKeyWithFallback(@NonNls @NotNull String externalName, @Nullable ColorKey fallbackColorKey) {
    ColorKey existing = ourRegistry.get(externalName);
    if (existing != null) {
      if (Comparing.equal(existing.getFallbackColorKey(), fallbackColorKey)) return existing;
      // some crazy life cycle assumes we can overwrite color
      ourRegistry.remove(externalName, existing);
    }
    ColorKey newKey = new ColorKey(externalName, existing == null ? null : existing.getDefaultColor(), fallbackColorKey);
    ColorKey res = ConcurrencyUtil.cacheOrGet(ourRegistry, externalName, newKey);

    if (fallbackColorKey != null) {
      JBIterable<ColorKey> it = JBIterable.generate(fallbackColorKey, o -> o == res ? null : o.myFallbackColorKey);
      if (it.find(o -> o == res) == res) {
        String cycle = StringUtil.join(it.map(ColorKey::getExternalName), "->");
        LOG.error("Cycle detected: " + cycle);
      }
    }

    return res;
  }
public static @NotNull ColorKey createColorKeyWithFallback(@NonNls @NotNull String externalName, @Nullable ColorKey fallbackColorKey)