Example of Java Smart Differencer Output

This page contains an example of the output generated by SD's Java Smart Differencer tool
when applied to an original file and an updated version of the same file.

Output from Java Smart Differencer on original and updated file

This page contains an example of the output generated by SD's Java Smart Differencer tool.
Observe that the Smart Differencer produces only 117 lines of output, compared to diff's 167 lines of output; the programmer simply has to look at less code. Note the added precision of Smart Differencer output: fine grain deltas with line and column number (l.c) ranges vs. full-line deltas, and the detection of renamed variables ('oldname' ->'newname'). Notice that source code formatting (different line breaks at line 158) don't fool the smart differencer, that changed comments don't confuse it, and that radix changes on the numeric constant and different escaping conventions that don't change its content in the string are ignored.
For comparison, see deltas generated from a standard diff tool.


Insert 12.5-12.57
>    Map<Integer,Set<Integer>> probesLocatedInFile = null;
Insert 185.9-185.71
>        this.probesLocatedInFile = new HashMap<Integer,Set<Integer>>();
Insert 201.9-203.9 copying 196.14-196.20 to 201.13-201.21
>        for(int i = 1; i <= totalFiles; i++) {
>                probesLocatedInFile.put(i, new HashSet<Integer>());
>        }
Insert 279.13-280.33 copying 267.13-268.30 to 279.13-280.33 with 'columnNum'~>'endColumnNum' and 'lineNum'~>'endLineNum'
>            int endLineNum = 0;
>            int endColumnNum = 0;
Insert 352.68-352.73
>                                                                   , 0, 0  
Insert 436.13-509.38 copying 450.17-518.35 to 436.13-509.38 with 'hlevel'~>'endLineNum' and 'hname'~>'endColumnNum'
>            i = startFrom;
>            nextNumber = 0;
>
>            while (i < probeLineLength) {
>                if (probeLine[i] >= '0' && probeLine[i] <= '9') {
>                    nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
>                    ++i;
>                } else
>                    break;
>            }
>
>            if (i < probeLineLength) {
>                if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
>                    while (i < probeLineLength) {
>                        if (probeLine[i] == ' ') //skip blanks
>                            ++i;
>                        else
>                            break;
>                    }
>                    if (i >= probeLineLength
>                        || probeLine[i] == '\r'
>                        || probeLine[i] == '\n') //end of the line
>                        startFrom = -1;
>                    else
>                        startFrom = i;
>                } else
>                    throw new WrongProbeLine(current_line);
>            } else
>                startFrom = -1;
>
>            if (nextNumber == 0) //some non-digit char is in the probe line
>                throw new WrongProbeLine(current_line);
>            endLineNum = nextNumber;
>
>            /****************************************************************************************/
>            /****************************** Read END column number ***************************************/
>            // note: end column indicates probe region ends on the character right before end column number
>            // using definition of lexeme extractor: Lexeme start and end information indicates
>            //  where the first and character past the end of lexeme, respectively, are found
>            //  in the source file.
>            
>            i = startFrom;
>            nextNumber = 0;
>
>            while (i < probeLineLength) {
>                if (probeLine[i] >= '0' && probeLine[i] <= '9') {
>                    nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
>                    ++i;
>                } else
>                    break;
>            }
>
>            if (i < probeLineLength) {
>                if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
>                    while (i < probeLineLength) {
>                        if (probeLine[i] == ' ') //skip blanks
>                            ++i;
>                        else
>                            break;
>                    }
>                    if (i >= probeLineLength
>                        || probeLine[i] == '\r'
>                        || probeLine[i] == '\n') //end of the line
>                        startFrom = -1;
>                    else
>                        startFrom = i;
>                } else
>                    throw new WrongProbeLine(current_line);
>            } else
>                startFrom = -1;
>
>            if (nextNumber == 0) //some non-digit char is in the probe line
>                throw new WrongProbeLine(current_line);
>            endColumnNum = nextNumber;
Insert 513.84-513.109
>                                                                                   , endLineNum, endColumnNum  
Substitute 424.13-424.59 by 514.25-514.47
<            probesInFile[fileNum] = ++probesInFile[fileNum] 
>                        probesInFile[fileNum]++ 
Insert 515.25-515.87
>                        Set<Integer> t_probe_numbers = probesLocatedInFile.get(fileNum) 
Delete 429.13-429.64 merging 429.42-429.64 into 1379.29-1379.52 with 'startFrom'~>'currentPos'
<            int indexOfSpace = lineString.indexOf(' ',startFrom) 
Delete 430.13-432.51 merging 430.33-430.71 into 508.17-508.55, merging 431.26-431.68 into 150.31-150.79 with 'indexOfSpace'~>'lastsubstringEnd', and merging 432.28-432.50 into 233.34-233.56
<            if (indexOfSpace<0) throw new WrongProbeLine(current_line);
<            lineString = lineString.substring(indexOfSpace+1).trim();
<            indexOfSpace = lineString.indexOf(' ');
Insert 516.25-519.25
>                        if (t_probe_numbers==null) {
>                                t_probe_numbers = new TreeSet<Integer>();
>                                probesLocatedInFile.put(fileNum,t_probe_numbers);
>                        }
Delete 433.13-439.13 merging 435.28-435.70 into 150.31-150.79 with 'indexOfSpace'~>'lastsubstringEnd'
<            if (indexOfSpace<0) startFrom=-1;
<            else {
<                lineString=lineString.substring(indexOfSpace+1).trim();
<                startFrom=0;
<                probeLine=lineString.toCharArray();
<                probeLineLength=probeLine.length;
<            }
Insert 520.25-520.54
>                        t_probe_numbers.add(probeNum);

Output from Cygwin diff tool

Note absence of column number data, absence of rename detection, failure to recognize reformatted code as unchanged (diff thinks the block of code at line 158 has changed), failure to notice same numeric values in the face radix change (line 168), and failure to ignore comments.
See the actual deltas generated from Java Smart Differencer.
See original file and updated version of the same file.


11a12
>     Map<Integer,Set<Integer>> probesLocatedInFile = null;
17c18,19
<     int coveredProbes; float coveredPercentage;
---
>     int coveredProbes;
>     float coveredPercentage;
153c155,156
<                 String newFileName = prfDirectory + System.getProperty("file.separator") + fileName;
---
>                 String newFileName =
>                     prfDirectory + System.getProperty("file.separator") + fileName;
158,163c161,169
<             else { // This block of code is badly formatted, someone should clean it up
<                 javax.swing.JOptionPane.showMessageDialog( null,
<                    "Could not open the file " + fileName
<                         + "\n specified in selected probe reference file "
<                          + probeReferenceFile.getName(),
<                   "Can not Open Source File", javax.swing.JOptionPane.WARNING_MESSAGE);
---
>             else {
>                 javax.swing.JOptionPane.showMessageDialog(
>                                                           null,
>                                                           "Could not open the file "
>                                                           + fileName
>                                                           + "\n specified in selected probe reference file "
>                                                           + probeReferenceFile.getName(),
>                                                           "Can not Open Source File",
>                                                           javax.swing.JOptionPane.WARNING_MESSAGE);
168c174
<             this.sortedFileIndex[fileNumber - 0x1] = fileNumber;
---
>             this.sortedFileIndex[fileNumber - 1] = fileNumber;
178a185
>         this.probesLocatedInFile = new HashMap<Integer,Set<Integer>>();
192a200,203
>
>         for(int i = 1; i <= totalFiles; i++) {
>               probesLocatedInFile.put(i, new HashSet<Integer>());
>         }
246d256
<
268a279,280
>             int endLineNum = 0;
>             int endColumnNum = 0;
340c352
<               probesArray[probeNum] = new Probe(probeNum, 0, 0, 0);
---
>               probesArray[probeNum] = new Probe(probeNum, 0, 0, 0, 0, 0);
421a434,511
>             /****************************************************************************************/
>             /****************************** Read END line number ***************************************/
>             i = startFrom;
>             nextNumber = 0;
>
>             while (i < probeLineLength) {
>                 if (probeLine[i] >= '0' && probeLine[i] <= '9') {
>                     nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
>                     ++i;
>                 } else
>                     break;
>             }
>
>             if (i < probeLineLength) {
>                 if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
>                     while (i < probeLineLength) {
>                         if (probeLine[i] == ' ') //skip blanks
>                             ++i;
>                         else
>                             break;
>                     }
>                     if (i >= probeLineLength
>                         || probeLine[i] == '\r'
>                         || probeLine[i] == '\n') //end of the line
>                         startFrom = -1;
>                     else
>                         startFrom = i;
>                 } else
>                     throw new WrongProbeLine(current_line);
>             } else
>                 startFrom = -1;
>
>             if (nextNumber == 0) //some non-digit char is in the probe line
>                 throw new WrongProbeLine(current_line);
>             endLineNum = nextNumber;
>
>             /****************************************************************************************/
>             /****************************** Read END column number ***************************************/
>             // note: end column indicates probe region ends on the character right before end column number
>             // using definition of lexeme extractor: Lexeme start and end information indicates
>             //  where the first and character past the end of lexeme, respectively, are found
>             //  in the source file.
>
>             i = startFrom;
>             nextNumber = 0;
>
>             while (i < probeLineLength) {
>                 if (probeLine[i] >= '0' && probeLine[i] <= '9') {
>                     nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
>                     ++i;
>                 } else
>                     break;
>             }
>
>             if (i < probeLineLength) {
>                 if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
>                     while (i < probeLineLength) {
>                         if (probeLine[i] == ' ') //skip blanks
>                             ++i;
>                         else
>                             break;
>                     }
>                     if (i >= probeLineLength
>                         || probeLine[i] == '\r'
>                         || probeLine[i] == '\n') //end of the line
>                         startFrom = -1;
>                     else
>                         startFrom = i;
>                 } else
>                     throw new WrongProbeLine(current_line);
>             } else
>                 startFrom = -1;
>
>             if (nextNumber == 0) //some non-digit char is in the probe line
>                 throw new WrongProbeLine(current_line);
>             endColumnNum = nextNumber;
>
>
423,424c513,520
<             probesArray[probeNum] = new Probe(probeNum, lineNum, fileNum, columnNum);
<             probesInFile[fileNum] = ++probesInFile[fileNum];
---
>             probesArray[probeNum] = new Probe(probeNum, lineNum, fileNum, columnNum, endLineNum, endColumnNum);
>                       probesInFile[fileNum]++;
>                       Set<Integer> t_probe_numbers = probesLocatedInFile.get(fileNum);
>                       if (t_probe_numbers==null) {
>                               t_probe_numbers = new TreeSet<Integer>();
>                               probesLocatedInFile.put(fileNum,t_probe_numbers);
>                       }
>                       t_probe_numbers.add(probeNum);
429,439c525,538
<             int indexOfSpace = lineString.indexOf(' ',startFrom);
<             if (indexOfSpace<0) throw new WrongProbeLine(current_line);
<             lineString = lineString.substring(indexOfSpace+1).trim();
<             indexOfSpace = lineString.indexOf(' ');
<             if (indexOfSpace<0) startFrom=-1;
<             else {
<                 lineString=lineString.substring(indexOfSpace+1).trim();
<                 startFrom=0;
<                 probeLine=lineString.toCharArray();
<                 probeLineLength=probeLine.length;
<             }
---
> //            if (false) {
> //            int indexOfSpace = lineString.indexOf(' ',startFrom);
> //            if (indexOfSpace<0) throw new WrongProbeLine(current_line);
> //            lineString = lineString.substring(indexOfSpace+1).trim();
> //            indexOfSpace = lineString.indexOf(' ');
> //            if (indexOfSpace<0) startFrom=-1;
> //            else {
> //                lineString=lineString.substring(indexOfSpace+1).trim();
> //                startFrom=0;
> //                probeLine=lineString.toCharArray();
> //                probeLineLength=probeLine.length;
> //            }
> //            }

Source Code before Change

This code is a sample taken from one of SD's Java files (1381 lines), before an update was made.
See updated version of the same file.


package DMS.Tools.TestCoverage;
import java.io.*;
import java.util.*;

class TCVModel{
    public TCVModel(){
    }

    File probeReferenceFile;
    long CONFIGURATION_NUMBER = 0;
    int[][] visitedProbeLinesInFile = null;
    HorizontalTabulators DMS_HorizontalTabulators;
    final String DMS_TABULATORS_PROPERTY = "DMS_HORIZONTAL_TABULATORS";
    final String TOOL_NAME = "TestCoverage";
    String CurrentTCVDisplayDomain;
    String ToolVersion;
    int coveredProbes; float coveredPercentage;
    int totalProbes;
    int deadProbes;
    int totalFiles;
    int totalHierarchyNames;
    int totalHierarchyLevels=0;

    String[] fileIndex;
    int[] sortedFileIndex;
    int[] probesInFile;
    int[] coveredProbesInFile;
    Probe[] probesArray;
    String[] hierarchyNames;
    String hierarchyLevels[] = new String[10];
    HierarchyElements topLevelHierarchy;
    boolean globalVisitedProbes[];

    private Comparator stringComparator = new StringComparator();

    int   uncoveredProbesInFile[];
    float uncoveredPercentageInFile[];
    int   uncoveredProbesInDirectoryRecursive[];
    float uncoveredPercentageInDirectoryRecursive[];

    //for subsystem report
    int totalDirectories;
    int[] coveredProbesInDirectoryNonrecursive;
    int[] coveredProbesInDirectoryRecursive;
    int[] sortedDirectoryIndex;
    boolean[][] subdirectories;
    int[] probesInDirectoryNonrecursive;
    int[] probesInDirectoryRecursive;
    boolean[][] filesInDirectory;
    int[] directoryOfFile;
    String[] directoryIndex;

    /**
     * Insert the method's description here.
     * Creation date: (2/11/2003 2:23:33 PM)
     * @param config java.lang.String
     */
    private boolean isValidConfig(String config) {
        int end_index = config.indexOf(" ");
        if (end_index < 0) {
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "No domain name found at the first line of your prf file. \nFormat of the first line: DomainName TestCoverage VerstionNumber.",
                                                      "Invalid probe reference file",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            return false;
        }
        this.CurrentTCVDisplayDomain = config.substring(0, end_index);
        if (end_index + 1 >= config.length()) {
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "No tool name found at the first line of your prf file. \nFormat of the first line: DomainName TestCoverage VerstionNumber.",
                                                      "Invalid probe reference file",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            return false;
        }
        config = config.substring(end_index + 1).trim();
        end_index = config.indexOf(" ");
        if (end_index < 0) {
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Incomplete first line of your prf file. \nFormat of the first line: DomainName TestCoverage VerstionNumber.",
                                                      "Invalid probe reference file",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            return false;
        }
        String toolName = config.substring(0, end_index);
        if (toolName.compareTo(this.TOOL_NAME) != 0) {
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Wrong tool name found at the first line of your prf file. \nFormat of the first line: DomainName TestCoverage VerstionNumber.",
                                                      "Invalid probe reference file",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            return false;
        }
        this.ToolVersion = config.substring(end_index + 1).trim();
        return true;
    }

    private String detectEncoding(InputStream inputStream) throws IOException{
        byte[] b = new byte[2];

        final byte ff = (byte) 0xff;
        final byte fe = (byte) 0xfe;

        inputStream.read(b);

        if (b[0] == fe && b[1] == ff) {
            return "Unicode";
        }
        if (b[0] == ff && b[1] == fe) {
            return "Unicode";
        }
        return "ASCII";
    }

    private String constructFileIndexMap(LineNumberReader linenumberReader) throws IOException, WrongProbeReferenceFileConfig{
        //constructing file numbers map
        String lineString;
        String prfDirectory = probeReferenceFile.getAbsoluteFile().getParentFile().getCanonicalPath();

        for (;;) {
            lineString = linenumberReader.readLine().trim();

            //skip the empty line
            if (lineString.length() == 0)
                continue;

            //start hierarchy information list) or start the probe number section
            if (lineString.startsWith("%%") || lineString.startsWith("!"))
                break;

            int lastsubstringEnd = lineString.indexOf(" ");
            if (lastsubstringEnd <= 0)
                continue;
            String fileNumberString = lineString.substring(0, lastsubstringEnd).trim();
            int fileNumber = 0;
            try {
                fileNumber = Integer.parseInt(fileNumberString);
            } catch (NumberFormatException nfe) {
                javax.swing.JOptionPane.showMessageDialog(
                                                          null,
                                                          "Line " + linenumberReader.getLineNumber()+ ": there is number format exception on file number " + fileNumberString,
                                                          "Wrong File Number in Probe Reference File",
                                                          javax.swing.JOptionPane.WARNING_MESSAGE);
                throw nfe;    
            }
            String fileName = lineString.substring(lastsubstringEnd + 1).trim();
            String canonicalFileName = null;
            File sourceFile = new File(fileName);

            if (!sourceFile.canRead()) {
                String newFileName = prfDirectory + System.getProperty("file.separator") + fileName;
                sourceFile = new File(newFileName);
            }
            if (sourceFile.canRead())
                canonicalFileName = sourceFile.getAbsolutePath();
            else { // This block of code is badly formatted, someone should clean it up
                javax.swing.JOptionPane.showMessageDialog( null,
                   "Could not open the file " + fileName
                        + "\n specified in selected probe reference file "
                         + probeReferenceFile.getName(),
                  "Can not Open Source File", javax.swing.JOptionPane.WARNING_MESSAGE);
                throw new WrongProbeReferenceFileConfig();
            }

            this.fileIndex[fileNumber] = canonicalFileName;
            this.sortedFileIndex[fileNumber - 0x1] = fileNumber;
        } // end of for(;;)
        return lineString;
    }

    private void allocateArrays(){
        this.probesArray = new Probe[totalProbes + 1];
        this.fileIndex = new String[totalFiles + 1];
        this.probesInFile = new int[totalFiles + 1];
        this.sortedFileIndex = new int[totalFiles];
        this.visitedProbeLinesInFile = new int[this.totalFiles + 1][];
        this.directoryOfFile = new int[totalFiles + 1];
        uncoveredProbesInFile = new int[totalFiles + 1];
        uncoveredPercentageInFile= new float[totalFiles + 1];

        System.out.println(
                           "Total Probes in "
                           + probeReferenceFile.getName()
                           + " is "
                           + totalProbes);
        System.out.println(
                           "Total files in "
                           + probeReferenceFile.getName()
                           + " is "
                           + totalFiles);
    }

    void initializeProbes(){
        for (int i=1; i<=totalProbes; ++i){
            HierarchyElements he = probesArray[i].hierarchies;
            for (int j=0; j<he.size(); ++j){
                he.getElement(j).probesVisited=0;
            }
        }
	globalVisitedProbes = new boolean[totalProbes + 1];
	coveredProbesInFile = new int[totalFiles + 1];
        coveredProbesInDirectoryNonrecursive = new int[totalDirectories];
    }

    private String getHierarchyNames(LineNumberReader linenumberReader) throws IOException,WrongProbeReferenceFileConfig{
        //start getting hierarchy names
        String lineString;
            hierarchyNames = new String[totalHierarchyNames+1];
            int hcount = 0;
            for (;;) {
                lineString = linenumberReader.readLine().trim();

                //skip the empty line
                if (lineString.length() == 0)
                    continue;

                //start hierarchy information list) or start the probe number section
                if (lineString.startsWith("%%"))
                    break;
                int spaceIndex = lineString.indexOf(' ');
                if (spaceIndex<0){
                    javax.swing.JOptionPane.showMessageDialog(
                                                              null,
                                                              "Line "+linenumberReader.getLineNumber()+": \"<number> <name>\" required for hierarchy names list. "
                                                              + "\nSelected probe reference file "
                                                              + probeReferenceFile.getName(),
                                                              "Wrong Hierarchy Name Format",
                                                              javax.swing.JOptionPane.WARNING_MESSAGE);
                    throw new WrongProbeReferenceFileConfig();
                }
                String name = lineString.substring(spaceIndex).trim();
                hierarchyNames[++hcount]=name;
            }
            return lineString;
    }

    /***********************************************************************************/
    /* Read next number is supposed to be a method to be called many times here. *******/
    /* However, it's really slow down the execution. So I have to inline it. ***********/
    /***********************************************************************************/
    private  void readProbes(LineNumberReader linenumberReader)throws IOException,WrongProbeLine{
        //start getting probe information
        //temporarily holding created hierarchy elements for avoiding duplication

        String lineString;
        HierarchyElements hierarchyElementArray[][]=new HierarchyElements[totalHierarchyLevels][totalHierarchyNames];
        HierarchyElements createdHierarchyElements;

        while ((lineString = linenumberReader.readLine()) != null) {
            //get probe number string
            lineString = lineString.trim();
            if (lineString.length() == 0) {
                //empty line
                continue;
            }
            char[] probeLine = lineString.toCharArray();
            int probeLineLength=probeLine.length;
            int startFrom =0;
            int current_line = linenumberReader.getLineNumber();

            //readNextNumber will have side-effect on this.startFrom

            int fileNum = 0;
            int probeNum = 0;
            int lineNum = 0;
            int columnNum = 0;

            /****************************************************************************************/
            /***************************** Read probe number ***************************************/
            int i = startFrom;
            int nextNumber = 0;

            while (i < probeLineLength) {
                if (probeLine[i] >= '0' && probeLine[i] <= '9') {
                    nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
                    ++i;
                } else
                    break;
            }

            if (i < probeLineLength) {
                if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
                    while (i < probeLineLength) {
                        if (probeLine[i] == ' ') //skip blanks
                            ++i;
                        else
                            break;
                    }
                    if (i >= probeLineLength
                        || probeLine[i] == '\r'
                        || probeLine[i] == '\n') //end of the line
                        startFrom = -1;
                    else
                        startFrom = i;
                } else
                    throw new WrongProbeLine(current_line);
            } else
                startFrom = -1;

            if (nextNumber == 0) //some non-digit char is in the probe line
                throw new WrongProbeLine(current_line);
            probeNum = nextNumber;

            /****************************************************************************************/
            /****************************** Read file number ***************************************/
            i = startFrom;
            nextNumber = 0;

            while (i < probeLineLength) {
                if (probeLine[i] >= '0' && probeLine[i] <= '9') {
                    nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
                    ++i;
                } else
                    break;
            }

            if (i < probeLineLength) {
                if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
                    while (i < probeLineLength) {
                        if (probeLine[i] == ' ') //skip blanks
                            ++i;
                        else
                            break;
                    }
                    if (i >= probeLineLength
                        || probeLine[i] == '\r'
                        || probeLine[i] == '\n') //end of the line
                        startFrom = -1;
                    else
                        startFrom = i;
                } else
                    throw new WrongProbeLine(current_line);
            } else
                startFrom = -1;

	    if (nextNumber == 0) {
	        ++deadProbes;
	        probesArray[probeNum] = new Probe(probeNum, 0, 0, 0);
	        continue; // ignore probes with 0 file number
	    }
	    
            if (nextNumber == 0) //some non-digit char is in the probe line
                throw new WrongProbeLine(current_line);
            fileNum = nextNumber;


            /****************************************************************************************/
            /****************************** Read line number ***************************************/
            i = startFrom;
            nextNumber = 0;

            while (i < probeLineLength) {
                if (probeLine[i] >= '0' && probeLine[i] <= '9') {
                    nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
                    ++i;
                } else
                    break;
            }

            if (i < probeLineLength) {
                if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
                    while (i < probeLineLength) {
                        if (probeLine[i] == ' ') //skip blanks
                            ++i;
                        else
                            break;
                    }
                    if (i >= probeLineLength
                        || probeLine[i] == '\r'
                        || probeLine[i] == '\n') //end of the line
                        startFrom = -1;
                    else
                        startFrom = i;
                } else
                    throw new WrongProbeLine(current_line);
            } else
                startFrom = -1;

            if (nextNumber == 0) //some non-digit char is in the probe line
                throw new WrongProbeLine(current_line);
            lineNum = nextNumber;

            /****************************************************************************************/
            /****************************** Read column number ***************************************/
            i = startFrom;
            nextNumber = 0;

            while (i < probeLineLength) {
                if (probeLine[i] >= '0' && probeLine[i] <= '9') {
                    nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
                    ++i;
                } else
                    break;
            }

            if (i < probeLineLength) {
                if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
                    while (i < probeLineLength) {
                        if (probeLine[i] == ' ') //skip blanks
                            ++i;
                        else
                            break;
                    }
                    if (i >= probeLineLength
                        || probeLine[i] == '\r'
                        || probeLine[i] == '\n') //end of the line
                        startFrom = -1;
                    else
                        startFrom = i;
                } else
                    throw new WrongProbeLine(current_line);
            } else
                startFrom = -1;

            if (nextNumber == 0) //some non-digit char is in the probe line
                throw new WrongProbeLine(current_line);
            columnNum = nextNumber;


            //fill in line number array           
            probesArray[probeNum] = new Probe(probeNum, lineNum, fileNum, columnNum);
            probesInFile[fileNum] = ++probesInFile[fileNum];

            //skip the end_line, end_column
            /****************************************************************************************/
            /****************************** Read end line number ***************************************/
            int indexOfSpace = lineString.indexOf(' ',startFrom);
            if (indexOfSpace<0) throw new WrongProbeLine(current_line);
            lineString = lineString.substring(indexOfSpace+1).trim();
            indexOfSpace = lineString.indexOf(' ');
            if (indexOfSpace<0) startFrom=-1;
            else {
                lineString=lineString.substring(indexOfSpace+1).trim();
                startFrom=0;
                probeLine=lineString.toCharArray();
                probeLineLength=probeLine.length;
            }

            //read hiearchy level and name pairs
            int hlevel,hname;
            String hashCodeString="";
            int indentLevel=0;

            while  (startFrom>=0){

                /****************************************************************************************/
                /****************************** Read hlevel number ***************************************/
                i = startFrom;
                nextNumber = 0;

                while (i < probeLineLength) {
                    if (probeLine[i] >= '0' && probeLine[i] <= '9') {
                        nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
                        ++i;
                    } else
                        break;
                }

                if (i < probeLineLength) {
                    if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
                        while (i < probeLineLength) {
                            if (probeLine[i] == ' ') //skip blanks
                                ++i;
                            else
                                break;
                        }
                        if (i >= probeLineLength
                            || probeLine[i] == '\r'
                            || probeLine[i] == '\n') //end of the line
                            startFrom = -1;
                        else
                            startFrom = i;
                    } else
                        throw new WrongProbeLine(current_line);
                } else
                    startFrom = -1;

                if (nextNumber == 0) //some non-digit char is in the probe line
                    throw new WrongProbeLine(current_line);
                hlevel = nextNumber;

                /****************************************************************************************/
                /****************************** Read hname ***************************************/
                i = startFrom;
                nextNumber = 0;

                while (i < probeLineLength) {
                    if (probeLine[i] >= '0' && probeLine[i] <= '9') {
                        nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
                        ++i;
                    } else
                        break;
                }

                if (i < probeLineLength) {
                    if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
                        while (i < probeLineLength) {
                            if (probeLine[i] == ' ') //skip blanks
                                ++i;
                            else
                                break;
                        }
                        if (i >= probeLineLength
                            || probeLine[i] == '\r'
                            || probeLine[i] == '\n') //end of the line
                            startFrom = -1;
                        else
                            startFrom = i;
                    } else
                        throw new WrongProbeLine(current_line);
                } else
                    startFrom = -1;

                if (nextNumber == 0) //some non-digit char is in the probe line
                    throw new WrongProbeLine(current_line);
                hname = nextNumber;

                hashCodeString=hashCodeString+hlevel+hname;
                ++indentLevel;
                HierarchyElement hElement = new HierarchyElement(hlevel,hname,indentLevel,hashCodeString);
                createdHierarchyElements = hierarchyElementArray[hlevel-1][hname-1];
                if (createdHierarchyElements==null){
                    hierarchyElementArray[hlevel-1][hname-1] = new HierarchyElements();
                    hierarchyElementArray[hlevel-1][hname-1].add(hElement);
                }else{
                    int elementIndex = createdHierarchyElements.indexOf(hElement);
                    if (elementIndex<0){
                        createdHierarchyElements.add(hElement);
                    }
                    else {
                        hElement = createdHierarchyElements.getElement(elementIndex);
                    }
                }
                ++hElement.probesInserted;
                probesArray[probeNum].addHierarchyElement(hElement);
            }
        } //end of reading probes
    }

    private void constructToplevelHierarchy(){
        //suppose the h1, h2, h3 in the hierarchy names in each probe has the containing relationship
        topLevelHierarchy = new HierarchyElements();
        for (int i=1; i<=totalProbes; ++i){
            Probe probe = probesArray[i];
            HierarchyElements hierarchy = probe.hierarchies;
            if (hierarchy.size()==0) continue;
            HierarchyElement parent = hierarchy.getElement(0);
            if (!topLevelHierarchy.contains(parent)){
                topLevelHierarchy.add(parent);
            }
            for (int j=1; j<hierarchy.size(); ++j){
                HierarchyElement child = hierarchy.getElement(j);
                if (!parent.children.contains(child)){
                    parent.children.add(child);
                }
                parent = child;
            }
        }
    }

    private void setTabulators(){
        String DMSTabulators =
            DMSTabulators = System.getenv(DMS_TABULATORS_PROPERTY);
        String domainTabName =
            "DMS_" + this.CurrentTCVDisplayDomain + "_HORIZONTAL_TABULATORS";
        String DMSDomainTabulators = System.getenv(domainTabName);
        if (DMSDomainTabulators != null && DMSDomainTabulators.length() != 0)
            DMSTabulators = DMSDomainTabulators;
        DMS_HorizontalTabulators = new HorizontalTabulators(DMSTabulators);
    }

    private void quickSortIndexArray(int[] indexArray, int min, int max, Object[] objectArray, Comparator comparator){
        if (min < max){
            int mid = (max+min)/2;
            int left=min;
            int right = max;
            int swap;

            //move pivot to maximal position
            swap = indexArray[mid];
            indexArray[mid]=indexArray[max];
            indexArray[max]=swap;

            //partition array
            //find elements greater than and less than pivot
            PARTITIONED: 
            for(;;){
                while(comparator.compare(objectArray[indexArray[left]],objectArray[indexArray[max]]) <0){
                    ++left;
                    if (left>=right)
                        break PARTITIONED;
                }
                do{
                    --right;
                    if (left>=right)
                        break PARTITIONED;
                }while(comparator.compare(objectArray[indexArray[right]],objectArray[indexArray[max]])>0);
                swap = indexArray[left];
                indexArray[left] = indexArray[right];
                indexArray[right]=swap;
            }
            //move pivot to final position
            swap = indexArray[left];
            indexArray[left] = indexArray[max];
            indexArray[max]=swap;
            quickSortIndexArray(indexArray, min, left-1, objectArray, comparator);
            quickSortIndexArray(indexArray, left+1, max, objectArray, comparator);
        }
    }


    void readProbeReferenceFile(File prf)
        throws IOException,FileNotFoundException,SecurityException,WrongProbeReferenceFileConfig,UnsupportedEncodingException,WrongProbeLine{

        System.out.println("Reading probe reference file");
        String encoding = detectEncoding(new FileInputStream(prf));

        //To reset the input stream, you have to create new FileInputStream in order to put
        //the file reset to the beginning. inputstream.reset() does not set to the beginning
        //and throws an exception. The first object new FileInputStream(probeReferenceFile)
        //will be collected by garbage collector.

        probeReferenceFile = prf;
        FileInputStream inputStream = new FileInputStream(probeReferenceFile); 

        InputStreamReader streamReader;
        try{
            streamReader = new InputStreamReader(inputStream, encoding);
        }catch(UnsupportedEncodingException ue){
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Unsupported \""+ encoding+"\" encoding in the file "+probeReferenceFile,
                                                      "Unsupported Encoding",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw ue;
        }

        LineNumberReader linenumberReader = new LineNumberReader(streamReader);

        setFilesAndProbesCountFrom(linenumberReader);

        inputStream = new FileInputStream(probeReferenceFile);
        streamReader = new InputStreamReader(inputStream,encoding);
        linenumberReader = new LineNumberReader(streamReader);
        allocateArrays();
        setTabulators();

        String lineString = null;
        //skip first 2 lines of specification config and configuratin number
        lineString = linenumberReader.readLine();
        lineString = linenumberReader.readLine();

        lineString = constructFileIndexMap(linenumberReader);

        if (lineString.startsWith("!"))
           lineString = getHierarchyNames(linenumberReader);

        System.out.println("Reading probes ...");
        readProbes(linenumberReader);
        inputStream.close();

        System.out.println("Constructing top level hierarchy ...");
        constructToplevelHierarchy();
        //java.util.Arrays.sort(this.sortedFileIndex, fileNameComparator);

        quickSortIndexArray(this.sortedFileIndex,0,this.totalFiles-1,fileIndex,stringComparator);
        computeDirectoryIndex();
        computeSubdirectories();
        System.out.println("Read probe file done.");
    }

    void computeSubdirectories(){
        this.probesInDirectoryNonrecursive = new int[this.totalDirectories];
        this.filesInDirectory = new boolean[this.totalDirectories][this.totalFiles];
        //java.util.Arrays.sort(this.sortedDirectoryIndex, directoryNameComparator);
        quickSortIndexArray(this.sortedDirectoryIndex,0,this.totalDirectories-1,directoryIndex,stringComparator);
        for (int index = 0; index < this.totalFiles; index++) {
            int file_index = this.sortedFileIndex[index];
            int dir = this.directoryOfFile[file_index];
            this.probesInDirectoryNonrecursive[dir] += this.probesInFile[file_index];
            this.filesInDirectory[dir][index] = true;
        }
        //compute subdirectory relation's for each directory using sorted directory index
        subdirectories = new boolean[this.totalDirectories][this.totalDirectories];
        for (int i = 0; i < this.totalDirectories; i++) {
            for (int j = 0; j < this.totalDirectories; j++) {
                if (i == j)
                    continue;
                if (directoryIndex[sortedDirectoryIndex[j]]
                   .startsWith(directoryIndex[sortedDirectoryIndex[i]]))
                    subdirectories[i][j] = true;
            }
        }
        probesInDirectoryRecursive = new int[totalDirectories];
        for (int i = 0; i < this.totalDirectories; i++) {
            probesInDirectoryRecursive[sortedDirectoryIndex[i]] = probesInDirectoryRecursive(i,probesInDirectoryNonrecursive);
        }
    }

    void computeDirectoryIndex(){
        int directoryCount=0;
        String canonicalFileName;
        List directoryList = new ArrayList();

        for (int fileNumber=1; fileNumber<=totalFiles; ++fileNumber){
           canonicalFileName = this.fileIndex[fileNumber];
            String currentDirectory =
                (new File(canonicalFileName)).getParentFile().getAbsolutePath();
            int index = directoryList.indexOf(currentDirectory);
            if (index < 0) {
                index = directoryCount;
                directoryList.add(index, currentDirectory);
                directoryCount++;
            }
            this.directoryOfFile[fileNumber] = index;
        } // end of for(;;)
        this.totalDirectories = directoryCount;
        this.directoryIndex = new String[this.totalDirectories];
        for (int i = 0; i < this.totalDirectories; i++) {
            this.directoryIndex[i] = (String) directoryList.get(i);
        }
        //this arrays will NOT be changed by loading TCVs, only be changed by loading
        //new probe reference file
        coveredProbesInDirectoryRecursive= new int[this.totalDirectories];
        this.sortedDirectoryIndex = new int[this.totalDirectories];
        uncoveredProbesInDirectoryRecursive= new int [this.totalDirectories];
        uncoveredPercentageInDirectoryRecursive=new float[this.totalDirectories];

        for (int i = 0; i < this.totalDirectories; i++) {
            this.sortedDirectoryIndex[i] = i;
        }

    }

    /**
     * Insert the method's description here.
     * Creation date: (12/23/2004 1:18:05 PM)
     * @return int
     * @param probeLine byte[]
     * @param startIndex java.lang.Integer
     */
//     private int readNextNumber(byte[] probeLine, int current_line)
//         throws WrongProbeLine {
// 
//         int i = this.startFrom;
//         int nextNumber = 0;
// 
//         while (i < probeLine.Length) {
//             if (probeLine[i] >= 0x30 && probeLine[i] <= 0x39) {
//                 nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
//                 ++i;
//             } else
//                 break;
//         }
// 
//         if (i < probeLine.Length) {
//             if (probeLine[i] == 0x20 || probeLine[i] == 0x0D || probeLine[i] == 0x0A) {
//                 while (i < probeLine.Length) {
//                     if (probeLine[i] == 0x20) //skip blanks
//                         ++i;
//                     else
//                         break;
//                 }
//                 if (i >= probeLine.length
//                     || probeLine[i] == 0x0D
//                     || probeLine[i] == 0x0A) //end of the line
//                     this.startFrom = -1;
//                 else
//                     this.startFrom = i;
//             } else
//                 throw new WrongProbeLine(current_line);
//         } else
//             this.startFrom = -1;
// 
//         if (nextNumber == 0) //some non-digit char is in the probe line
//             throw new WrongProbeLine(current_line);
//         return nextNumber;
//     }


    /**
     * Insert the method's description here.
     * Creation date: (12/12/2002 3:23:24 PM)
     */
    /*  As of 03/06/02:
        TCV file format described as regular expression:
        tcv_configuration_number
        (placeNumber | placeNumber1-placeNumber2 | placeNumberLetter)*
   
        TCV files are written by TestCoverage.writeTCVToFile(visitedArray, fileName)                         
    */
    /*  As of 10/09/01:
        TCV file format described as regular expression:
        (placeNumber | placeNumber1-placeNumber2 | placeNumber+)*
   
        TCV files are written by TestCoverage.writeTCVToFile(visitedArray, fileName)                         
    */
    void readTCVFile(
                     File tcvFile) throws
                         IOException,FileNotFoundException,SecurityException,UnsupportedEncodingException{

        String encoding = null;
        FileInputStream inputStream=null;
        try{
            encoding = detectEncoding(new FileInputStream(tcvFile));
            inputStream = new FileInputStream(tcvFile);
        }catch(FileNotFoundException fe){
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Can not find the file "+tcvFile
                                                      + "\nIt will be removed from the TCV list.",
                                                      "File Not Found",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw fe;
        }
        catch(SecurityException se){
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Security exception on "+tcvFile
                                                      +"\nPlease make sure you have the read access permission."
                                                      + "\nIt will be removed from the TCV list.",
                                                      "File Security Exception",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw se;
        }
        catch(IOException ie){
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                      "I/O Exception in reading File",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw ie;
        }
        InputStreamReader tcvFileReader=null;
        try{
            tcvFileReader = new InputStreamReader(inputStream, encoding);
        }catch(UnsupportedEncodingException ue){
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Unsupported \""+ encoding+"\" encoding in the file "+tcvFile,
                                                      "Unsupported Encoding",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw ue;
        }
        StreamTokenizer tokens = new StreamTokenizer(tcvFileReader);
        tokens.parseNumbers();
        tokens.ordinaryChars(65, 90);
        tokens.ordinaryChar(58);
        int next = 0;
        int start = 0, end = 0;
        int visitedCount = 1;
        //First token is configuration number
        try{
            next = tokens.nextToken();
        }catch(IOException ie){
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Line " + tokens.lineno() + ": I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                      "I/O Exception in reading File",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw ie;
        }

        long tcv_configuration_number = (long) tokens.nval;

        if (tcv_configuration_number != CONFIGURATION_NUMBER) {
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Signature Mismatch: The Test Coverage Vector file\n      "
                                                      +"\""
                                                      + tcvFile
                                                      +"\""
                                                      + "\nis for different Probe Reference File than the current\n      "
                                                      +"\""
                                                      + probeReferenceFile
                                                      +"\""
                                                      + "\nIt will be removed from the TCV list."                
                                                      +"\n\nEither wrong/old test coverage vector file or wrong/old probe reference file is loaded."
                                                      +"\nSee the Section 2.3 in TCV Display Tool documentation for details.",
                                                      "Test Coverage Vector File Signature Mismatch.",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw new IOException();
        }
        try{
            next = tokens.nextToken();
        }catch(IOException ie){
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Line " + tokens.lineno() + ": I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                      "I/O Exception in reading File",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw ie;
        }
        while (next != tokens.TT_EOF) {
            //Get start and end first
            boolean startEndDetermined = false;
            start = 0;
            end = 0;
            visitedCount = 1;
            while (!startEndDetermined) {
                int tempVal = (int) tokens.nval;
                if (next >= 'A' && next <= 'Z') {
                    if (start == 0) {
                        javax.swing.JOptionPane.showMessageDialog(
                                                                  null,
                                                                  "Line " + tokens.lineno() + ": no start for numberLetter in the TCV file "+tcvFile,
                                                                  "Wrong TCV File Format",
                                                                  javax.swing.JOptionPane.WARNING_MESSAGE);
                        throw new IOException();
                    }
                    end = start + (next - 'A') + 1;
                    startEndDetermined = true;
                    try{
                        next = tokens.nextToken();
                    }catch(IOException ie){
                        javax.swing.JOptionPane.showMessageDialog(
                                                                  null,
                                                                  "Line " + tokens.lineno() + ": I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                                  "I/O Exception in reading File",
                                                                  javax.swing.JOptionPane.WARNING_MESSAGE);
                        throw ie;
                    }
                } else
                    if (tempVal < 0) {
                        if (start == 0) {
                            javax.swing.JOptionPane.showMessageDialog(
                                                                      null,
                                                                      "Line " + tokens.lineno() + ": no start for -number in the TCV file "+tcvFile,
                                                                      "Wrong TCV File Format",
                                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
                            throw new IOException();
                        }
                        end = -tempVal;
                        startEndDetermined = true;
                        try{
                            next = tokens.nextToken();
                        }catch(IOException ie){
                            javax.swing.JOptionPane.showMessageDialog(
                                                                      null,
                                                                      "Line " + tokens.lineno() + ": I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                                      "I/O Exception in reading File",
                                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
                            throw ie;
                        }
                    } else {
                        if (start == 0) {
                            start = tempVal;
                            try{
                                next = tokens.nextToken();
                            }catch(IOException ie){
                                javax.swing.JOptionPane.showMessageDialog(
                                                                          null,
                                                                          "Line " + tokens.lineno() + ": I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                                          "I/O Exception in reading File",
                                                                          javax.swing.JOptionPane.WARNING_MESSAGE);
                                throw ie;
                            }
                        } else {
                            end = start;
                            startEndDetermined = true;
                        }
                    }
            }
            if (next == ':') {
                try{
                    next = tokens.nextToken();
                }catch(IOException ie){
                    javax.swing.JOptionPane.showMessageDialog(
                                                              null,
                                                              "Line " + tokens.lineno() + ": I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                              "I/O Exception in reading File",
                                                              javax.swing.JOptionPane.WARNING_MESSAGE);
                    throw ie;
                }
                if (next >= 'A' && next <= 'Z') {
                    visitedCount = next - 'A' + 10;
                } else {
                    visitedCount = (int) tokens.nval;
                    try{
                        next = tokens.nextToken();
                    }catch(IOException ie){
                        javax.swing.JOptionPane.showMessageDialog(
                                                                  null,
                                                                  "Line " + tokens.lineno() + ": I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                                  "I/O Exception in reading File",
                                                                  javax.swing.JOptionPane.WARNING_MESSAGE);
                        throw ie;
                    }
                }
            }
            for (int probeNo = start; probeNo <= end; ++probeNo) {
                if ((probeNo > this.totalProbes) || (probeNo <= 0)) {
                    javax.swing.JOptionPane.showMessageDialog(
                                                              null,
                                                              "Line " + tokens.lineno() + ": probe number "
                                                              + probeNo
                                                              + " is out of the valid range [1,"+this.totalProbes+"] in the TCV file" + tcvFile+"\n"
                                                              + "\nThe file will be removed from the TCV list.",
                                                              "Wrong Test Coverage Vector File.",
                                                              javax.swing.JOptionPane.WARNING_MESSAGE);

                    //remove this item from the selected tcvs list
                    throw new IOException();
                }
                if (!globalVisitedProbes[probeNo]){
                   globalVisitedProbes[probeNo] = true;
                   Probe probe = this.probesArray[probeNo];
                   probe.increaseProbesVisitedInContainingHierarchy();
                }
            }
        }
    }

    /**
     * Insert the method's description here.
     * Creation date: (3/7/02 11:16:58 AM)
     */
    void saveTCVsAction(File outputTCV) {    
        try {
            FileOutputStream outputTCVFile = new FileOutputStream(outputTCV);
            OutputStreamWriter output = new OutputStreamWriter(outputTCVFile);
            int endIndex = 0;
            int startIndex = -1;
            int writeTimes = 0;
            int arrayIndex = 1;
            int consecutive_number = 0;
            int letterBase = 'A' - 1;
            boolean firstIn = true;
            final int arraySize = globalVisitedProbes.length;
            output.write(CONFIGURATION_NUMBER + "\r\n");
            while (arrayIndex < arraySize) {
                while (globalVisitedProbes[arrayIndex]) {
                    if (firstIn) {
                        startIndex = arrayIndex;
                        firstIn = false;
                    }
                    ++arrayIndex;
                    if (arrayIndex == arraySize)
                        break;
                }
                if (startIndex > 0) {
                    firstIn = true;
                    endIndex = arrayIndex - 1;
                    consecutive_number = endIndex - startIndex;
                    ++writeTimes;
                    if (endIndex == startIndex)
                        output.write(startIndex + " ");
                    else
                        if (consecutive_number > 26)
                            output.write(startIndex + "-" + endIndex + " ");
                        else {
                            char letter = (char) (letterBase + consecutive_number);
                            output.write(startIndex + "");
                            output.write(letter + " ");
                        }
                    if (writeTimes % 10 == 0)
                        output.write("\r\n");
                    startIndex = -1;
                }
                ++arrayIndex;
            }
            output.close();
        } catch (IOException ioe) {
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Can not save file "
                                                      + outputTCV.getAbsolutePath()
                                                      + "\nPlease check if you have right permission on this file.",
                                                      "Can not save file",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
        }
    }

    /**
     * Insert the method's description here.
     * Creation date: (2/10/2003 12:32:04 PM)
     * @param stringBuffer java.lang.StringBuffer
     */

    private String untabify(char[] sourceChars, int n) {
        StringBuffer untabifiedStringBuffer = new StringBuffer(n);
        int current_index_in_target = 0;
        int line_starting_index_in_target = 0;
        int current_column_in_target = 0;
        int nextTabStop = 0;
        char[] spaces = null;
        int flushIndex = 0;
        int previousFlushIndex = 0;
        //long start = System.currentTimeMillis();
        for (int i = 0; i < n; ++i) {
            //looking for first tab
            if (sourceChars[i] == '\t') {
                if (i - flushIndex > 0) {
                    untabifiedStringBuffer.append(sourceChars, flushIndex, i);
                }
                flushIndex = i + 1;
                current_index_in_target = untabifiedStringBuffer.length();
                line_starting_index_in_target =
                    (current_index_in_target == 0) ? 0 : current_index_in_target - 1;
                while (line_starting_index_in_target > 0
                       && untabifiedStringBuffer.charAt(line_starting_index_in_target) != '\n') {
                    --line_starting_index_in_target;
                }
                current_column_in_target =
                    current_index_in_target
                    - line_starting_index_in_target
                    + (line_starting_index_in_target == 0 ? 1 : 0);
                nextTabStop =
                    DMS_HorizontalTabulators.getNextHorizontalTabulatorPosition(
                                                                                current_column_in_target);
                //System.out.println("current column = " + current_column_in_target);
                //System.out.println("next stop = " + nextTabStop);
                spaces = new char[nextTabStop - current_column_in_target];
                java.util.Arrays.fill(spaces, ' ');
                untabifiedStringBuffer.append(spaces);
                break;
            }
        }
        if (flushIndex != previousFlushIndex) {
            //first tab encountered, otherwise no tab in the text
            previousFlushIndex = flushIndex;
            for (int i = flushIndex; i < n; ++i) {
                if (sourceChars[i] == '\t') {
                    if (i - flushIndex > 0) {
                        untabifiedStringBuffer.append(sourceChars, flushIndex, i - flushIndex);
                    }
                    flushIndex = i + 1;
                    current_index_in_target = untabifiedStringBuffer.length();
                    line_starting_index_in_target = current_index_in_target - 1;
                    while (line_starting_index_in_target > 0
                           && untabifiedStringBuffer.charAt(line_starting_index_in_target) != '\n') {
                        --line_starting_index_in_target;
                    }
                    current_column_in_target =
                        current_index_in_target
                        - line_starting_index_in_target
                        + (line_starting_index_in_target == 0 ? 1 : 0);
                    nextTabStop =
                        DMS_HorizontalTabulators.getNextHorizontalTabulatorPosition(
                                                                                    current_column_in_target);
                    spaces = new char[nextTabStop - current_column_in_target];
                    java.util.Arrays.fill(spaces, ' ');
                    untabifiedStringBuffer.append(spaces);

                    if (line_starting_index_in_target != 0)
                        break;
                }
            }
            if (flushIndex != previousFlushIndex) {
                for (int i = flushIndex; i < n; ++i) {
                    if (sourceChars[i] == '\t') {
                        if (i - flushIndex > 0) {
                            untabifiedStringBuffer.append(sourceChars, flushIndex, i - flushIndex);
                        }
                        flushIndex = i + 1;
                        current_index_in_target = untabifiedStringBuffer.length();
                        line_starting_index_in_target = current_index_in_target - 1;
                        while (untabifiedStringBuffer.charAt(line_starting_index_in_target) != '\n') {
                            --line_starting_index_in_target;
                        }
                        current_column_in_target =
                            current_index_in_target - line_starting_index_in_target;
                        nextTabStop =
                            DMS_HorizontalTabulators.getNextHorizontalTabulatorPosition(
                                                                                        current_column_in_target);
                        spaces = new char[nextTabStop - current_column_in_target];
                        java.util.Arrays.fill(spaces, ' ');
                        untabifiedStringBuffer.append(spaces);
                    }
                }
            }
        }
        if (n - flushIndex > 0) {
            untabifiedStringBuffer.append(sourceChars, flushIndex, n - flushIndex);
        }

        return untabifiedStringBuffer.toString();
    }

    /**
     * Insert the method's description here.
     * Creation date: (9/23/01 2:25:09 PM)
     * @param selectedFile java.io.File
     */
    // load selected source code file into source code text area
    String loadSourceCodeFile(File selectedFile)
        throws FileNotFoundException,IOException,SecurityException{
        FileInputStream inputStream = null;
        char[] buffer;

        String  encodingString = detectEncoding(new FileInputStream(selectedFile));
        inputStream = new FileInputStream(selectedFile);
        InputStreamReader sourceCodeFile = null;
        sourceCodeFile = new InputStreamReader(inputStream, encodingString);
        //getSourceCodeJTextArea().setVisible(false);
        System.out.println("Loading file " + selectedFile + " ... ...");
        // getSourceCodeJTextArea().read(sourceCodeFile, null);
        long fileSize = selectedFile.length();
        int character_count = (int) fileSize;
        buffer = new char[character_count];
        character_count = sourceCodeFile.read(buffer, 0, character_count);
        if (inputStream != null)
            inputStream.close();
        System.out.println("Untabifying loaded file ... ...");
        return untabify(buffer, character_count);
    }

    /**
     * Insert the method's description here.
     * Creation date: (9/21/01 8:54:12 PM)
     * @return int
     */
    private void setFilesAndProbesCountFrom(LineNumberReader linenumberReader)
        throws IOException,WrongProbeReferenceFileConfig{

        int probesCount = 0;
        int filesCount = 0;
        int hierarchyNamesCount = 0;

        String lineString = null;
        //first line of prf is tool specification
        lineString = linenumberReader.readLine().trim();

        if (! isValidConfig(lineString))
            throw new WrongProbeReferenceFileConfig();

        //second line of prf is configuration number
        lineString = linenumberReader.readLine().trim();
        CONFIGURATION_NUMBER = java.lang.Long.parseLong(lineString);

        //start reading file names
        for (;;) {
            lineString = linenumberReader.readLine().trim();
            if (lineString.length() == 0)
                continue;
            if (lineString.startsWith("%%") || lineString.startsWith("!"))
                break;
            ++filesCount;
        }

        if (lineString.startsWith("!")) {
            //skip the ! started hierarchy information
            getHierarchyLevels(lineString);
            for (;;) {
                lineString = linenumberReader.readLine().trim();
                if (lineString.length() == 0)
                    continue;
                if (lineString.startsWith("%%"))
                    break;
                ++hierarchyNamesCount;
            }
        }
        while ((lineString = linenumberReader.readLine()) != null) {
            //get probe number string
            lineString = lineString.trim();
            if (lineString.length() != 0)
                ++probesCount;
        }

        totalProbes = probesCount;
        deadProbes = 0;
        totalFiles = filesCount;
        totalHierarchyNames = hierarchyNamesCount;
    }

    private void getHierarchyLevels(String line){
        //The line starts with !
        //The line is read from LineNumberReader, so it does not contains line terminaters.
        int i=0;
        int currentPos = 1; //skip the !
        int slen = line.length();
        String hierarchy_name;
        int nextSpace;

        for(;;){
            while (currentPos<slen && line.charAt(currentPos)==' ') ++currentPos;
            if (currentPos>=slen) break;
            nextSpace = line.indexOf(' ',currentPos);
            if (nextSpace<0){
                //The last one
                hierarchy_name = line.substring(currentPos);
                hierarchyLevels[++i] = hierarchy_name;
                break;
            }else{
                hierarchy_name = line.substring(currentPos,nextSpace);
                hierarchyLevels[++i] = hierarchy_name;
            }
            currentPos=nextSpace+1;
        }
        totalHierarchyLevels = i;
    }

    //called by constructUnvisitedTree
    void computeCoveredProbes(){
        this.coveredProbes = 0;
        for (int probeNo = 1; probeNo <= this.totalProbes; probeNo++) {
            int findex = this.probesArray[probeNo].fileNum;
            if (globalVisitedProbes[probeNo]) {
                this.coveredProbes++;
                this.coveredProbesInFile[findex] = ++this.coveredProbesInFile[findex];
                int dir = this.directoryOfFile[findex];
                this.coveredProbesInDirectoryNonrecursive[dir] += 1;
            }

        }
        if (!(totalProbes==deadProbes)) {
          float floatper = ((float) coveredProbes / (totalProbes-deadProbes)) * 1000;
          coveredPercentage = ((int) floatper) / (float)10.0;
        }
        else {
          coveredPercentage = (float)100.0;
        }
    }


    private int probesInDirectoryRecursive(int sortedDir,int[] probesInDirNonrecursive) {
        int dir = this.sortedDirectoryIndex[sortedDir];
        int probes = probesInDirNonrecursive[dir];
        for (int i = 0; i < this.totalDirectories; i++) {
            if (subdirectories[sortedDir][i]) {
                int probesInSubdirectory = probesInDirNonrecursive[this.sortedDirectoryIndex[i]];
                probes = probes + probesInSubdirectory;
            }
        }
        return probes;
    }

    void summarizeCoverage(){
        computeUncoverageForFiles();
        computeUncoverageForDirectoryRecursive();
    }


    private void computeUncoverageForDirectoryRecursive(){
        int uncoveredProbes;
        float uncoveredPercentage;

        for (int i = 0; i < totalDirectories; ++i) {
            int sortedDir = sortedDirectoryIndex[i];
            coveredProbesInDirectoryRecursive[sortedDir] =
                probesInDirectoryRecursive(i, coveredProbesInDirectoryNonrecursive);
            uncoveredProbes=probesInDirectoryRecursive[sortedDir]-coveredProbesInDirectoryRecursive[sortedDir];
            uncoveredPercentage =
                ((float) uncoveredProbes
                 /probesInDirectoryRecursive[sortedDir])
                * 1000;
            uncoveredPercentage = ((int) uncoveredPercentage) / (float) 10.0;            
            
            uncoveredProbesInDirectoryRecursive[sortedDir]=uncoveredProbes;
            uncoveredPercentageInDirectoryRecursive[sortedDir]=uncoveredPercentage;
        }
    }

    private void computeUncoverageForFiles(){
        int uncoveredProbes;
        float uncoveredPercentage;

        for (int i = 1; i <= totalFiles; ++i) {
            uncoveredProbes=probesInFile[i]-coveredProbesInFile[i];;
            uncoveredPercentage =
                ((float) uncoveredProbes
                 / probesInFile[i])
                * 1000;
            uncoveredPercentage = ((int) uncoveredPercentage) / (float) 10.0;

            uncoveredProbesInFile[i]= uncoveredProbes;
            uncoveredPercentageInFile[i] = uncoveredPercentage;
        }
    }
}

class WrongProbeReferenceFileConfig extends Exception{
}

Source Code after Change

This code is that same file at the next checkin with a number of changes (now 1475 lines). It is hard to see the differences by simply looking at the text, partly just from the sheer size of it. This is why you want a diff tool of some kind.
See the actual deltas generated from Java Smart Differencer.
For comparison, see deltas generated from a standard diff tool.


package DMS.Tools.TestCoverage;
import java.io.*;
import java.util.*;

class TCVModel{
    public TCVModel(){
    }

    File probeReferenceFile;
    long CONFIGURATION_NUMBER = 0;
    int[][] visitedProbeLinesInFile = null;
    Map<Integer,Set<Integer>> probesLocatedInFile = null;
    HorizontalTabulators DMS_HorizontalTabulators;
    final String DMS_TABULATORS_PROPERTY = "DMS_HORIZONTAL_TABULATORS";
    final String TOOL_NAME = "TestCoverage";
    String CurrentTCVDisplayDomain;
    String ToolVersion;
    int coveredProbes;
    float coveredPercentage;
    int totalProbes;
    int deadProbes;
    int totalFiles;
    int totalHierarchyNames;
    int totalHierarchyLevels=0;

    String[] fileIndex;
    int[] sortedFileIndex;
    int[] probesInFile;
    int[] coveredProbesInFile;
    Probe[] probesArray;
    String[] hierarchyNames;
    String hierarchyLevels[] = new String[10];
    HierarchyElements topLevelHierarchy;
    boolean globalVisitedProbes[];

    private Comparator stringComparator = new StringComparator();

    int   uncoveredProbesInFile[];
    float uncoveredPercentageInFile[];
    int   uncoveredProbesInDirectoryRecursive[];
    float uncoveredPercentageInDirectoryRecursive[];

    //for subsystem report
    int totalDirectories;
    int[] coveredProbesInDirectoryNonrecursive;
    int[] coveredProbesInDirectoryRecursive;
    int[] sortedDirectoryIndex;
    boolean[][] subdirectories;
    int[] probesInDirectoryNonrecursive;
    int[] probesInDirectoryRecursive;
    boolean[][] filesInDirectory;
    int[] directoryOfFile;
    String[] directoryIndex;

    /**
     * Insert the method's description here.
     * Creation date: (2/11/2003 2:23:33 PM)
     * @param config java.lang.String
     */
    private boolean isValidConfig(String config) {
        int end_index = config.indexOf(" ");
        if (end_index < 0) {
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "No domain name found at the first line of your prf file. \nFormat of the first line: DomainName TestCoverage VerstionNumber.",
                                                      "Invalid probe reference file",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            return false;
        }
        this.CurrentTCVDisplayDomain = config.substring(0, end_index);
        if (end_index + 1 >= config.length()) {
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "No tool name found at the first line of your prf file. \nFormat of the first line: DomainName TestCoverage VerstionNumber.",
                                                      "Invalid probe reference file",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            return false;
        }
        config = config.substring(end_index + 1).trim();
        end_index = config.indexOf(" ");
        if (end_index < 0) {
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Incomplete first line of your prf file. \nFormat of the first line: DomainName TestCoverage VerstionNumber.",
                                                      "Invalid probe reference file",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            return false;
        }
        String toolName = config.substring(0, end_index);
        if (toolName.compareTo(this.TOOL_NAME) != 0) {
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Wrong tool name found at the first line of your prf file. \nFormat of the first line: DomainName TestCoverage VerstionNumber.",
                                                      "Invalid probe reference file",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            return false;
        }
        this.ToolVersion = config.substring(end_index + 1).trim();
        return true;
    }

    private String detectEncoding(InputStream inputStream) throws IOException{
        byte[] b = new byte[2];

        final byte ff = (byte) 0xff;
        final byte fe = (byte) 0xfe;

        inputStream.read(b);

        if (b[0] == fe && b[1] == ff) {
            return "Unicode";
        }
        if (b[0] == ff && b[1] == fe) {
            return "Unicode";
        }
        return "ASCII";
    }

    private String constructFileIndexMap(LineNumberReader linenumberReader) throws IOException, WrongProbeReferenceFileConfig{
        //constructing file numbers map
        String lineString;
        String prfDirectory = probeReferenceFile.getAbsoluteFile().getParentFile().getCanonicalPath();

        for (;;) {
            lineString = linenumberReader.readLine().trim();

            //skip the empty line
            if (lineString.length() == 0)
                continue;

            //start hierarchy information list) or start the probe number section
            if (lineString.startsWith("%%") || lineString.startsWith("!"))
                break;

            int lastsubstringEnd = lineString.indexOf(" ");
            if (lastsubstringEnd <= 0)
                continue;
            String fileNumberString = lineString.substring(0, lastsubstringEnd).trim();
            int fileNumber = 0;
            try {
                fileNumber = Integer.parseInt(fileNumberString);
            } catch (NumberFormatException nfe) {
                javax.swing.JOptionPane.showMessageDialog(
                                                          null,
                                                          "Line " + linenumberReader.getLineNumber()+ ": there is number format exception on file number " + fileNumberString,
                                                          "Wrong File Number in Probe Reference File",
                                                          javax.swing.JOptionPane.WARNING_MESSAGE);
                throw nfe;    
            }
            String fileName = lineString.substring(lastsubstringEnd + 1).trim();
            String canonicalFileName = null;
            File sourceFile = new File(fileName);

            if (!sourceFile.canRead()) {
                String newFileName =
                    prfDirectory + System.getProperty("file.separator") + fileName;
                sourceFile = new File(newFileName);
            }
            if (sourceFile.canRead())
                canonicalFileName = sourceFile.getAbsolutePath();
            else {
                javax.swing.JOptionPane.showMessageDialog(
                                                          null,
                                                          "Could not open the file "
                                                          + fileName
                                                          + "\n specified in selected probe reference file "
                                                          + probeReferenceFile.getName(),
                                                          "Can not Open Source File",
                                                          javax.swing.JOptionPane.WARNING_MESSAGE);
                throw new WrongProbeReferenceFileConfig();
            }

            this.fileIndex[fileNumber] = canonicalFileName;
            this.sortedFileIndex[fileNumber - 1] = fileNumber;
        } // end of for(;;)
        return lineString;
    }

    private void allocateArrays(){
        this.probesArray = new Probe[totalProbes + 1];
        this.fileIndex = new String[totalFiles + 1];
        this.probesInFile = new int[totalFiles + 1];
        this.sortedFileIndex = new int[totalFiles];
        this.visitedProbeLinesInFile = new int[this.totalFiles + 1][];
        this.probesLocatedInFile = new HashMap<Integer,Set<Integer>>();
        this.directoryOfFile = new int[totalFiles + 1];
        uncoveredProbesInFile = new int[totalFiles + 1];
        uncoveredPercentageInFile= new float[totalFiles + 1];

        System.out.println(
                           "Total Probes in "
                           + probeReferenceFile.getName()
                           + " is "
                           + totalProbes);
        System.out.println(
                           "Total files in "
                           + probeReferenceFile.getName()
                           + " is "
                           + totalFiles);
        
        for(int i = 1; i <= totalFiles; i++) {
        	probesLocatedInFile.put(i, new HashSet<Integer>());
        }
    }

    void initializeProbes(){
        for (int i=1; i<=totalProbes; ++i){
            HierarchyElements he = probesArray[i].hierarchies;
            for (int j=0; j<he.size(); ++j){
                he.getElement(j).probesVisited=0;
            }
        }
	globalVisitedProbes = new boolean[totalProbes + 1];
	coveredProbesInFile = new int[totalFiles + 1];
        coveredProbesInDirectoryNonrecursive = new int[totalDirectories];
    }

    private String getHierarchyNames(LineNumberReader linenumberReader) throws IOException,WrongProbeReferenceFileConfig{
        //start getting hierarchy names
        String lineString;
            hierarchyNames = new String[totalHierarchyNames+1];
            int hcount = 0;
            for (;;) {
                lineString = linenumberReader.readLine().trim();

                //skip the empty line
                if (lineString.length() == 0)
                    continue;

                //start hierarchy information list) or start the probe number section
                if (lineString.startsWith("%%"))
                    break;
                int spaceIndex = lineString.indexOf(' ');
                if (spaceIndex<0){
                    javax.swing.JOptionPane.showMessageDialog(
                                                              null,
                                                              "Line "+linenumberReader.getLineNumber()+": \"<number> <name>\" required for hierarchy names list. "
                                                              + "\nSelected probe reference file "
                                                              + probeReferenceFile.getName(),
                                                              "Wrong Hierarchy Name Format",
                                                              javax.swing.JOptionPane.WARNING_MESSAGE);
                    throw new WrongProbeReferenceFileConfig();
                }
                String name = lineString.substring(spaceIndex).trim();
                hierarchyNames[++hcount]=name;
            }
            return lineString;
    }

    /***********************************************************************************/
    /* Read next number is supposed to be a method to be called many times here. *******/
    /* However, it's really slow down the execution. So I have to inline it. ***********/
    /***********************************************************************************/
    private  void readProbes(LineNumberReader linenumberReader)throws IOException,WrongProbeLine{
        //start getting probe information
        //temporarily holding created hierarchy elements for avoiding duplication
        String lineString;
        HierarchyElements hierarchyElementArray[][]=new HierarchyElements[totalHierarchyLevels][totalHierarchyNames];
        HierarchyElements createdHierarchyElements;

        while ((lineString = linenumberReader.readLine()) != null) {
            //get probe number string
            lineString = lineString.trim();
            if (lineString.length() == 0) {
                //empty line
                continue;
            }
            char[] probeLine = lineString.toCharArray();
            int probeLineLength=probeLine.length;
            int startFrom =0;
            int current_line = linenumberReader.getLineNumber();

            //readNextNumber will have side-effect on this.startFrom

            int fileNum = 0;
            int probeNum = 0;
            int lineNum = 0;
            int columnNum = 0;
            int endLineNum = 0;
            int endColumnNum = 0;

            /****************************************************************************************/
            /***************************** Read probe number ***************************************/
            int i = startFrom;
            int nextNumber = 0;

            while (i < probeLineLength) {
                if (probeLine[i] >= '0' && probeLine[i] <= '9') {
                    nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
                    ++i;
                } else
                    break;
            }

            if (i < probeLineLength) {
                if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
                    while (i < probeLineLength) {
                        if (probeLine[i] == ' ') //skip blanks
                            ++i;
                        else
                            break;
                    }
                    if (i >= probeLineLength
                        || probeLine[i] == '\r'
                        || probeLine[i] == '\n') //end of the line
                        startFrom = -1;
                    else
                        startFrom = i;
                } else
                    throw new WrongProbeLine(current_line);
            } else
                startFrom = -1;

            if (nextNumber == 0) //some non-digit char is in the probe line
                throw new WrongProbeLine(current_line);
            probeNum = nextNumber;

            /****************************************************************************************/
            /****************************** Read file number ***************************************/
            i = startFrom;
            nextNumber = 0;

            while (i < probeLineLength) {
                if (probeLine[i] >= '0' && probeLine[i] <= '9') {
                    nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
                    ++i;
                } else
                    break;
            }

            if (i < probeLineLength) {
                if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
                    while (i < probeLineLength) {
                        if (probeLine[i] == ' ') //skip blanks
                            ++i;
                        else
                            break;
                    }
                    if (i >= probeLineLength
                        || probeLine[i] == '\r'
                        || probeLine[i] == '\n') //end of the line
                        startFrom = -1;
                    else
                        startFrom = i;
                } else
                    throw new WrongProbeLine(current_line);
            } else
                startFrom = -1;

	    if (nextNumber == 0) {
	        ++deadProbes;
	        probesArray[probeNum] = new Probe(probeNum, 0, 0, 0, 0, 0);
	        continue; // ignore probes with 0 file number
	    }
	    
            if (nextNumber == 0) //some non-digit char is in the probe line
                throw new WrongProbeLine(current_line);
            fileNum = nextNumber;


            /****************************************************************************************/
            /****************************** Read line number ***************************************/
            i = startFrom;
            nextNumber = 0;

            while (i < probeLineLength) {
                if (probeLine[i] >= '0' && probeLine[i] <= '9') {
                    nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
                    ++i;
                } else
                    break;
            }

            if (i < probeLineLength) {
                if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
                    while (i < probeLineLength) {
                        if (probeLine[i] == ' ') //skip blanks
                            ++i;
                        else
                            break;
                    }
                    if (i >= probeLineLength
                        || probeLine[i] == '\r'
                        || probeLine[i] == '\n') //end of the line
                        startFrom = -1;
                    else
                        startFrom = i;
                } else
                    throw new WrongProbeLine(current_line);
            } else
                startFrom = -1;

            if (nextNumber == 0) //some non-digit char is in the probe line
                throw new WrongProbeLine(current_line);
            lineNum = nextNumber;

            /****************************************************************************************/
            /****************************** Read column number ***************************************/
            i = startFrom;
            nextNumber = 0;

            while (i < probeLineLength) {
                if (probeLine[i] >= '0' && probeLine[i] <= '9') {
                    nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
                    ++i;
                } else
                    break;
            }

            if (i < probeLineLength) {
                if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
                    while (i < probeLineLength) {
                        if (probeLine[i] == ' ') //skip blanks
                            ++i;
                        else
                            break;
                    }
                    if (i >= probeLineLength
                        || probeLine[i] == '\r'
                        || probeLine[i] == '\n') //end of the line
                        startFrom = -1;
                    else
                        startFrom = i;
                } else
                    throw new WrongProbeLine(current_line);
            } else
                startFrom = -1;

            if (nextNumber == 0) //some non-digit char is in the probe line
                throw new WrongProbeLine(current_line);
            columnNum = nextNumber;


            /****************************************************************************************/
            /****************************** Read END line number ***************************************/
            i = startFrom;
            nextNumber = 0;

            while (i < probeLineLength) {
                if (probeLine[i] >= '0' && probeLine[i] <= '9') {
                    nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
                    ++i;
                } else
                    break;
            }

            if (i < probeLineLength) {
                if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
                    while (i < probeLineLength) {
                        if (probeLine[i] == ' ') //skip blanks
                            ++i;
                        else
                            break;
                    }
                    if (i >= probeLineLength
                        || probeLine[i] == '\r'
                        || probeLine[i] == '\n') //end of the line
                        startFrom = -1;
                    else
                        startFrom = i;
                } else
                    throw new WrongProbeLine(current_line);
            } else
                startFrom = -1;

            if (nextNumber == 0) //some non-digit char is in the probe line
                throw new WrongProbeLine(current_line);
            endLineNum = nextNumber;

            /****************************************************************************************/
            /****************************** Read END column number ***************************************/
            // note: end column indicates probe region ends on the character right before end column number
            // using definition of lexeme extractor: Lexeme start and end information indicates
            //  where the first and character past the end of lexeme, respectively, are found
            //  in the source file.
            
            i = startFrom;
            nextNumber = 0;

            while (i < probeLineLength) {
                if (probeLine[i] >= '0' && probeLine[i] <= '9') {
                    nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
                    ++i;
                } else
                    break;
            }

            if (i < probeLineLength) {
                if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
                    while (i < probeLineLength) {
                        if (probeLine[i] == ' ') //skip blanks
                            ++i;
                        else
                            break;
                    }
                    if (i >= probeLineLength
                        || probeLine[i] == '\r'
                        || probeLine[i] == '\n') //end of the line
                        startFrom = -1;
                    else
                        startFrom = i;
                } else
                    throw new WrongProbeLine(current_line);
            } else
                startFrom = -1;

            if (nextNumber == 0) //some non-digit char is in the probe line
                throw new WrongProbeLine(current_line);
            endColumnNum = nextNumber;


            //fill in line number array           
            probesArray[probeNum] = new Probe(probeNum, lineNum, fileNum, columnNum, endLineNum, endColumnNum);
			probesInFile[fileNum]++;
			Set<Integer> t_probe_numbers = probesLocatedInFile.get(fileNum);
			if (t_probe_numbers==null) {
				t_probe_numbers = new TreeSet<Integer>();
				probesLocatedInFile.put(fileNum,t_probe_numbers);
			}
			t_probe_numbers.add(probeNum);

            //skip the end_line, end_column
            /****************************************************************************************/
            /****************************** Read end line number ***************************************/
//            if (false) {
//            int indexOfSpace = lineString.indexOf(' ',startFrom);
//            if (indexOfSpace<0) throw new WrongProbeLine(current_line);
//            lineString = lineString.substring(indexOfSpace+1).trim();
//            indexOfSpace = lineString.indexOf(' ');
//            if (indexOfSpace<0) startFrom=-1;
//            else {
//                lineString=lineString.substring(indexOfSpace+1).trim();
//                startFrom=0;
//                probeLine=lineString.toCharArray();
//                probeLineLength=probeLine.length;
//            }
//            }


            //read hiearchy level and name pairs
            int hlevel,hname;
            String hashCodeString="";
            int indentLevel=0;

            while  (startFrom>=0){

                /****************************************************************************************/
                /****************************** Read hlevel number ***************************************/
                i = startFrom;
                nextNumber = 0;

                while (i < probeLineLength) {
                    if (probeLine[i] >= '0' && probeLine[i] <= '9') {
                        nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
                        ++i;
                    } else
                        break;
                }

                if (i < probeLineLength) {
                    if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
                        while (i < probeLineLength) {
                            if (probeLine[i] == ' ') //skip blanks
                                ++i;
                            else
                                break;
                        }
                        if (i >= probeLineLength
                            || probeLine[i] == '\r'
                            || probeLine[i] == '\n') //end of the line
                            startFrom = -1;
                        else
                            startFrom = i;
                    } else
                        throw new WrongProbeLine(current_line);
                } else
                    startFrom = -1;

                if (nextNumber == 0) //some non-digit char is in the probe line
                    throw new WrongProbeLine(current_line);
                hlevel = nextNumber;

                /****************************************************************************************/
                /****************************** Read hname ***************************************/
                i = startFrom;
                nextNumber = 0;

                while (i < probeLineLength) {
                    if (probeLine[i] >= '0' && probeLine[i] <= '9') {
                        nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
                        ++i;
                    } else
                        break;
                }

                if (i < probeLineLength) {
                    if (probeLine[i] == ' ' || probeLine[i] == '\r' || probeLine[i] == '\n') {
                        while (i < probeLineLength) {
                            if (probeLine[i] == ' ') //skip blanks
                                ++i;
                            else
                                break;
                        }
                        if (i >= probeLineLength
                            || probeLine[i] == '\r'
                            || probeLine[i] == '\n') //end of the line
                            startFrom = -1;
                        else
                            startFrom = i;
                    } else
                        throw new WrongProbeLine(current_line);
                } else
                    startFrom = -1;

                if (nextNumber == 0) //some non-digit char is in the probe line
                    throw new WrongProbeLine(current_line);
                hname = nextNumber;

                hashCodeString=hashCodeString+hlevel+hname;
                ++indentLevel;
                HierarchyElement hElement = new HierarchyElement(hlevel,hname,indentLevel,hashCodeString);
                createdHierarchyElements = hierarchyElementArray[hlevel-1][hname-1];
                if (createdHierarchyElements==null){
                    hierarchyElementArray[hlevel-1][hname-1] = new HierarchyElements();
                    hierarchyElementArray[hlevel-1][hname-1].add(hElement);
                }else{
                    int elementIndex = createdHierarchyElements.indexOf(hElement);
                    if (elementIndex<0){
                        createdHierarchyElements.add(hElement);
                    }
                    else {
                        hElement = createdHierarchyElements.getElement(elementIndex);
                    }
                }
                ++hElement.probesInserted;
                probesArray[probeNum].addHierarchyElement(hElement);
            }
        } //end of reading probes
    }

    private void constructToplevelHierarchy(){
        //suppose the h1, h2, h3 in the hierarchy names in each probe has the containing relationship
        topLevelHierarchy = new HierarchyElements();
        for (int i=1; i<=totalProbes; ++i){
            Probe probe = probesArray[i];
            HierarchyElements hierarchy = probe.hierarchies;
            if (hierarchy.size()==0) continue;
            HierarchyElement parent = hierarchy.getElement(0);
            if (!topLevelHierarchy.contains(parent)){
                topLevelHierarchy.add(parent);
            }
            for (int j=1; j<hierarchy.size(); ++j){
                HierarchyElement child = hierarchy.getElement(j);
                if (!parent.children.contains(child)){
                    parent.children.add(child);
                }
                parent = child;
            }
        }
    }

    private void setTabulators(){
        String DMSTabulators =
            DMSTabulators = System.getenv(DMS_TABULATORS_PROPERTY);
        String domainTabName =
            "DMS_" + this.CurrentTCVDisplayDomain + "_HORIZONTAL_TABULATORS";
        String DMSDomainTabulators = System.getenv(domainTabName);
        if (DMSDomainTabulators != null && DMSDomainTabulators.length() != 0)
            DMSTabulators = DMSDomainTabulators;
        DMS_HorizontalTabulators = new HorizontalTabulators(DMSTabulators);
    }

    private void quickSortIndexArray(int[] indexArray, int min, int max, Object[] objectArray, Comparator comparator){
        if (min < max){
            int mid = (max+min)/2;
            int left=min;
            int right = max;
            int swap;

            //move pivot to maximal position
            swap = indexArray[mid];
            indexArray[mid]=indexArray[max];
            indexArray[max]=swap;

            //partition array
            //find elements greater than and less than pivot
            PARTITIONED: 
            for(;;){
                while(comparator.compare(objectArray[indexArray[left]],objectArray[indexArray[max]]) <0){
                    ++left;
                    if (left>=right)
                        break PARTITIONED;
                }
                do{
                    --right;
                    if (left>=right)
                        break PARTITIONED;
                }while(comparator.compare(objectArray[indexArray[right]],objectArray[indexArray[max]])>0);
                swap = indexArray[left];
                indexArray[left] = indexArray[right];
                indexArray[right]=swap;
            }
            //move pivot to final position
            swap = indexArray[left];
            indexArray[left] = indexArray[max];
            indexArray[max]=swap;
            quickSortIndexArray(indexArray, min, left-1, objectArray, comparator);
            quickSortIndexArray(indexArray, left+1, max, objectArray, comparator);
        }
    }


    void readProbeReferenceFile(File prf)
        throws IOException,FileNotFoundException,SecurityException,WrongProbeReferenceFileConfig,UnsupportedEncodingException,WrongProbeLine{

        System.out.println("Reading probe reference file");
        String encoding = detectEncoding(new FileInputStream(prf));

        //To reset the input stream, you have to create new FileInputStream in order to put
        //the file reset to the beginning. inputstream.reset() does not set to the beginning
        //and throws an exception. The first object new FileInputStream(probeReferenceFile)
        //will be collected by garbage collector.

        probeReferenceFile = prf;
        FileInputStream inputStream = new FileInputStream(probeReferenceFile); 

        InputStreamReader streamReader;
        try{
            streamReader = new InputStreamReader(inputStream, encoding);
        }catch(UnsupportedEncodingException ue){
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Unsupported \""+ encoding+"\" encoding in the file "+probeReferenceFile,
                                                      "Unsupported Encoding",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw ue;
        }

        LineNumberReader linenumberReader = new LineNumberReader(streamReader);

        setFilesAndProbesCountFrom(linenumberReader);

        inputStream = new FileInputStream(probeReferenceFile);
        streamReader = new InputStreamReader(inputStream,encoding);
        linenumberReader = new LineNumberReader(streamReader);
        allocateArrays();
        setTabulators();

        String lineString = null;
        //skip first 2 lines of specification config and configuratin number
        lineString = linenumberReader.readLine();
        lineString = linenumberReader.readLine();

        lineString = constructFileIndexMap(linenumberReader);

        if (lineString.startsWith("!"))
           lineString = getHierarchyNames(linenumberReader);

        System.out.println("Reading probes ...");
        readProbes(linenumberReader);
        inputStream.close();

        System.out.println("Constructing top level hierarchy ...");
        constructToplevelHierarchy();
        //java.util.Arrays.sort(this.sortedFileIndex, fileNameComparator);

        quickSortIndexArray(this.sortedFileIndex,0,this.totalFiles-1,fileIndex,stringComparator);
        computeDirectoryIndex();
        computeSubdirectories();
        System.out.println("Read probe file done.");
    }

    void computeSubdirectories(){
        this.probesInDirectoryNonrecursive = new int[this.totalDirectories];
        this.filesInDirectory = new boolean[this.totalDirectories][this.totalFiles];
        //java.util.Arrays.sort(this.sortedDirectoryIndex, directoryNameComparator);
        quickSortIndexArray(this.sortedDirectoryIndex,0,this.totalDirectories-1,directoryIndex,stringComparator);
        for (int index = 0; index < this.totalFiles; index++) {
            int file_index = this.sortedFileIndex[index];
            int dir = this.directoryOfFile[file_index];
            this.probesInDirectoryNonrecursive[dir] += this.probesInFile[file_index];
            this.filesInDirectory[dir][index] = true;
        }
        //compute subdirectory relation's for each directory using sorted directory index
        subdirectories = new boolean[this.totalDirectories][this.totalDirectories];
        for (int i = 0; i < this.totalDirectories; i++) {
            for (int j = 0; j < this.totalDirectories; j++) {
                if (i == j)
                    continue;
                if (directoryIndex[sortedDirectoryIndex[j]]
                   .startsWith(directoryIndex[sortedDirectoryIndex[i]]))
                    subdirectories[i][j] = true;
            }
        }
        probesInDirectoryRecursive = new int[totalDirectories];
        for (int i = 0; i < this.totalDirectories; i++) {
            probesInDirectoryRecursive[sortedDirectoryIndex[i]] = probesInDirectoryRecursive(i,probesInDirectoryNonrecursive);
        }
    }

    void computeDirectoryIndex(){
        int directoryCount=0;
        String canonicalFileName;
        List directoryList = new ArrayList();

        for (int fileNumber=1; fileNumber<=totalFiles; ++fileNumber){
           canonicalFileName = this.fileIndex[fileNumber];
            String currentDirectory =
                (new File(canonicalFileName)).getParentFile().getAbsolutePath();
            int index = directoryList.indexOf(currentDirectory);
            if (index < 0) {
                index = directoryCount;
                directoryList.add(index, currentDirectory);
                directoryCount++;
            }
            this.directoryOfFile[fileNumber] = index;
        } // end of for(;;)
        this.totalDirectories = directoryCount;
        this.directoryIndex = new String[this.totalDirectories];
        for (int i = 0; i < this.totalDirectories; i++) {
            this.directoryIndex[i] = (String) directoryList.get(i);
        }
        //this arrays will NOT be changed by loading TCVs, only be changed by loading
        //new probe reference file
        coveredProbesInDirectoryRecursive= new int[this.totalDirectories];
        this.sortedDirectoryIndex = new int[this.totalDirectories];
        uncoveredProbesInDirectoryRecursive= new int [this.totalDirectories];
        uncoveredPercentageInDirectoryRecursive=new float[this.totalDirectories];

        for (int i = 0; i < this.totalDirectories; i++) {
            this.sortedDirectoryIndex[i] = i;
        }

    }

    /**
     * Insert the method's description here.
     * Creation date: (12/23/2004 1:18:05 PM)
     * @return int
     * @param probeLine byte[]
     * @param startIndex java.lang.Integer
     */
//     private int readNextNumber(byte[] probeLine, int current_line)
//         throws WrongProbeLine {
// 
//         int i = this.startFrom;
//         int nextNumber = 0;
// 
//         while (i < probeLine.Length) {
//             if (probeLine[i] >= 0x30 && probeLine[i] <= 0x39) {
//                 nextNumber = nextNumber * 10 + (probeLine[i] - 0x30);
//                 ++i;
//             } else
//                 break;
//         }
// 
//         if (i < probeLine.Length) {
//             if (probeLine[i] == 0x20 || probeLine[i] == 0x0D || probeLine[i] == 0x0A) {
//                 while (i < probeLine.Length) {
//                     if (probeLine[i] == 0x20) //skip blanks
//                         ++i;
//                     else
//                         break;
//                 }
//                 if (i >= probeLine.length
//                     || probeLine[i] == 0x0D
//                     || probeLine[i] == 0x0A) //end of the line
//                     this.startFrom = -1;
//                 else
//                     this.startFrom = i;
//             } else
//                 throw new WrongProbeLine(current_line);
//         } else
//             this.startFrom = -1;
// 
//         if (nextNumber == 0) //some non-digit char is in the probe line
//             throw new WrongProbeLine(current_line);
//         return nextNumber;
//     }


    /**
     * Insert the method's description here.
     * Creation date: (12/12/2002 3:23:24 PM)
     */
    /*  As of 03/06/02:
        TCV file format described as regular expression:
        tcv_configuration_number
        (placeNumber | placeNumber1-placeNumber2 | placeNumberLetter)*
   
        TCV files are written by TestCoverage.writeTCVToFile(visitedArray, fileName)                         
    */
    /*  As of 10/09/01:
        TCV file format described as regular expression:
        (placeNumber | placeNumber1-placeNumber2 | placeNumber+)*
   
        TCV files are written by TestCoverage.writeTCVToFile(visitedArray, fileName)                         
    */
    void readTCVFile(
                     File tcvFile) throws
                         IOException,FileNotFoundException,SecurityException,UnsupportedEncodingException{

        String encoding = null;
        FileInputStream inputStream=null;
        try{
            encoding = detectEncoding(new FileInputStream(tcvFile));
            inputStream = new FileInputStream(tcvFile);
        }catch(FileNotFoundException fe){
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Can not find the file "+tcvFile
                                                      + "\nIt will be removed from the TCV list.",
                                                      "File Not Found",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw fe;
        }
        catch(SecurityException se){
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Security exception on "+tcvFile
                                                      +"\nPlease make sure you have the read access permission."
                                                      + "\nIt will be removed from the TCV list.",
                                                      "File Security Exception",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw se;
        }
        catch(IOException ie){
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                      "I/O Exception in reading File",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw ie;
        }
        InputStreamReader tcvFileReader=null;
        try{
            tcvFileReader = new InputStreamReader(inputStream, encoding);
        }catch(UnsupportedEncodingException ue){
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Unsupported \""+ encoding+"\" encoding in the file "+tcvFile,
                                                      "Unsupported Encoding",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw ue;
        }
        StreamTokenizer tokens = new StreamTokenizer(tcvFileReader);
        tokens.parseNumbers();
        tokens.ordinaryChars(65, 90);
        tokens.ordinaryChar(58);
        int next = 0;
        int start = 0, end = 0;
        int visitedCount = 1;
        //First token is configuration number
        try{
            next = tokens.nextToken();
        }catch(IOException ie){
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Line " + tokens.lineno() + ": I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                      "I/O Exception in reading File",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw ie;
        }

        long tcv_configuration_number = (long) tokens.nval;

        if (tcv_configuration_number != CONFIGURATION_NUMBER) {
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Signature Mismatch: The Test Coverage Vector file\n      "
                                                      +"\""
                                                      + tcvFile
                                                      +"\""
                                                      + "\nis for different Probe Reference File than the current\n      "
                                                      +"\""
                                                      + probeReferenceFile
                                                      +"\""
                                                      + "\nIt will be removed from the TCV list."                
                                                      +"\n\nEither wrong/old test coverage vector file or wrong/old probe reference file is loaded."
                                                      +"\nSee the Section 2.3 in TCV Display Tool documentation for details.",
                                                      "Test Coverage Vector File Signature Mismatch.",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw new IOException();
        }
        try{
            next = tokens.nextToken();
        }catch(IOException ie){
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Line " + tokens.lineno() + ": I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                      "I/O Exception in reading File",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
            throw ie;
        }
        while (next != tokens.TT_EOF) {
            //Get start and end first
            boolean startEndDetermined = false;
            start = 0;
            end = 0;
            visitedCount = 1;
            while (!startEndDetermined) {
                int tempVal = (int) tokens.nval;
                if (next >= 'A' && next <= 'Z') {
                    if (start == 0) {
                        javax.swing.JOptionPane.showMessageDialog(
                                                                  null,
                                                                  "Line " + tokens.lineno() + ": no start for numberLetter in the TCV file "+tcvFile,
                                                                  "Wrong TCV File Format",
                                                                  javax.swing.JOptionPane.WARNING_MESSAGE);
                        throw new IOException();
                    }
                    end = start + (next - 'A') + 1;
                    startEndDetermined = true;
                    try{
                        next = tokens.nextToken();
                    }catch(IOException ie){
                        javax.swing.JOptionPane.showMessageDialog(
                                                                  null,
                                                                  "Line " + tokens.lineno() + ": I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                                  "I/O Exception in reading File",
                                                                  javax.swing.JOptionPane.WARNING_MESSAGE);
                        throw ie;
                    }
                } else
                    if (tempVal < 0) {
                        if (start == 0) {
                            javax.swing.JOptionPane.showMessageDialog(
                                                                      null,
                                                                      "Line " + tokens.lineno() + ": no start for -number in the TCV file "+tcvFile,
                                                                      "Wrong TCV File Format",
                                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
                            throw new IOException();
                        }
                        end = -tempVal;
                        startEndDetermined = true;
                        try{
                            next = tokens.nextToken();
                        }catch(IOException ie){
                            javax.swing.JOptionPane.showMessageDialog(
                                                                      null,
                                                                      "Line " + tokens.lineno() + ": I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                                      "I/O Exception in reading File",
                                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
                            throw ie;
                        }
                    } else {
                        if (start == 0) {
                            start = tempVal;
                            try{
                                next = tokens.nextToken();
                            }catch(IOException ie){
                                javax.swing.JOptionPane.showMessageDialog(
                                                                          null,
                                                                          "Line " + tokens.lineno() + ": I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                                          "I/O Exception in reading File",
                                                                          javax.swing.JOptionPane.WARNING_MESSAGE);
                                throw ie;
                            }
                        } else {
                            end = start;
                            startEndDetermined = true;
                        }
                    }
            }
            if (next == ':') {
                try{
                    next = tokens.nextToken();
                }catch(IOException ie){
                    javax.swing.JOptionPane.showMessageDialog(
                                                              null,
                                                              "Line " + tokens.lineno() + ": I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                              "I/O Exception in reading File",
                                                              javax.swing.JOptionPane.WARNING_MESSAGE);
                    throw ie;
                }
                if (next >= 'A' && next <= 'Z') {
                    visitedCount = next - 'A' + 10;
                } else {
                    visitedCount = (int) tokens.nval;
                    try{
                        next = tokens.nextToken();
                    }catch(IOException ie){
                        javax.swing.JOptionPane.showMessageDialog(
                                                                  null,
                                                                  "Line " + tokens.lineno() + ": I/O exception in reading the file "+tcvFile + "\nPlease make sure you have the file is not broken.",
                                                                  "I/O Exception in reading File",
                                                                  javax.swing.JOptionPane.WARNING_MESSAGE);
                        throw ie;
                    }
                }
            }
            for (int probeNo = start; probeNo <= end; ++probeNo) {
                if ((probeNo > this.totalProbes) || (probeNo <= 0)) {
                    javax.swing.JOptionPane.showMessageDialog(
                                                              null,
                                                              "Line " + tokens.lineno() + ": probe number "
                                                              + probeNo
                                                              + " is out of the valid range [1,"+this.totalProbes+"] in the TCV file" + tcvFile+"\n"
                                                              + "\nThe file will be removed from the TCV list.",
                                                              "Wrong Test Coverage Vector File.",
                                                              javax.swing.JOptionPane.WARNING_MESSAGE);

                    //remove this item from the selected tcvs list
                    throw new IOException();
                }
                if (!globalVisitedProbes[probeNo]){
                   globalVisitedProbes[probeNo] = true;
                   Probe probe = this.probesArray[probeNo];
                   probe.increaseProbesVisitedInContainingHierarchy();
                }
            }
        }
    }

    /**
     * Insert the method's description here.
     * Creation date: (3/7/02 11:16:58 AM)
     */
    void saveTCVsAction(File outputTCV) {    
        try {
            FileOutputStream outputTCVFile = new FileOutputStream(outputTCV);
            OutputStreamWriter output = new OutputStreamWriter(outputTCVFile);
            int endIndex = 0;
            int startIndex = -1;
            int writeTimes = 0;
            int arrayIndex = 1;
            int consecutive_number = 0;
            int letterBase = 'A' - 1;
            boolean firstIn = true;
            final int arraySize = globalVisitedProbes.length;
            output.write(CONFIGURATION_NUMBER + "\r\n");
            while (arrayIndex < arraySize) {
                while (globalVisitedProbes[arrayIndex]) {
                    if (firstIn) {
                        startIndex = arrayIndex;
                        firstIn = false;
                    }
                    ++arrayIndex;
                    if (arrayIndex == arraySize)
                        break;
                }
                if (startIndex > 0) {
                    firstIn = true;
                    endIndex = arrayIndex - 1;
                    consecutive_number = endIndex - startIndex;
                    ++writeTimes;
                    if (endIndex == startIndex)
                        output.write(startIndex + " ");
                    else
                        if (consecutive_number > 26)
                            output.write(startIndex + "-" + endIndex + " ");
                        else {
                            char letter = (char) (letterBase + consecutive_number);
                            output.write(startIndex + "");
                            output.write(letter + " ");
                        }
                    if (writeTimes % 10 == 0)
                        output.write("\r\n");
                    startIndex = -1;
                }
                ++arrayIndex;
            }
            output.close();
        } catch (IOException ioe) {
            javax.swing.JOptionPane.showMessageDialog(
                                                      null,
                                                      "Can not save file "
                                                      + outputTCV.getAbsolutePath()
                                                      + "\nPlease check if you have right permission on this file.",
                                                      "Can not save file",
                                                      javax.swing.JOptionPane.WARNING_MESSAGE);
        }
    }

    /**
     * Insert the method's description here.
     * Creation date: (2/10/2003 12:32:04 PM)
     * @param stringBuffer java.lang.StringBuffer
     */

    private String untabify(char[] sourceChars, int n) {
        StringBuffer untabifiedStringBuffer = new StringBuffer(n);
        int current_index_in_target = 0;
        int line_starting_index_in_target = 0;
        int current_column_in_target = 0;
        int nextTabStop = 0;
        char[] spaces = null;
        int flushIndex = 0;
        int previousFlushIndex = 0;
        //long start = System.currentTimeMillis();
        for (int i = 0; i < n; ++i) {
            //looking for first tab
            if (sourceChars[i] == '\t') {
                if (i - flushIndex > 0) {
                    untabifiedStringBuffer.append(sourceChars, flushIndex, i);
                }
                flushIndex = i + 1;
                current_index_in_target = untabifiedStringBuffer.length();
                line_starting_index_in_target =
                    (current_index_in_target == 0) ? 0 : current_index_in_target - 1;
                while (line_starting_index_in_target > 0
                       && untabifiedStringBuffer.charAt(line_starting_index_in_target) != '\n') {
                    --line_starting_index_in_target;
                }
                current_column_in_target =
                    current_index_in_target
                    - line_starting_index_in_target
                    + (line_starting_index_in_target == 0 ? 1 : 0);
                nextTabStop =
                    DMS_HorizontalTabulators.getNextHorizontalTabulatorPosition(
                                                                                current_column_in_target);
                //System.out.println("current column = " + current_column_in_target);
                //System.out.println("next stop = " + nextTabStop);
                spaces = new char[nextTabStop - current_column_in_target];
                java.util.Arrays.fill(spaces, ' ');
                untabifiedStringBuffer.append(spaces);
                break;
            }
        }
        if (flushIndex != previousFlushIndex) {
            //first tab encountered, otherwise no tab in the text
            previousFlushIndex = flushIndex;
            for (int i = flushIndex; i < n; ++i) {
                if (sourceChars[i] == '\t') {
                    if (i - flushIndex > 0) {
                        untabifiedStringBuffer.append(sourceChars, flushIndex, i - flushIndex);
                    }
                    flushIndex = i + 1;
                    current_index_in_target = untabifiedStringBuffer.length();
                    line_starting_index_in_target = current_index_in_target - 1;
                    while (line_starting_index_in_target > 0
                           && untabifiedStringBuffer.charAt(line_starting_index_in_target) != '\n') {
                        --line_starting_index_in_target;
                    }
                    current_column_in_target =
                        current_index_in_target
                        - line_starting_index_in_target
                        + (line_starting_index_in_target == 0 ? 1 : 0);
                    nextTabStop =
                        DMS_HorizontalTabulators.getNextHorizontalTabulatorPosition(
                                                                                    current_column_in_target);
                    spaces = new char[nextTabStop - current_column_in_target];
                    java.util.Arrays.fill(spaces, ' ');
                    untabifiedStringBuffer.append(spaces);

                    if (line_starting_index_in_target != 0)
                        break;
                }
            }
            if (flushIndex != previousFlushIndex) {
                for (int i = flushIndex; i < n; ++i) {
                    if (sourceChars[i] == '\t') {
                        if (i - flushIndex > 0) {
                            untabifiedStringBuffer.append(sourceChars, flushIndex, i - flushIndex);
                        }
                        flushIndex = i + 1;
                        current_index_in_target = untabifiedStringBuffer.length();
                        line_starting_index_in_target = current_index_in_target - 1;
                        while (untabifiedStringBuffer.charAt(line_starting_index_in_target) != '\n') {
                            --line_starting_index_in_target;
                        }
                        current_column_in_target =
                            current_index_in_target - line_starting_index_in_target;
                        nextTabStop =
                            DMS_HorizontalTabulators.getNextHorizontalTabulatorPosition(
                                                                                        current_column_in_target);
                        spaces = new char[nextTabStop - current_column_in_target];
                        java.util.Arrays.fill(spaces, ' ');
                        untabifiedStringBuffer.append(spaces);
                    }
                }
            }
        }
        if (n - flushIndex > 0) {
            untabifiedStringBuffer.append(sourceChars, flushIndex, n - flushIndex);
        }

        return untabifiedStringBuffer.toString();
    }

    /**
     * Insert the method's description here.
     * Creation date: (9/23/01 2:25:09 PM)
     * @param selectedFile java.io.File
     */
    // load selected source code file into source code text area
    String loadSourceCodeFile(File selectedFile)
        throws FileNotFoundException,IOException,SecurityException{
        FileInputStream inputStream = null;
        char[] buffer;

        String  encodingString = detectEncoding(new FileInputStream(selectedFile));
        inputStream = new FileInputStream(selectedFile);
        InputStreamReader sourceCodeFile = null;
        sourceCodeFile = new InputStreamReader(inputStream, encodingString);
        //getSourceCodeJTextArea().setVisible(false);
        System.out.println("Loading file " + selectedFile + " ... ...");
        // getSourceCodeJTextArea().read(sourceCodeFile, null);
        long fileSize = selectedFile.length();
        int character_count = (int) fileSize;
        buffer = new char[character_count];
        character_count = sourceCodeFile.read(buffer, 0, character_count);
        if (inputStream != null)
            inputStream.close();
        System.out.println("Untabifying loaded file ... ...");
        return untabify(buffer, character_count);
    }

    /**
     * Insert the method's description here.
     * Creation date: (9/21/01 8:54:12 PM)
     * @return int
     */
    private void setFilesAndProbesCountFrom(LineNumberReader linenumberReader)
        throws IOException,WrongProbeReferenceFileConfig{

        int probesCount = 0;
        int filesCount = 0;
        int hierarchyNamesCount = 0;

        String lineString = null;
        //first line of prf is tool specification
        lineString = linenumberReader.readLine().trim();

        if (! isValidConfig(lineString))
            throw new WrongProbeReferenceFileConfig();

        //second line of prf is configuration number
        lineString = linenumberReader.readLine().trim();
        CONFIGURATION_NUMBER = java.lang.Long.parseLong(lineString);

        //start reading file names
        for (;;) {
            lineString = linenumberReader.readLine().trim();
            if (lineString.length() == 0)
                continue;
            if (lineString.startsWith("%%") || lineString.startsWith("!"))
                break;
            ++filesCount;
        }

        if (lineString.startsWith("!")) {
            //skip the ! started hierarchy information
            getHierarchyLevels(lineString);
            for (;;) {
                lineString = linenumberReader.readLine().trim();
                if (lineString.length() == 0)
                    continue;
                if (lineString.startsWith("%%"))
                    break;
                ++hierarchyNamesCount;
            }
        }
        while ((lineString = linenumberReader.readLine()) != null) {
            //get probe number string
            lineString = lineString.trim();
            if (lineString.length() != 0)
                ++probesCount;
        }

        totalProbes = probesCount;
        deadProbes = 0;
        totalFiles = filesCount;
        totalHierarchyNames = hierarchyNamesCount;
    }

    private void getHierarchyLevels(String line){
        //The line starts with !
        //The line is read from LineNumberReader, so it does not contains line terminaters.
        int i=0;
        int currentPos = 1; //skip the !
        int slen = line.length();
        String hierarchy_name;
        int nextSpace;

        for(;;){
            while (currentPos<slen && line.charAt(currentPos)==' ') ++currentPos;
            if (currentPos>=slen) break;
            nextSpace = line.indexOf(' ',currentPos);
            if (nextSpace<0){
                //The last one
                hierarchy_name = line.substring(currentPos);
                hierarchyLevels[++i] = hierarchy_name;
                break;
            }else{
                hierarchy_name = line.substring(currentPos,nextSpace);
                hierarchyLevels[++i] = hierarchy_name;
            }
            currentPos=nextSpace+1;
        }
        totalHierarchyLevels = i;
    }

    //called by constructUnvisitedTree
    void computeCoveredProbes(){
        this.coveredProbes = 0;
        for (int probeNo = 1; probeNo <= this.totalProbes; probeNo++) {
            int findex = this.probesArray[probeNo].fileNum;
            if (globalVisitedProbes[probeNo]) {
                this.coveredProbes++;
                this.coveredProbesInFile[findex] = ++this.coveredProbesInFile[findex];
                int dir = this.directoryOfFile[findex];
                this.coveredProbesInDirectoryNonrecursive[dir] += 1;
            }

        }
        if (!(totalProbes==deadProbes)) {
          float floatper = ((float) coveredProbes / (totalProbes-deadProbes)) * 1000;
          coveredPercentage = ((int) floatper) / (float)10.0;
        }
        else {
          coveredPercentage = (float)100.0;
        }
    }


    private int probesInDirectoryRecursive(int sortedDir,int[] probesInDirNonrecursive) {
        int dir = this.sortedDirectoryIndex[sortedDir];
        int probes = probesInDirNonrecursive[dir];
        for (int i = 0; i < this.totalDirectories; i++) {
            if (subdirectories[sortedDir][i]) {
                int probesInSubdirectory = probesInDirNonrecursive[this.sortedDirectoryIndex[i]];
                probes = probes + probesInSubdirectory;
            }
        }
        return probes;
    }

    void summarizeCoverage(){
        computeUncoverageForFiles();
        computeUncoverageForDirectoryRecursive();
    }


    private void computeUncoverageForDirectoryRecursive(){
        int uncoveredProbes;
        float uncoveredPercentage;

        for (int i = 0; i < totalDirectories; ++i) {
            int sortedDir = sortedDirectoryIndex[i];
            coveredProbesInDirectoryRecursive[sortedDir] =
                probesInDirectoryRecursive(i, coveredProbesInDirectoryNonrecursive);
            uncoveredProbes=probesInDirectoryRecursive[sortedDir]-coveredProbesInDirectoryRecursive[sortedDir];
            uncoveredPercentage =
                ((float) uncoveredProbes
                 /probesInDirectoryRecursive[sortedDir])
                * 1000;
            uncoveredPercentage = ((int) uncoveredPercentage) / (float) 10.0;            
            
            uncoveredProbesInDirectoryRecursive[sortedDir]=uncoveredProbes;
            uncoveredPercentageInDirectoryRecursive[sortedDir]=uncoveredPercentage;
        }
    }

    private void computeUncoverageForFiles(){
        int uncoveredProbes;
        float uncoveredPercentage;

        for (int i = 1; i <= totalFiles; ++i) {
            uncoveredProbes=probesInFile[i]-coveredProbesInFile[i];;
            uncoveredPercentage =
                ((float) uncoveredProbes
                 / probesInFile[i])
                * 1000;
            uncoveredPercentage = ((int) uncoveredPercentage) / (float) 10.0;

            uncoveredProbesInFile[i]= uncoveredProbes;
            uncoveredPercentageInFile[i] = uncoveredPercentage;
        }
    }
}

class WrongProbeReferenceFileConfig extends Exception{
}
For more information: [email protected]    Follow us at Twitter: @SemanticDesigns

Java Smart Differencer
Example