/*
 * JMockit Coverage
 * Copyright (c) 2006-2009 Rogério Liesenfeld
 * All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package mockit.coverage.reporting;

import java.io.*;

import mockit.coverage.*;
import mockit.coverage.reporting.codeCoverage.*;
import mockit.coverage.reporting.parsing.*;
import mockit.coverage.reporting.pathCoverage.*;

/**
 * Generates an XHTML page containing line-by-line coverage information for a single source file.
 */
final class FileCoverageReport
{
   private final InputFile inputFile;
   private final OutputFile output;
   private final LineParser lineParser = new LineParser();
   private final CodeCoverageOutput codeCoverage;
   private final PathCoverageOutput pathCoverage;

   FileCoverageReport(
      String outputDir, InputFile inputFile, String sourceFilePath, FileCoverageData fileData,
      boolean withCallPoints) throws IOException
   {
      this.inputFile = inputFile;
      output = new OutputFile(outputDir, sourceFilePath);
      codeCoverage = new CodeCoverageOutput(output, fileData.getLineToLineData(), withCallPoints);
      pathCoverage = new PathCoverageOutput(output, fileData.getMethods());
   }

   void generate() throws IOException
   {
      try {
         writeHeader();
         writeFormattedSourceLines();
         writeFooter();
      }
      finally {
         inputFile.input.close();
         output.close();
      }
   }

   private void writeHeader()
   {
      output.printCommonHeader(true);
      output.println("  <table cellpadding='0' cellspacing='1'>");
      output.println("    <caption><code>" + inputFile.sourceFile.getPath() + "</code></caption>");
   }

   private void writeFormattedSourceLines() throws IOException
   {
      String line;

      while ((line = inputFile.input.readLine()) != null) {
         lineParser.parse(line);

         if (!lineParser.isInComments()) {
            pathCoverage.writePathCoverageInfoIfLineStartsANewMethodOrConstructor(lineParser);
         }

         codeCoverage.writeLineOfSourceCodeWithCoverageInfo(lineParser);
      }
   }

   private void writeFooter()
   {
      output.println("  </table>");
      output.writeCommonFooter();
   }
}

@@ -1248,16 +1248,37 @@
 a.io.*;%0D
+%0Aimport java.util.*;%0D
 %0A%0D%0Aimpor
@@ -1291,32 +1291,65 @@
 it.coverage.*;%0D%0A
+import mockit.coverage.paths.*;%0D%0A
 import mockit.co
@@ -2237,28 +2237,128 @@
 );%0D%0A
-      pathCoverage =
+%0D%0A      Collection%3CMethodCoverageData%3E methods = fileData.getMethods();%0D%0A      pathCoverage = methods.isEmpty() ? null :
  new
@@ -2385,37 +2385,23 @@
 output, 
-fileData.getM
+m
 ethods
-()
 );%0D%0A   %7D
@@ -3093,24 +3093,24 @@
 e(line);%0D%0A%0D%0A
-
          if 
@@ -3110,16 +3110,40 @@
     if (
+pathCoverage != null && 
 !linePar

Fix for interfaces, for which no method data items are created.