private Collection<EditorSchemeAttributeDescriptor> getOrderedDescriptors(
     @NotNull ColorAndFontOptions options) {
   ArrayList<EditorSchemeAttributeDescriptor> list = ContainerUtil.newArrayList();
   for (EditorSchemeAttributeDescriptor description : options.getCurrentDescriptions()) {
     if (!description.getGroup().equals(myCategoryName)) continue;
     list.add(description);
   }
   Collections.sort(list, ATTR_COMPARATOR);
   return list;
 }
    public void apply(@NotNull EditorColorsScheme scheme) {
      scheme.setFontPreferences(getFontPreferences());
      scheme.setLineSpacing(myLineSpacing);
      scheme.setQuickDocFontSize(getQuickDocFontSize());
      scheme.setConsoleFontPreferences(getConsoleFontPreferences());
      scheme.setConsoleLineSpacing(getConsoleLineSpacing());

      for (EditorSchemeAttributeDescriptor descriptor : myDescriptors) {
        descriptor.apply(scheme);
      }
    }
    public boolean isModified() {
      if (isFontModified() || isConsoleFontModified()) return true;

      for (EditorSchemeAttributeDescriptor descriptor : myDescriptors) {
        if (descriptor.isModified()) {
          return true;
        }
      }

      return false;
    }
 public void fillOptions(@NotNull ColorAndFontOptions options) {
   DefaultMutableTreeNode root = new DefaultMutableTreeNode();
   for (EditorSchemeAttributeDescriptor description : getOrderedDescriptors(options)) {
     if (!description.getGroup().equals(myCategoryName)) continue;
     List<String> path = extractPath(description);
     if (path != null && path.size() > 1) {
       MyTreeNode groupNode = ensureGroup(root, path, 0);
       groupNode.add(new MyTreeNode(description, path.get(path.size() - 1)));
     } else {
       root.add(new MyTreeNode(description));
     }
   }
   myTreeModel.setRoot(root);
 }
    @Override
    public boolean isModified() {
      createPanel();
      for (MyColorScheme scheme : mySchemes.values()) {
        if (mySubPanel.containsFontOptions()) {
          if (scheme.isFontModified() || scheme.isConsoleFontModified()) {
            myRevertChangesCompleted = false;
            return true;
          }
        } else {
          for (EditorSchemeAttributeDescriptor descriptor : scheme.getDescriptors()) {
            if (mySubPanel.contains(descriptor) && descriptor.isModified()) {
              myRevertChangesCompleted = false;
              return true;
            }
          }
        }
      }

      return false;
    }
 @Nullable
 private static List<String> extractPath(@NotNull EditorSchemeAttributeDescriptor descriptor) {
   if (descriptor instanceof ColorAndFontDescription) {
     String name = descriptor.toString();
     List<String> path = new ArrayList<String>();
     int separatorStart = name.indexOf(NAME_SEPARATOR);
     int nextChunkStart = 0;
     while (separatorStart > 0) {
       path.add(name.substring(nextChunkStart, separatorStart));
       nextChunkStart = separatorStart + NAME_SEPARATOR.length();
       separatorStart = name.indexOf(NAME_SEPARATOR, nextChunkStart);
     }
     if (nextChunkStart < name.length()) {
       path.add(name.substring(nextChunkStart));
     }
     return path;
   }
   return null;
 }
 @Override
 public int compare(EditorSchemeAttributeDescriptor o1, EditorSchemeAttributeDescriptor o2) {
   return StringUtil.naturalCompare(o1.toString(), o2.toString());
 }
 public MyTreeNode(@NotNull EditorSchemeAttributeDescriptor descriptor) {
   super(descriptor);
   myName = descriptor.toString();
 }