@Nullable
  public PropertiesFile findPropertiesFile(
      final Module module, final String bundleName, final Locale locale) {
    List<PropertiesFile> propFiles = findPropertiesFiles(module, bundleName);
    if (locale != null) {
      for (PropertiesFile propFile : propFiles) {
        if (propFile.getLocale().equals(locale)) {
          return propFile;
        }
      }
    }

    // fallback to default locale
    for (PropertiesFile propFile : propFiles) {
      if (propFile.getLocale().getLanguage().length() == 0
          || propFile.getLocale().equals(Locale.getDefault())) {
        return propFile;
      }
    }

    // fallback to any file
    if (!propFiles.isEmpty()) {
      return propFiles.get(0);
    }

    return null;
  }
  public void testPropertiesFilesDefaultCombiningToResourceBundle() {
    final PsiFile file = myFixture.addFileToProject("prop_core_en.properties", "");
    final PsiFile file2 = myFixture.addFileToProject("prop_core_fi.properties", "");
    final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file);
    final PropertiesFile propertiesFile2 = PropertiesImplUtil.getPropertiesFile(file2);
    assertNotNull(propertiesFile);
    assertNotNull(propertiesFile2);
    final ResourceBundle bundle = propertiesFile.getResourceBundle();
    final ResourceBundle bundle2 = propertiesFile2.getResourceBundle();
    assertTrue(bundle.equals(bundle2));
    assertSize(2, bundle.getPropertiesFiles());
    assertTrue(bundle.getDefaultPropertiesFile().equals(bundle2.getDefaultPropertiesFile()));
    assertEquals("prop_core", bundle.getBaseName());

    assertNotSame(
        propertiesFile.getLocale().getLanguage(), propertiesFile.getLocale().getDisplayLanguage());
    assertNotSame(
        propertiesFile2.getLocale().getLanguage(),
        propertiesFile2.getLocale().getDisplayLanguage());
  }
  public void testPropertiesFileNotAssociatedWhileLanguageCodeNotRecognized() {
    final PsiFile file = myFixture.addFileToProject("some_property_file.properties", "");
    final PsiFile file2 = myFixture.addFileToProject("some_property_fil.properties", "");
    final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file);
    assertNotNull(propertiesFile);
    final ResourceBundle resourceBundle = propertiesFile.getResourceBundle();
    assertSize(1, resourceBundle.getPropertiesFiles());

    final PropertiesFile propertiesFile2 = PropertiesImplUtil.getPropertiesFile(file2);
    assertNotNull(propertiesFile2);
    final ResourceBundle resourceBundle2 = propertiesFile.getResourceBundle();
    assertSize(1, resourceBundle2.getPropertiesFiles());

    assertEquals(PropertiesUtil.DEFAULT_LOCALE, propertiesFile.getLocale());
  }
  public void testLanguageCodeNotRecognized() {
    final PsiFile file = myFixture.addFileToProject("p.properties", "");
    final PsiFile file2 = myFixture.addFileToProject("p_asd.properties", "");

    final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file);
    final PropertiesFile propertiesFile2 = PropertiesImplUtil.getPropertiesFile(file2);
    assertNotNull(propertiesFile);
    assertNotNull(propertiesFile2);
    final ResourceBundle bundle = propertiesFile.getResourceBundle();
    final ResourceBundle bundle2 = propertiesFile2.getResourceBundle();
    assertSize(1, bundle.getPropertiesFiles());
    assertSize(1, bundle2.getPropertiesFiles());
    assertEquals("p", bundle.getBaseName());
    assertEquals("p_asd", bundle2.getBaseName());

    final ResourceBundleManager manager = ResourceBundleManager.getInstance(getProject());
    final ArrayList<PropertiesFile> rawBundle =
        ContainerUtil.newArrayList(propertiesFile, propertiesFile2);
    final String suggestedBaseName = PropertiesUtil.getDefaultBaseName(rawBundle);
    assertEquals("p", suggestedBaseName);
    manager.combineToResourceBundle(rawBundle, suggestedBaseName);

    assertEquals("asd", propertiesFile2.getLocale().getLanguage());
  }
  private void recreateEditorsPanel() {
    myValuesPanel.removeAll();
    myValuesPanel.setLayout(new CardLayout());

    if (!myProject.isOpen()) return;
    JPanel valuesPanelComponent = new MyJPanel(new GridBagLayout());
    myValuesPanel.add(
        new JBScrollPane(valuesPanelComponent) {
          @Override
          public void updateUI() {
            super.updateUI();
            getViewport().setBackground(UIUtil.getPanelBackground());
          }
        },
        VALUES);
    myValuesPanel.add(myNoPropertySelectedPanel, NO_PROPERTY_SELECTED);

    List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles();

    GridBagConstraints gc =
        new GridBagConstraints(
            0,
            0,
            0,
            0,
            0,
            0,
            GridBagConstraints.NORTHWEST,
            GridBagConstraints.BOTH,
            new Insets(5, 5, 5, 5),
            0,
            0);
    releaseAllEditors();
    myTitledPanels.clear();
    int y = 0;
    Editor previousEditor = null;
    Editor firstEditor = null;
    for (final PropertiesFile propertiesFile : propertiesFiles) {
      final Editor editor = createEditor();
      final Editor oldEditor = myEditors.put(propertiesFile, editor);
      if (firstEditor == null) {
        firstEditor = editor;
      }
      if (previousEditor != null) {
        editor.putUserData(
            ChooseSubsequentPropertyValueEditorAction.PREV_EDITOR_KEY, previousEditor);
        previousEditor.putUserData(
            ChooseSubsequentPropertyValueEditorAction.NEXT_EDITOR_KEY, editor);
      }
      previousEditor = editor;
      if (oldEditor != null) {
        EditorFactory.getInstance().releaseEditor(oldEditor);
      }
      ((EditorEx) editor)
          .addFocusListener(
              new FocusChangeListener() {
                @Override
                public void focusGained(final Editor editor) {
                  mySelectedEditor = editor;
                }

                @Override
                public void focusLost(final Editor eventEditor) {
                  writeEditorPropertyValue(editor, propertiesFile, null);
                }
              });
      gc.gridx = 0;
      gc.gridy = y++;
      gc.gridheight = 1;
      gc.gridwidth = GridBagConstraints.REMAINDER;
      gc.weightx = 1;
      gc.weighty = 1;
      gc.anchor = GridBagConstraints.CENTER;

      Locale locale = propertiesFile.getLocale();
      List<String> names = new ArrayList<String>();
      if (!Comparing.strEqual(locale.getDisplayLanguage(), null)) {
        names.add(locale.getDisplayLanguage());
      }
      if (!Comparing.strEqual(locale.getDisplayCountry(), null)) {
        names.add(locale.getDisplayCountry());
      }
      if (!Comparing.strEqual(locale.getDisplayVariant(), null)) {
        names.add(locale.getDisplayVariant());
      }

      String title = propertiesFile.getName();
      if (!names.isEmpty()) {
        title += " (" + StringUtil.join(names, "/") + ")";
      }
      JComponent comp =
          new JPanel(new BorderLayout()) {
            @Override
            public Dimension getPreferredSize() {
              Insets insets = getBorder().getBorderInsets(this);
              return new Dimension(100, editor.getLineHeight() * 4 + insets.top + insets.bottom);
            }
          };
      comp.add(editor.getComponent(), BorderLayout.CENTER);
      comp.setBorder(IdeBorderFactory.createTitledBorder(title, true));
      myTitledPanels.put(propertiesFile, (JPanel) comp);

      valuesPanelComponent.add(comp, gc);
    }
    if (previousEditor != null) {
      previousEditor.putUserData(
          ChooseSubsequentPropertyValueEditorAction.NEXT_EDITOR_KEY, firstEditor);
      firstEditor.putUserData(
          ChooseSubsequentPropertyValueEditorAction.PREV_EDITOR_KEY, previousEditor);
    }

    gc.gridx = 0;
    gc.gridy = y;
    gc.gridheight = GridBagConstraints.REMAINDER;
    gc.gridwidth = GridBagConstraints.REMAINDER;
    gc.weightx = 10;
    gc.weighty = 1;

    valuesPanelComponent.add(new JPanel(), gc);
    selectionChanged();
    myValuesPanel.repaint();
    UIUtil.invokeAndWaitIfNeeded(
        new Runnable() {
          @Override
          public void run() {
            updateEditorsFromProperties();
          }
        });
  }