public int countQuerySequenceOccurrences (String qurySeq) throws ReportedException {

        Charset utf8Charset;
        Calendar calendar;
        String queryStartTimeBuffer;
        String queryEndTimeBuffer;
        String statistics;
        byte[] querySequenceBuffer;
        long countDuration;
        int queryCharacter;
        int queryIndex;
        int queryLength;
        int lowIndex;
        int lowIndexShift;
        int highIndex;
        int highIndexShift;
        byte characterToProcess;

        /* get query start time */
        calendar = Calendar.getInstance();
        countDuration = calendar.getTimeInMillis();
        queryStartTimeBuffer = sdf.format(calendar.getTime());
        System.out.println("Query start time: " + queryStartTimeBuffer);

        /* prepare query buffer */
        queryLength = qurySeq.length();
        if (queryLength <= 0) {
            reportError("Prazan upitni slijed!");
            throw new ReportedException();
        }
        querySequenceBuffer = new byte[queryLength];
        utf8Charset = Charset.forName("UTF-8");
        querySequenceBuffer = qurySeq.getBytes(utf8Charset);
        utf8Charset = null;
        queryIndex = 0;
        for (int i = 0; i < queryLength; i++) {
            queryCharacter = querySequenceBuffer[i];
            if ((queryCharacter >= 32) && (queryCharacter <= 126)) {
                queryCharacter = toUpperCase(queryCharacter);
                queryCharacter = referenceSequenceIndex.alphabetDictionary.getCompactCode((byte) queryCharacter);
                if (queryCharacter == 0) {
                    reportError("Znak (" + qurySeq.substring(i, i + 1) + ") iz upitnog slijeda ne nalazi se u referentnom slijedu!");
                    throw new ReportedException();
                }
                querySequenceBuffer[queryIndex++] = ((byte) queryCharacter);
            }
        }
        queryLength = queryIndex;
        if (queryLength <= 0) {
            reportError("Prazan upitni slijed!");
            throw new ReportedException();
        }

        /* count matches */
        characterToProcess = querySequenceBuffer[queryLength - 1];
        lowIndex =  referenceSequenceIndex.C(characterToProcess);
        highIndex = (   referenceSequenceIndex.C((byte) (characterToProcess + 1)) - 1);
        for (int i = (queryLength - 2); i >= 0; i--) {
            characterToProcess = querySequenceBuffer[i];

            lowIndexShift = referenceSequenceIndex.occurrenceWaveletTree.Occ(characterToProcess, lowIndex);
            lowIndex =  referenceSequenceIndex.C(characterToProcess);
            lowIndex += lowIndexShift;

            highIndexShift = referenceSequenceIndex.getCharacterTotal(characterToProcess);
            highIndexShift -= referenceSequenceIndex.occurrenceWaveletTree.Occ(characterToProcess, (highIndex + 1));
            highIndex = (   referenceSequenceIndex.C((byte) (characterToProcess + 1)) - 1);
            highIndex -= highIndexShift;

            if (highIndex < lowIndex) {
                break;
            }
        }
        highIndex -= lowIndex;
        highIndex++;

        /* get query end time */
        calendar = Calendar.getInstance();
        countDuration = (calendar.getTimeInMillis() - countDuration);
        queryEndTimeBuffer = sdf.format(calendar.getTime());
        System.out.println("Query start time: " + queryEndTimeBuffer);

        /* report statistics */
        statistics = "Statistika brojanja ponavljanja upita u referentnoj sekvenci:\n";
        statistics += (  "\n    Vrijeme početka brojanja:                           " + queryStartTimeBuffer);
        statistics += (  "\n    Vrijeme završetka brojanja:                         " + queryEndTimeBuffer);
        statistics += (  "\n    Ukupno vrijeme brojanja:                            " + Long.toString(countDuration) + " ms");

        statistics += ("\n\n    Dužina referentnog slijede:                         " + Integer.toString(referenceSequenceIndex.prefixSumTable[referenceSequenceIndex.prefixSumTable.length - 1] - 1));
        statistics += (  "\n    Dužina upitnog slijede:                             " + Integer.toString(queryLength));

        statistics += ("\n\n    Broj pronađenih podudaranja:                        " + Integer.toString(highIndex));

        statistics += ("\n\n    Maksimalno zauzeće memorije tijekom brojanja:       " + Integer.toString((int) ((maximalPreprocessingMemoryConsumption + querySequenceBuffer.length) / 1000)) + " KB");

        JOptionPane.showConfirmDialog(null, statistics, "FMIndexCount", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE);

        if (highIndex <= 0) {
            return 0;
        } else {
            return highIndex;
        }
    }