private void createBwt() throws ReportedException {

        int[][] rotationBuffers;
        int compactCodeBufferSize;
        int alphabetSize;
        int initial_start_sequence_length;
        int changeDepth;
        String startSequenceString;



//        testBwtBuffer = new int[compactCodeBuffer.length];


        compactCodeBufferSize = compactCodeBuffer.length;
        bwtBuffer = new byte[compactCodeBufferSize];
        bwtBuffer[0] = compactCodeBuffer[compactCodeBufferSize - 2];
        bwtBufferIndex = 1;



//        testBwtBuffer[0] = compactCodeBufferSize - 1;



        /* initialize prefix-sum table */
        alphabetSize = referenceSequenceIndex.alphabetDictionary.getAlphabetSize();
        referenceSequenceIndex.prefixSumTable = new int[alphabetSize + 2];
        referenceSequenceIndex.prefixSumTable[0] = 0;
        referenceSequenceIndex.prefixSumTable[alphabetSize + 1] = compactCodeBufferSize;    // last entry contains reference sequence length

        /* prepare start sequence buffer */
        startSequenceBuffer = new byte[START_SEQUENCE_BUFFER_SIZE];
        Arrays.fill(startSequenceBuffer, (byte) 1);

        /* prepare rotation buffers array */
        rotationBuffers = new int[START_SEQUENCE_BUFFER_SIZE + 1][];

        /* detect long runs of same character */
        detectLongRuns();

        /* calculate initial start sequence length */
        initial_start_sequence_length = INITIAL_START_SEQUENCE_LENGTH_5;
        if (alphabetSize > 5) {
            initial_start_sequence_length = INITIAL_START_SEQUENCE_LENGTH_10;
        }
        if (alphabetSize > 10) {
            initial_start_sequence_length = INITIAL_START_SEQUENCE_LENGTH_10_PLUS;
        }

        /* update progress bar */
        noStartSequenceCombinations = ((int) round(pow( alphabetSize,
                                                        initial_start_sequence_length   )));
        currentStartSequenceCombination = 0;
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                parentFrame.setProgressBarMaximum(noStartSequenceCombinations);
                parentFrame.setProgressBarValue(currentStartSequenceCombination);
                parentFrame.setProgressBarIndeterminate(false);
            }
        });

        /* update statistics */
        currentPreprocessingMemoryConsumption += compactCodeBufferSize;
        currentPreprocessingMemoryConsumption += START_SEQUENCE_BUFFER_SIZE;
        currentPreprocessingMemoryConsumption += ((START_SEQUENCE_BUFFER_SIZE + 1) * 8);
        if (currentPreprocessingMemoryConsumption > maximalPreprocessingMemoryConsumption) {
            maximalPreprocessingMemoryConsumption = currentPreprocessingMemoryConsumption;
        }

        /* process each start sequence */
        changeDepth = 1;
        do {

            /* fill prefix-sum table */
            if (changeDepth == 1) {
                referenceSequenceIndex.prefixSumTable[startSequenceBuffer[0]] = bwtBufferIndex;
            }

            /*
             * process sequences that are shorter than initial sequence length.
             * They are located at the end of reference sequence.
             */
            for (; changeDepth < initial_start_sequence_length; changeDepth++) {
                checkTail(changeDepth);
            }


            startSequenceString = Byte.toString(startSequenceBuffer[0]);
            for (int i = 1; i < initial_start_sequence_length; i++) {
                startSequenceString += (", " + Byte.toString(startSequenceBuffer[i]));
            }
            System.out.println("Starting sequence \"" + startSequenceString + "\" at: " + sdf.format(Calendar.getInstance().getTime()));


            /* proces all rotations starting with sequence from start sequence buffer */
            findRotations(initial_start_sequence_length, 0, rotationBuffers);

            /* update progress bar */
            currentStartSequenceCombination++;
            java.awt.EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    parentFrame.setProgressBarValue(currentStartSequenceCombination);
                }
            });

            /* calculate next start sequence */
            for (changeDepth = initial_start_sequence_length; changeDepth > 0; changeDepth--) {
                startSequenceBuffer[changeDepth - 1]++;
                if (startSequenceBuffer[changeDepth - 1] <= alphabetSize) {
                    break;
                }
                startSequenceBuffer[changeDepth - 1] = 1;
            }
        } while (changeDepth > 0);



//        System.out.println("BWT test started at: " + sdf.format(Calendar.getInstance().getTime()));
//        testBwt();



        /* release unused objects */
        releaseLongRunMemory();
        compactCodeBuffer = null;
        startSequenceBuffer = null;
        rotationBuffers = null;
        currentPreprocessingMemoryConsumption -= compactCodeBufferSize;
        currentPreprocessingMemoryConsumption -= START_SEQUENCE_BUFFER_SIZE;
        currentPreprocessingMemoryConsumption -= ((START_SEQUENCE_BUFFER_SIZE + 1) * 8);

        bwtCreationTimeBuffer = sdf.format(Calendar.getInstance().getTime());
        System.out.println("Reference sequence BWT creation completed at: " + bwtCreationTimeBuffer);
    }