ColorKey (@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; }