private void addCondition(@NotNull ArrangementUiComponent component) {
    mySkipStateChange = true;
    try {
      component.setSelected(true);
      Collection<Set<ArrangementSettingsToken>> mutexes = mySettingsManager.getMutexes();

      // Update 'mutex conditions', i.e. conditions which can't be active at the same time (e.g.
      // type 'field' and type 'method').
      for (Set<ArrangementSettingsToken> mutex : mutexes) {
        if (!mutex.contains(component.getToken())) {
          continue;
        }
        for (ArrangementSettingsToken key : mutex) {
          if (key.equals(component.getToken())) {
            continue;
          }
          ArrangementUiComponent c = myComponents.get(key);
          if (c != null && c.isEnabled()) {
            removeCondition(c);
          }
        }
      }
      refreshConditions();
    } finally {
      mySkipStateChange = false;
    }
  }
  /**
   * Asks current editor to refresh its state in accordance with the arrangement rule shown at the
   * given row.
   *
   * @param row row index of the rule which match condition should be edited (if defined); <code>
   *     '-1'</code> as an indication that no settings should be active
   */
  public void reset(int row) {
    // Reset state.
    myRow = row;
    myFocusRequestor = myDefaultFocusRequestor;
    mySkipStateChange = true;
    try {
      for (ArrangementUiComponent component : myComponents.values()) {
        component.reset();
      }
    } finally {
      mySkipStateChange = false;
    }

    ArrangementMatchingRulesModel model = myControl.getModel();
    if (row < 0 || row >= model.getSize()) {
      myRow = -1;
      return;
    }

    Object element = model.getElementAt(row);
    ArrangementSettingsToken orderType =
        element instanceof ArrangementMatchRule
            ? ((ArrangementMatchRule) element).getOrderType()
            : null;
    final ArrangementMatchCondition condition;
    final Map<ArrangementSettingsToken, Object> conditionTokens;

    if (element instanceof EmptyArrangementRuleComponent) {
      // We need to disable conditions which are not applicable for empty rules (e.g. we don't want
      // to enable 'volatile' condition
      // for java rearranger if no 'field' condition is selected.
      condition = null;
      conditionTokens = ContainerUtilRt.newHashMap();
    } else if (!(element instanceof StdArrangementMatchRule)) {
      return;
    } else {
      condition = ((StdArrangementMatchRule) element).getMatcher().getCondition();
      conditionTokens = ArrangementUtil.extractTokens(condition);
    }

    mySkipStateChange = true;
    try {
      for (ArrangementUiComponent component : myComponents.values()) {
        ArrangementSettingsToken token = component.getToken();
        if (token != null
            && (token.equals(orderType) || mySettingsManager.isEnabled(token, condition))) {
          component.setEnabled(true);
          component.setSelected(conditionTokens.containsKey(token));
          Object value = conditionTokens.get(token);
          if (value != null) {
            component.setData(value);
          }
        }
      }

      refreshConditions();
    } finally {
      mySkipStateChange = false;
    }
  }
  private void init(@NotNull ArrangementStandardSettingsManager settingsManager) {
    setLayout(new GridBagLayout());
    setBorder(IdeBorderFactory.createEmptyBorder(5));

    List<CompositeArrangementSettingsToken> tokens = settingsManager.getSupportedMatchingTokens();
    if (tokens != null) {
      for (CompositeArrangementSettingsToken token : tokens) {
        addToken(token);
      }
    }

    applyBackground(UIUtil.getListBackground());
  }
 /**
  * Disable conditions not applicable at the current context (e.g. disable 'synchronized' if no
  * 'method' is selected).
  */
 private void refreshConditions() {
   Pair<ArrangementMatchCondition, ArrangementSettingsToken> pair = buildCondition();
   ArrangementMatchCondition condition = pair == null ? null : pair.first;
   for (ArrangementUiComponent component : myComponents.values()) {
     ArrangementSettingsToken token = component.getToken();
     if (token == null) {
       continue;
     }
     boolean enabled = mySettingsManager.isEnabled(token, condition);
     component.setEnabled(enabled);
     if (!enabled) {
       component.setSelected(false);
     }
   }
 }
  public ArrangementSettingsPanel(@NotNull CodeStyleSettings settings, @NotNull Language language) {
    super(settings);
    myLanguage = language;
    Rearranger<?> rearranger = Rearranger.EXTENSION.forLanguage(language);

    assert rearranger instanceof ArrangementStandardSettingsAware;
    mySettingsAware = (ArrangementStandardSettingsAware) rearranger;

    final ArrangementColorsProvider colorsProvider;
    if (rearranger instanceof ArrangementColorsAware) {
      colorsProvider = new ArrangementColorsProviderImpl((ArrangementColorsAware) rearranger);
    } else {
      colorsProvider = new ArrangementColorsProviderImpl(null);
    }

    ArrangementStandardSettingsManager settingsManager =
        new ArrangementStandardSettingsManager(mySettingsAware, colorsProvider);

    myGroupingRulesPanel = new ArrangementGroupingRulesPanel(settingsManager, colorsProvider);
    myMatchingRulesPanel =
        new ArrangementMatchingRulesPanel(myLanguage, settingsManager, colorsProvider);

    myContent.add(
        myGroupingRulesPanel, new GridBag().coverLine().fillCellHorizontally().weightx(1));
    myContent.add(myMatchingRulesPanel, new GridBag().fillCell().weightx(1).weighty(1).coverLine());

    if (settings.getCommonSettings(myLanguage).isForceArrangeMenuAvailable()) {
      myForceArrangementPanel = new ForceArrangementPanel();
      myForceArrangementPanel.setSelectedMode(
          settings.getCommonSettings(language).FORCE_REARRANGE_MODE);
      myContent.add(
          myForceArrangementPanel.getPanel(),
          new GridBag().anchor(GridBagConstraints.WEST).coverLine().fillCellHorizontally());
    } else {
      myForceArrangementPanel = null;
    }

    final List<CompositeArrangementSettingsToken> groupingTokens =
        settingsManager.getSupportedGroupingTokens();
    myGroupingRulesPanel.setVisible(groupingTokens != null && !groupingTokens.isEmpty());

    registerShortcut(
        ArrangementConstants.MATCHING_RULE_ADD, CommonShortcuts.getNew(), myMatchingRulesPanel);
    registerShortcut(
        ArrangementConstants.MATCHING_RULE_REMOVE,
        CommonShortcuts.getDelete(),
        myMatchingRulesPanel);
    registerShortcut(
        ArrangementConstants.MATCHING_RULE_MOVE_UP, CommonShortcuts.MOVE_UP, myMatchingRulesPanel);
    registerShortcut(
        ArrangementConstants.MATCHING_RULE_MOVE_DOWN,
        CommonShortcuts.MOVE_DOWN,
        myMatchingRulesPanel);
    final CustomShortcutSet edit = new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0));
    registerShortcut(ArrangementConstants.MATCHING_RULE_EDIT, edit, myMatchingRulesPanel);

    registerShortcut(
        ArrangementConstants.GROUPING_RULE_MOVE_UP, CommonShortcuts.MOVE_UP, myGroupingRulesPanel);
    registerShortcut(
        ArrangementConstants.GROUPING_RULE_MOVE_DOWN,
        CommonShortcuts.MOVE_DOWN,
        myGroupingRulesPanel);
  }