private int getThreshold(BigLong2ShortHashMap hm) {
        if (maximalBadFrequency.get() != null) {
            return maximalBadFrequency.get();
        }

        long totalKmers = 0;
        int[] stat = new int[STAT_LEN];
        Iterator<MutableLongShortEntry> it = hm.entryIterator();
        while (it.hasNext()) {
            MutableLongShortEntry entry = it.next();
            int v = entry.getValue();
            totalKmers += v;
            if (v >= stat.length) {
                v = stat.length - 1;
            }
            ++stat[v];
        }

        if (bottomCutPercent.get() != null) {
            long kmersToCut = totalKmers * bottomCutPercent.get() / 100;
            long currentKmersCount = 0;
            for (int i = 0; i < stat.length - 1; i++) {
                if (currentKmersCount >= kmersToCut) {
                    return i;
                }
                currentKmersCount += (long) i * stat[i];
            }
        }

        if (maximalBadFrequency.get() == null) {
            int threshold = 1;
            long currentSum = 0;
            while (stat[threshold] * (long) threshold > stat[threshold + 1] * (long) (threshold + 1)) {
                currentSum += stat[threshold];
                if (currentSum * 2 > totalKmers) {
                    debug("Threshold search stopped at 50 %");
                    break;
                }
                threshold++;
            }
            return threshold;
        }

        debug("Something strange about threshold");
        return 0;
    }