protected void stepForward(boolean showSteps) {

      switch (m_currentPhase) {
         case PHASE_PREPROCESSING:

            long precSize = getNumPrecomputedBlocs();

            if (precSize > Integer.MAX_VALUE) {
               JOptionPane.showMessageDialog(null,
                                             "Number of precompiled matrix too large!",
                                             "Error",
                                             JOptionPane.ERROR_MESSAGE);
               return;
            }

            // it's about 550 bytes for every matrix..
            int megs = (int)((double)(550 * precSize) / 1000000.0);

            NumberFormat nf = NumberFormat.getInstance();
            String precSizeStr = nf.format(precSize);

            if (precSize > PRECOMPILED_WARNING_LIMIT) {

               int retVal = JOptionPane.showConfirmDialog(null,
                   "Warning! The number of blocs to compute will be very large (" +
                   precSizeStr +
                   ").\n You will need a huge amount of memory (~" +
                   megs +
                   " MB).\n Do you still want to continue?", "Warning!",
                   JOptionPane.YES_NO_OPTION);

               if (retVal != JOptionPane.YES_OPTION) {
                  return;
               }
            }

            try {
               m_preprocTable = new Hashtable( (int) precSize);
               m_orderedKeys = new ArrayList( (int) precSize);
            }
            catch (java.lang.OutOfMemoryError e) {
               m_preprocTable = null;
               m_orderedKeys = null;
               Runtime.getRuntime().gc();
               JOptionPane.showMessageDialog(null,
                                             "Out of memory!\n (Please give " +
                                             "a second to the garbage collector " +
                                             "to clean this mess..).\n" +
                                             "Note: Il could be unstable anyway",
                                             "Didn't I tell you? :)",
                                             JOptionPane.ERROR_MESSAGE);

               Runtime.getRuntime().gc();
               Runtime.getRuntime().gc();
               return;

            }

            PreprocessingFrame prFrm =
                new PreprocessingFrame(m_preprocTable, m_orderedKeys,
                                       m_t, m_encodedAlphSize,
                                       this);

            prFrm.show();

            m_currentStep = 0;
            m_currentPhase = PHASE_CALC_GRID;

            break;

         case PHASE_CALC_GRID:

            if (m_currentStep >= m_nHBlocs * m_nVBlocs) {

               m_backtrackLastSel = m_dpTable.getLastCell();

               // reset result string
               for (int i = 0; i < 3; i++) {
                  m_resLine[i] = "";
               }

               setInfoMessage("Backtracking Pointers. Policy used: " +
                               CellElement.getPolicyName(
                               m_backtrackingPolicy) + ".");

               m_currentPhase = PHASE_BACKTRACK;
               ((FRTable)m_dpTable).setShowBackgroundIndexes(false);
               m_dpTable.clearHighlightColors();

               m_dwPanel.setVisible(true);
               m_l1Choiche.setVisible(true);
               m_l2Choiche.setVisible(true);
               m_l3Choiche.setVisible(true);

               stepFWDBackTrack(showSteps);

            }
            else {
               setInfoMessage("Applying preprocessed blocs. Step: " +
                              m_currentStep);
               this.stepFWDCalc(showSteps);
            }

            break;

         case PHASE_BACKTRACK:

            stepFWDBackTrack(showSteps);

            break;
      }
   }