private static Collection<RPackage> addImportDependencies(Collection<RPackage> importedPackages) {
    RPackageService packageService = RPackageService.getInstance();

    Collection<RPackage> imPckgsWithDeps = new HashSet<RPackage>();

    for (RPackage importedPackage : importedPackages) {
      imPckgsWithDeps.add(importedPackage);
      imPckgsWithDeps.addAll(packageService.getDependencies(importedPackage));
    }

    return imPckgsWithDeps;
  }
  public static List<Function> getFunctionByName(
      String funName, @Nullable Collection<RPackage> importedPackages) {

    RPackageService packageService = RPackageService.getInstance();

    if (packageService == null) return Collections.emptyList();

    // if the user didn't import anything do a global search todo: does this make sense???
    if (importedPackages == null) {
      importedPackages = packageService.getPackages();
    } else {
      importedPackages = addImportDependencies(importedPackages);
    }

    List<Function> funs = new ArrayList<Function>();
    for (RPackage importedPackage : importedPackages) {
      if (importedPackage.hasFunction(funName)) funs.add(importedPackage.getFunction(funName));
    }

    return funs;
  }
  /**
   * @param packageNames Packages to be reindexd if version has changed or package has been
   *     installed since last indexing run.If non are provided all packages will be refreshed.
   */
  public boolean refreshIndex(String... packageNames) {
    RHelperUtil.runHelperWithArgs(RHelperUtil.R_HELPER_INSTALL_TIDYVERSE);

    Set<RPackage> installedPackages = LocalRUtil.getInstalledPackages();

    // remove packages from index that are no longer present
    if (packageNames.length == 0) {
      Sets.SetView<RPackage> noLongerInstalled = Sets.difference(allPackages, installedPackages);
      allPackages.removeAll(noLongerInstalled);
    }

    // cut down packges to be refreshed to speed up calculations
    //        if(packageNames.length>0){
    //            installedPackages = installedPackages.stream().
    //                    filter(p -> Arrays.asList(packageNames).contains(p.getName())).
    //                    collect(Collectors.toSet());
    //        }

    ExecutorService executorService = Executors.newFixedThreadPool(8);

    final boolean[] hasChanged = {false};

    for (final RPackage rPackage : installedPackages) {
      final RPackage indexPackage = getByName(rPackage.getName());

      if (indexPackage != null
          && ObjectUtils.equals(indexPackage.getVersion(), rPackage.getVersion())) {
        continue;
      }

      executorService.submit(
          new Runnable() {
            @Override
            public void run() {
              reindexPackage(rPackage, indexPackage);
              hasChanged[0] = true;
            }
          });
    }

    executorService.shutdown();
    try {
      executorService.awaitTermination(1, TimeUnit.DAYS);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    //        allPackages.clear();
    //        allPackages.addAll(installedPackages);

    if (hasChanged[0]) {
      if (ApplicationManager.getApplication() != null) {
        Project[] projects = ProjectManager.getInstance().getOpenProjects();
        for (Project project : projects) {
          if (project.isInitialized() && project.isOpen() && !project.isDefault()) {
            SpellCheckerManager spellCheckerManager = SpellCheckerManager.getInstance(project);
            EditableDictionary dictionary = spellCheckerManager.getUserDictionary();

            for (RPackage rPackage : RPackageService.getInstance().allPackages) {
              dictionary.addToDictionary(rPackage.getName());
              dictionary.addToDictionary(rPackage.getFunctionNames());
            }

            DaemonCodeAnalyzer.getInstance(project).restart();
          }
        }
      }
    }

    return hasChanged[0];
  }