private void writeAttributes(Element attrElements) throws WriteExternalException {
    List<TextAttributesKey> list = new ArrayList<TextAttributesKey>(myAttributesMap.keySet());
    Collections.sort(list);

    for (TextAttributesKey key : list) {
      TextAttributes defaultAttr =
          myParentScheme != null ? myParentScheme.getAttributes(key) : new TextAttributes();
      TextAttributesKey baseKey = key.getFallbackAttributeKey();
      TextAttributes defaultFallbackAttr =
          baseKey != null && myParentScheme instanceof AbstractColorsScheme
              ? ((AbstractColorsScheme) myParentScheme).getFallbackAttributes(baseKey)
              : null;
      TextAttributes value = myAttributesMap.get(key);
      if (!value.equals(defaultAttr) || defaultAttr == defaultFallbackAttr) {
        Element element = new Element(OPTION_ELEMENT);
        element.setAttribute(NAME_ATTR, key.getExternalName());
        if (baseKey == null || !value.isFallbackEnabled()) {
          Element valueElement = new Element(VALUE_ELEMENT);
          value.writeExternal(valueElement);
          element.addContent(valueElement);
          attrElements.addContent(element);
        } else if (defaultAttr != defaultFallbackAttr) {
          element.setAttribute(BASE_ATTRIBUTES_ATTR, baseKey.getExternalName());
          attrElements.addContent(element);
        }
      }
    }
  }
 protected TextAttributes getFallbackAttributes(TextAttributesKey fallbackKey) {
   if (fallbackKey == null) return null;
   TextAttributes fallbackAttributes = getDirectlyDefinedAttributes(fallbackKey);
   if (fallbackAttributes != null) {
     if (!fallbackAttributes.isFallbackEnabled()
         || fallbackKey.getFallbackAttributeKey() == null) {
       return fallbackAttributes;
     }
   }
   return getFallbackAttributes(fallbackKey.getFallbackAttributeKey());
 }
  private void migrateErrorStripeColorFrom14(
      @NotNull TextAttributesKey name, @NotNull TextAttributes attr) {
    if (myVersion >= 141 || myParentScheme == null) return;

    Couple<Color> m = DEFAULT_STRIPE_COLORS.get(name.getExternalName());
    if (m != null && Comparing.equal(m.first, attr.getErrorStripeColor())) {
      attr.setErrorStripeColor(m.second);
    }
  }
 public void readAttributes(@NotNull Element childNode) {
   for (Element e : childNode.getChildren(OPTION_ELEMENT)) {
     TextAttributesKey name = TextAttributesKey.find(e.getAttributeValue(NAME_ATTR));
     Element valueElement = e.getChild(VALUE_ELEMENT);
     TextAttributes attr =
         valueElement != null ? new TextAttributes(valueElement) : new TextAttributes();
     myAttributesMap.put(name, attr);
     migrateErrorStripeColorFrom14(name, attr);
   }
 }