public void testResourceBundleManagerUpdatesProperlyWhileDirRemoval() {
    myFixture.addFileToProject("qwe/asd/p.properties", "");
    final PsiFile file = myFixture.addFileToProject("qwe/asd/p_en.properties", "");
    final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file);
    assertNotNull(propertiesFile);
    final ResourceBundleManager resourceBundleManager =
        ResourceBundleManager.getInstance(getProject());
    resourceBundleManager.dissociateResourceBundle(propertiesFile.getResourceBundle());

    final PropertiesFile propFile1 =
        PropertiesImplUtil.getPropertiesFile(
            myFixture.addFileToProject("qwe1/asd1/p.properties", ""));
    final PropertiesFile propFile2 =
        PropertiesImplUtil.getPropertiesFile(
            myFixture.addFileToProject("qwe1/asd1/p_abc.properties", ""));
    assertNotNull(propFile1);
    assertNotNull(propFile2);
    resourceBundleManager.combineToResourceBundle(
        ContainerUtil.newArrayList(propFile1, propFile2), "p");

    final PsiFile someFile = myFixture.addFileToProject("to_remove/asd.txt", "");
    final PsiDirectory toRemove = someFile.getParent();
    assertNotNull(toRemove);
    ApplicationManager.getApplication().runWriteAction(toRemove::delete);

    final ResourceBundleManagerState state = resourceBundleManager.getState();
    assertNotNull(state);
    assertSize(1, state.getCustomResourceBundles());
    assertSize(2, state.getDissociatedFiles());

    final PsiDirectory directory = propertiesFile.getParent().getParent();
    assertNotNull(directory);
    ApplicationManager.getApplication().runWriteAction(directory::delete);

    assertSize(1, state.getCustomResourceBundles());
    assertSize(0, state.getDissociatedFiles());

    final PsiDirectory directory1 = propFile1.getParent().getParent();
    assertNotNull(directory1);
    ApplicationManager.getApplication().runWriteAction(directory1::delete);

    assertSize(0, state.getCustomResourceBundles());
    assertSize(0, state.getDissociatedFiles());
  }
  public void testCustomResourceBundleFilesMovedOrDeleted() throws IOException {
    final PropertiesFile file =
        PropertiesImplUtil.getPropertiesFile(
            myFixture.addFileToProject("resources-dev/my-app-dev.properties", ""));
    final PropertiesFile file2 =
        PropertiesImplUtil.getPropertiesFile(
            myFixture.addFileToProject("resources-dev/my-app-test.properties", ""));
    final PropertiesFile file3 =
        PropertiesImplUtil.getPropertiesFile(
            myFixture.addFileToProject("resources-prod/my-app-prod.properties", ""));
    assertNotNull(file);
    assertNotNull(file2);
    assertNotNull(file3);
    assertOneElement(file.getResourceBundle().getPropertiesFiles());
    assertOneElement(file2.getResourceBundle().getPropertiesFiles());
    assertOneElement(file3.getResourceBundle().getPropertiesFiles());
    final ResourceBundleManager resourceBundleBaseNameManager =
        ResourceBundleManager.getInstance(getProject());
    resourceBundleBaseNameManager.combineToResourceBundle(list(file, file2, file3), "my-app");

    assertSize(3, file.getResourceBundle().getPropertiesFiles());

    final PsiDirectory newDir =
        PsiManager.getInstance(getProject())
            .findDirectory(myFixture.getTempDirFixture().findOrCreateDir("new-resources-dir"));
    new MoveFilesOrDirectoriesProcessor(
            getProject(),
            new PsiElement[] {file2.getContainingFile()},
            newDir,
            false,
            false,
            null,
            null)
        .run();
    ApplicationManager.getApplication().runWriteAction(() -> file3.getContainingFile().delete());

    assertSize(2, file.getResourceBundle().getPropertiesFiles());

    final ResourceBundleManagerState state =
        ResourceBundleManager.getInstance(getProject()).getState();
    assertNotNull(state);
    assertSize(1, state.getCustomResourceBundles());
    assertSize(2, state.getCustomResourceBundles().get(0).getFileUrls());
  }
  public void testResourceBundleManagerUpdatesProperlyWhileDirMove() {
    final PropertiesFile propFile1 =
        PropertiesImplUtil.getPropertiesFile(myFixture.addFileToProject("qwe/p.properties", ""));
    final PropertiesFile propFile2 =
        PropertiesImplUtil.getPropertiesFile(
            myFixture.addFileToProject("qwe/p_abc.properties", ""));
    assertNotNull(propFile1);
    assertNotNull(propFile2);
    myFixture.addFileToProject("qwe/q.properties", "");
    final PropertiesFile propertiesFile =
        PropertiesImplUtil.getPropertiesFile(myFixture.addFileToProject("qwe/q_fr.properties", ""));
    assertNotNull(propertiesFile);
    assertSize(2, propertiesFile.getResourceBundle().getPropertiesFiles());

    final ResourceBundleManager resourceBundleManager =
        ResourceBundleManager.getInstance(getProject());
    resourceBundleManager.combineToResourceBundle(
        ContainerUtil.newArrayList(propFile1, propFile2), "p");
    resourceBundleManager.dissociateResourceBundle(propertiesFile.getResourceBundle());
    assertSize(1, propertiesFile.getResourceBundle().getPropertiesFiles());
    assertSize(2, propFile2.getResourceBundle().getPropertiesFiles());

    final PsiDirectory toMove = myFixture.addFileToProject("asd/temp.txt", "").getParent();
    assertNotNull(toMove);
    ApplicationManager.getApplication()
        .runWriteAction(
            () -> MoveFilesOrDirectoriesUtil.doMoveDirectory(propFile1.getParent(), toMove));

    final PsiDirectory movedDir = toMove.findSubdirectory("qwe");
    assertNotNull(movedDir);

    final PropertiesFile newPropFile1 =
        PropertiesImplUtil.getPropertiesFile(movedDir.findFile("p.properties"));
    assertNotNull(newPropFile1);
    assertSize(2, newPropFile1.getResourceBundle().getPropertiesFiles());

    final PropertiesFile newPropertiesFile =
        PropertiesImplUtil.getPropertiesFile(movedDir.findFile("q_fr.properties"));
    assertNotNull(newPropertiesFile);
    assertSize(1, newPropertiesFile.getResourceBundle().getPropertiesFiles());
  }
  private void combineToResourceBundleIfNeed(Collection<PsiFile> files) {
    Collection<PropertiesFile> createdFiles =
        ContainerUtil.map(
            files,
            (NotNullFunction<PsiFile, PropertiesFile>)
                dom -> {
                  final PropertiesFile file = PropertiesImplUtil.getPropertiesFile(dom);
                  LOG.assertTrue(file != null, dom.getName());
                  return file;
                });

    ResourceBundle mainBundle = myResourceBundle;
    final Set<ResourceBundle> allBundles = new HashSet<>();
    if (mainBundle != null) {
      allBundles.add(mainBundle);
    }
    boolean needCombining = false;
    for (PropertiesFile file : createdFiles) {
      final ResourceBundle rb = file.getResourceBundle();
      if (mainBundle == null) {
        mainBundle = rb;
      } else if (!mainBundle.equals(rb)) {
        needCombining = true;
      }
      allBundles.add(rb);
    }

    if (needCombining) {
      final List<PropertiesFile> toCombine = new ArrayList<>(createdFiles);
      final String baseName = getBaseName();
      if (myResourceBundle != null) {
        toCombine.addAll(myResourceBundle.getPropertiesFiles());
      }
      ResourceBundleManager manager = ResourceBundleManager.getInstance(mainBundle.getProject());
      for (ResourceBundle bundle : allBundles) {
        manager.dissociateResourceBundle(bundle);
      }
      manager.combineToResourceBundle(toCombine, baseName);
    }
  }
  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());
  }
  public void testCombineToCustomResourceBundleAndDissociateAfter() {
    final PropertiesFile file =
        PropertiesImplUtil.getPropertiesFile(
            myFixture.addFileToProject("resources-dev/my-app-dev.properties", ""));
    final PropertiesFile file2 =
        PropertiesImplUtil.getPropertiesFile(
            myFixture.addFileToProject("resources-prod/my-app-prod.properties", ""));
    assertNotNull(file);
    assertNotNull(file2);
    assertOneElement(file.getResourceBundle().getPropertiesFiles());
    assertOneElement(file2.getResourceBundle().getPropertiesFiles());

    final ResourceBundleManager resourceBundleBaseNameManager =
        ResourceBundleManager.getInstance(getProject());
    final String newBaseName = "my-app";
    resourceBundleBaseNameManager.combineToResourceBundle(list(file, file2), newBaseName);
    final ResourceBundle resourceBundle = file.getResourceBundle();
    assertEquals(2, resourceBundle.getPropertiesFiles().size());
    assertEquals(newBaseName, resourceBundle.getBaseName());

    resourceBundleBaseNameManager.dissociateResourceBundle(resourceBundle);
    assertOneElement(file.getResourceBundle().getPropertiesFiles());
    assertOneElement(file2.getResourceBundle().getPropertiesFiles());
  }