@Nullable
  private static String getAirVersionIfCustomDescriptor(final JpsFlexBuildConfiguration bc) {
    if (bc.getTargetPlatform() == TargetPlatform.Desktop) {
      final JpsAirDesktopPackagingOptions packagingOptions = bc.getAirDesktopPackagingOptions();
      if (!packagingOptions.isUseGeneratedDescriptor()) {
        return FlexCommonUtils.parseAirVersionFromDescriptorFile(
            packagingOptions.getCustomDescriptorPath());
      }
    } else if (bc.getTargetPlatform() == TargetPlatform.Mobile) {
      final JpsAndroidPackagingOptions androidOptions = bc.getAndroidPackagingOptions();
      final JpsIosPackagingOptions iosPackagingOptions = bc.getIosPackagingOptions();

      // if at least one of descriptors is generated - return null
      if (androidOptions.isEnabled() && androidOptions.isUseGeneratedDescriptor()
          || iosPackagingOptions.isEnabled() && iosPackagingOptions.isUseGeneratedDescriptor()) {
        return null;
      }

      String androidAirVersion = null;
      String iosAirVersion = null;

      if (androidOptions.isEnabled() && !androidOptions.isUseGeneratedDescriptor()) {
        androidAirVersion =
            FlexCommonUtils.parseAirVersionFromDescriptorFile(
                androidOptions.getCustomDescriptorPath());
      }

      if (iosPackagingOptions.isEnabled() && !iosPackagingOptions.isUseGeneratedDescriptor()) {
        iosAirVersion =
            FlexCommonUtils.parseAirVersionFromDescriptorFile(
                iosPackagingOptions.getCustomDescriptorPath());
      }

      if (androidAirVersion == null) return iosAirVersion;
      if (iosAirVersion == null) return androidAirVersion;

      // return minimal
      return StringUtil.compareVersionNumbers(androidAirVersion, iosAirVersion) > 0
          ? iosAirVersion
          : androidAirVersion;
    }
    return null;
  }
  @NotNull
  public List<BuildRootDescriptor> computeRootDescriptors(
      final JpsModel model,
      final ModuleExcludeIndex index,
      final IgnoredFileIndex ignoredFileIndex,
      final BuildDataPaths dataPaths) {
    final List<BuildRootDescriptor> result = new ArrayList<BuildRootDescriptor>();

    final Collection<File> srcRoots = new ArrayList<File>();

    for (JpsModuleSourceRoot sourceRoot :
        myBC.getModule().getSourceRoots(JavaSourceRootType.SOURCE)) {
      final File root = JpsPathUtil.urlToFile(sourceRoot.getUrl());
      result.add(new FlexSourceRootDescriptor(this, root));
      srcRoots.add(root);
    }

    if (FlexCommonUtils.isFlexUnitBC(myBC)) {
      for (JpsModuleSourceRoot sourceRoot :
          myBC.getModule().getSourceRoots(JavaSourceRootType.TEST_SOURCE)) {
        final File root = JpsPathUtil.urlToFile(sourceRoot.getUrl());
        result.add(new FlexSourceRootDescriptor(this, root));
        srcRoots.add(root);
      }
    }

    for (final JpsFlexDependencyEntry entry : myBC.getDependencies().getEntries()) {
      if (entry instanceof JpsFlexBCDependencyEntry) {
        final JpsFlexBuildConfiguration dependencyBC = ((JpsFlexBCDependencyEntry) entry).getBC();
        if (dependencyBC != null) {
          result.add(
              new FlexSourceRootDescriptor(this, new File(dependencyBC.getActualOutputFilePath())));
        }
      } else if (entry instanceof JpsLibraryDependencyEntry) {
        final JpsLibrary library = ((JpsLibraryDependencyEntry) entry).getLibrary();
        if (library != null) {
          for (String rootUrl : library.getRootUrls(JpsOrderRootType.COMPILED)) {
            result.add(new FlexSourceRootDescriptor(this, JpsPathUtil.urlToFile(rootUrl)));
          }
        }
      }
    }

    final BuildConfigurationNature nature = myBC.getNature();

    if (nature.isWebPlatform()
        && nature.isApp()
        && myBC.isUseHtmlWrapper()
        && !myBC.getWrapperTemplatePath().isEmpty()) {
      addIfNotUnderRoot(result, new File(myBC.getWrapperTemplatePath()), srcRoots);
    }

    if (FlexCommonUtils.canHaveRLMsAndRuntimeStylesheets(myBC)) {
      for (String cssPath : myBC.getCssFilesToCompile()) {
        if (!cssPath.isEmpty()) {
          addIfNotUnderRoot(result, new File(cssPath), srcRoots);
        }
      }
    }

    if (!myBC.getCompilerOptions().getAdditionalConfigFilePath().isEmpty()) {
      addIfNotUnderRoot(
          result, new File(myBC.getCompilerOptions().getAdditionalConfigFilePath()), srcRoots);
    }

    if (nature.isApp()) {
      if (nature.isDesktopPlatform()) {
        addAirDescriptorPathIfCustom(result, myBC.getAirDesktopPackagingOptions(), srcRoots);
      } else if (nature.isMobilePlatform()) {
        if (myBC.getAndroidPackagingOptions().isEnabled()) {
          addAirDescriptorPathIfCustom(result, myBC.getAndroidPackagingOptions(), srcRoots);
        }
        if (myBC.getIosPackagingOptions().isEnabled()) {
          addAirDescriptorPathIfCustom(result, myBC.getIosPackagingOptions(), srcRoots);
        }
      }
    }

    return result;
  }