private void updateDirectories(boolean updateFileCombo) {
    final Module module = getModule();
    List<VirtualFile> valuesDirs = Collections.emptyList();

    if (module != null) {
      final AndroidFacet facet = AndroidFacet.getInstance(module);

      if (facet != null) {
        myResourceDir = AndroidRootUtil.getResourceDir(facet);

        if (myResourceDir != null) {
          valuesDirs =
              AndroidResourceUtil.getResourceSubdirs(
                  ResourceFolderType.VALUES.getName(), new VirtualFile[] {myResourceDir});
        }
      }
    }

    Collections.sort(
        valuesDirs,
        new Comparator<VirtualFile>() {
          @Override
          public int compare(VirtualFile f1, VirtualFile f2) {
            return f1.getName().compareTo(f2.getName());
          }
        });

    final Map<String, JCheckBox> oldCheckBoxes = myCheckBoxes;
    final int selectedIndex = myDirectoriesList.getSelectedIndex();
    final String selectedDirName = selectedIndex >= 0 ? myDirNames[selectedIndex] : null;

    final List<JCheckBox> checkBoxList = new ArrayList<JCheckBox>();
    myCheckBoxes = new HashMap<String, JCheckBox>();
    myDirNames = new String[valuesDirs.size()];

    int newSelectedIndex = -1;

    int i = 0;

    for (VirtualFile dir : valuesDirs) {
      final String dirName = dir.getName();
      final JCheckBox oldCheckBox = oldCheckBoxes.get(dirName);
      final boolean selected = oldCheckBox != null && oldCheckBox.isSelected();
      final JCheckBox checkBox = new JCheckBox(dirName, selected);
      checkBoxList.add(checkBox);
      myCheckBoxes.put(dirName, checkBox);
      myDirNames[i] = dirName;

      if (dirName.equals(selectedDirName)) {
        newSelectedIndex = i;
      }
      i++;
    }
    myDirectoriesList.setModel(new CollectionListModel<JCheckBox>(checkBoxList));

    if (newSelectedIndex >= 0) {
      myDirectoriesList.setSelectedIndex(newSelectedIndex);
    }

    if (checkBoxList.size() == 1) {
      checkBoxList.get(0).setSelected(true);
    }

    if (updateFileCombo) {
      final Object oldItem = myFileNameCombo.getEditor().getItem();
      final Set<String> fileNameSet = new HashSet<String>();

      for (VirtualFile valuesDir : valuesDirs) {
        for (VirtualFile file : valuesDir.getChildren()) {
          fileNameSet.add(file.getName());
        }
      }
      final List<String> fileNames = new ArrayList<String>(fileNameSet);
      Collections.sort(fileNames);
      myFileNameCombo.setModel(new DefaultComboBoxModel(fileNames.toArray()));
      myFileNameCombo.getEditor().setItem(oldItem);
    }
  }
  @Override
  protected void postWriteAction() throws ConsumerException {

    // now write the values files.
    for (String key : mValuesResMap.keySet()) {
      // the key is the qualifier.

      // check if we have to write the file due to deleted values.
      // also remove it from that list anyway (to detect empty qualifiers later).
      boolean mustWriteFile = mQualifierWithDeletedValues.remove(key);

      // get the list of items to write
      List<ResourceItem> items = mValuesResMap.get(key);

      // now check if we really have to write it
      if (!mustWriteFile) {
        for (ResourceItem item : items) {
          if (item.isTouched()) {
            mustWriteFile = true;
            break;
          }
        }
      }

      if (mustWriteFile) {
        String folderName =
            key.isEmpty()
                ? ResourceFolderType.VALUES.getName()
                : ResourceFolderType.VALUES.getName() + RES_QUALIFIER_SEP + key;

        try {
          File valuesFolder = new File(getRootFolder(), folderName);
          createDir(valuesFolder);
          File outFile = new File(valuesFolder, FN_VALUES_XML);

          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
          factory.setNamespaceAware(true);
          factory.setValidating(false);
          factory.setIgnoringComments(true);
          DocumentBuilder builder;

          builder = factory.newDocumentBuilder();
          Document document = builder.newDocument();

          Node rootNode = document.createElement(TAG_RESOURCES);
          document.appendChild(rootNode);

          Collections.sort(items);

          ResourceFile currentFile = null;
          for (ResourceItem item : items) {
            ResourceFile source = item.getSource();
            if (source != currentFile) {
              currentFile = source;
              rootNode.appendChild(document.createTextNode("\n"));
              File file = source.getFile();
              rootNode.appendChild(document.createComment(createPathComment(file)));
              rootNode.appendChild(document.createTextNode("\n"));
            }
            Node adoptedNode = NodeUtils.adoptNode(document, item.getValue());
            rootNode.appendChild(adoptedNode);
          }

          String content;
          try {
            content = XmlPrettyPrinter.prettyPrint(document, true);
          } catch (Throwable t) {
            content = XmlUtils.toXml(document, false);
          }

          Files.write(content, outFile, Charsets.UTF_8);
        } catch (Throwable t) {
          throw new ConsumerException(t);
        }
      }
    }

    // now remove empty values files.
    for (String key : mQualifierWithDeletedValues) {
      String folderName =
          key != null && !key.isEmpty()
              ? ResourceFolderType.VALUES.getName() + RES_QUALIFIER_SEP + key
              : ResourceFolderType.VALUES.getName();

      removeOutFile(folderName, FN_VALUES_XML);
    }
  }
  @Nullable
  public static String doExtractStyle(
      @NotNull Module module,
      @NotNull final XmlTag viewTag,
      final boolean addStyleAttributeToTag,
      @Nullable MyTestConfig testConfig) {
    final PsiFile file = viewTag.getContainingFile();
    if (file == null) {
      return null;
    }
    final String dialogTitle = AndroidBundle.message("android.extract.style.title");
    final String fileName = AndroidResourceUtil.getDefaultResourceFileName(ResourceType.STYLE);
    assert fileName != null;
    final List<String> dirNames = Arrays.asList(ResourceFolderType.VALUES.getName());
    final List<XmlAttribute> extractableAttributes = getExtractableAttributes(viewTag);
    final Project project = module.getProject();

    if (extractableAttributes.size() == 0) {
      AndroidUtils.reportError(
          project, "The tag doesn't contain any attributes that can be extracted", dialogTitle);
      return null;
    }

    final LayoutViewElement viewElement = getLayoutViewElement(viewTag);
    assert viewElement != null;
    final ResourceValue parentStyleVlaue = viewElement.getStyle().getValue();
    final String parentStyle;
    boolean supportImplicitParent = false;

    if (parentStyleVlaue != null) {
      parentStyle = parentStyleVlaue.getResourceName();
      if (!ResourceType.STYLE.getName().equals(parentStyleVlaue.getResourceType())
          || parentStyle == null
          || parentStyle.length() == 0) {
        AndroidUtils.reportError(
            project, "Invalid parent style reference " + parentStyleVlaue.toString(), dialogTitle);
        return null;
      }
      supportImplicitParent = parentStyleVlaue.getPackage() == null;
    } else {
      parentStyle = null;
    }

    final String styleName;
    final List<XmlAttribute> styledAttributes;
    final Module chosenModule;

    if (testConfig == null) {
      final ExtractStyleDialog dialog =
          new ExtractStyleDialog(
              module,
              fileName,
              supportImplicitParent ? parentStyle : null,
              dirNames,
              extractableAttributes);
      dialog.setTitle(dialogTitle);
      dialog.show();

      if (!dialog.isOK()) {
        return null;
      }
      chosenModule = dialog.getChosenModule();
      assert chosenModule != null;

      styledAttributes = dialog.getStyledAttributes();
      styleName = dialog.getStyleName();
    } else {
      testConfig.validate(extractableAttributes);

      chosenModule = testConfig.getModule();
      styleName = testConfig.getStyleName();
      final Set<String> attrsToExtract =
          new HashSet<String>(Arrays.asList(testConfig.getAttributesToExtract()));
      styledAttributes = new ArrayList<XmlAttribute>();

      for (XmlAttribute attribute : extractableAttributes) {
        if (attrsToExtract.contains(attribute.getName())) {
          styledAttributes.add(attribute);
        }
      }
    }
    final boolean[] success = {false};
    final boolean finalSupportImplicitParent = supportImplicitParent;

    new WriteCommandAction(project, "Extract Android Style '" + styleName + "'", file) {
      @Override
      protected void run(final Result result) throws Throwable {
        final List<XmlAttribute> attributesToDelete = new ArrayList<XmlAttribute>();

        if (!AndroidResourceUtil.createValueResource(
            chosenModule,
            styleName,
            ResourceType.STYLE,
            fileName,
            dirNames,
            new Processor<ResourceElement>() {
              @Override
              public boolean process(ResourceElement element) {
                assert element instanceof Style;
                final Style style = (Style) element;

                for (XmlAttribute attribute : styledAttributes) {
                  if (SdkConstants.NS_RESOURCES.equals(attribute.getNamespace())) {
                    final StyleItem item = style.addItem();
                    item.getName().setStringValue("android:" + attribute.getLocalName());
                    item.setStringValue(attribute.getValue());
                    attributesToDelete.add(attribute);
                  }
                }

                if (parentStyleVlaue != null
                    && (!finalSupportImplicitParent || !styleName.startsWith(parentStyle + "."))) {
                  final String aPackage = parentStyleVlaue.getPackage();
                  style
                      .getParentStyle()
                      .setStringValue((aPackage != null ? aPackage + ":" : "") + parentStyle);
                }
                return true;
              }
            })) {
          return;
        }

        ApplicationManager.getApplication()
            .runWriteAction(
                new Runnable() {
                  @Override
                  public void run() {
                    for (XmlAttribute attribute : attributesToDelete) {
                      attribute.delete();
                    }
                    if (addStyleAttributeToTag) {
                      final LayoutViewElement viewElement = getLayoutViewElement(viewTag);
                      assert viewElement != null;
                      viewElement.getStyle().setStringValue("@style/" + styleName);
                    }
                  }
                });
        success[0] = true;
      }

      @Override
      protected UndoConfirmationPolicy getUndoConfirmationPolicy() {
        return UndoConfirmationPolicy.REQUEST_CONFIRMATION;
      }
    }.execute();

    return success[0] ? styleName : null;
  }