@Override
  public void actionPerformed(@NotNull AnActionEvent e) {
    long start = System.currentTimeMillis();

    suffixes.clear();
    nameCount.clear();
    VirtualFile[] roots = ManagingFS.getInstance().getRoots(LocalFileSystem.getInstance());
    for (VirtualFile root : roots) {
      compute(root);
    }

    final List<Pair<String,Integer>> names = new ArrayList<>(nameCount.size());
    for (Object2IntMap.Entry<String> entry : nameCount.object2IntEntrySet()) {
      names.add(new Pair<>(entry.getKey(), entry.getIntValue()));
    }
    names.sort((o1, o2) -> o2.second - o1.second);

    System.out.println("Most frequent names ("+names.size()+" total):");
    int saveByIntern = 0;
    for (Pair<String, Integer> pair : names) {
      int count = pair.second;
      String name = pair.first;
      System.out.println(name + " -> " + count);
      saveByIntern += count * name.length();
      if (count == 1) break;
    }
    System.out.println("Total save if names were interned: "+saveByIntern+"; ------------");

    //System.out.println("Prefixes: ("+prefixes.size()+" total)");
    //show(prefixes);
    System.out.println("Suffix counts:("+suffixes.size()+" total)");
    show(suffixes);


    final Object2IntMap<String> save = new Object2IntOpenHashMap<>();
    // compute economy
    for (Object2IntMap.Entry<String> entry : suffixes.object2IntEntrySet()) {
      save.put(entry.getKey(), entry.getIntValue() * entry.getKey().length());
    }

    System.out.println("Supposed save by stripping suffixes: ("+save.size()+" total)");
    final List<Pair<String, Integer>> saveSorted = show(save);


    final List<String> picked = new ArrayList<>();
    //List<String> candidates = new ArrayList<String>();
    //int i =0;
    //for (Pair<String, Integer> pair : sorted) {
    //  if (i++>1000) break;
    //  candidates.add(pair.first);
    //}

    //final TObjectIntHashMap<String> counts = new TObjectIntHashMap<String>();
    //suffixes.forEachEntry(new TObjectIntProcedure<String>() {
    //  @Override
    //  public boolean execute(String a, int b) {
    //    counts.put(a, b);
    //    return true;
    //  }
    //});

    while (picked.size() != 15) {
      Pair<String, Integer> cp = saveSorted.get(0);
      final String candidate = cp.first;
      picked.add(candidate);
      System.out.println("Candidate: '"+candidate+"', save = "+cp.second);
      picked.sort((o1, o2) -> {
        return o2.length() - o1.length(); // longer first
      });
      saveSorted.clear();

      // adjust
      for (Object2IntMap.Entry<String> entry : suffixes.object2IntEntrySet()) {
        String s = entry.getKey();
        int count = entry.getIntValue();
        for (int i = picked.size() - 1; i >= 0; i--) {
          String pick = picked.get(i);
          if (pick.endsWith(s)) {
            count -= suffixes.getInt(pick);
            break;
          }
        }
        saveSorted.add(Pair.create(s, s.length() * count));
      }
      saveSorted.sort((o1, o2) -> o2.second.compareTo(o1.second));
    }

    System.out.println("Picked: "+ StringUtil.join(picked, s -> "\"" + s + "\"", ","));
    picked.sort((o1, o2) -> {
      return o2.length() - o1.length(); // longer first
    });

    int saved = 0;
    for (int i = 0; i < picked.size(); i++) {
      String s = picked.get(i);
      int count = suffixes.getInt(s);
      for (int k=0; k<i;k++) {
        String prev = picked.get(k);
        if (prev.endsWith(s)) {
          count -= suffixes.getInt(prev);
          break;
        }
      }
      saved += count * s.length();
    }
    System.out.println("total saved = " + saved);
    System.out.println("Time spent: " + (System.currentTimeMillis() - start));
  }
@Override
  public void actionPerformed(@NotNull AnActionEvent e)