/**
   * Print the data in the given table to this writer. The table is an array of rows, where each row
   * is an array of cell values. The size of each row must be the same. The array of column
   * alignments indicates how the cell values are to be aligned within the columns. The values must
   * be one of the following constants: {@link #ALIGN_LEFT} or {@link #ALIGN_RIGHT}.
   *
   * @return the text that has been written to this writer
   */
  public void printTable(String[][] data, int[] columnAlignments) {
    int rowCount, columnCount, padCount;
    int[] columnWidths;

    rowCount = data.length;
    columnCount = data[0].length;
    columnWidths = new int[columnCount];
    for (int i = 0; i < rowCount; i++) {
      for (int j = 0; j < columnCount; j++) {
        columnWidths[j] = Math.max(columnWidths[j], data[i][j].length());
      }
    }
    for (int i = 0; i < rowCount; i++) {
      for (int j = 0; j < columnCount; j++) {
        padCount = columnWidths[j] - data[i][j].length();
        if (columnAlignments[j] == ALIGN_RIGHT) {
          for (int k = 0; k < padCount; k++) {
            print(' ');
          }
        }
        print(data[i][j]);
        if (columnAlignments[j] == ALIGN_LEFT) {
          for (int k = 0; k < padCount; k++) {
            print(' ');
          }
        }
      }
      println();
    }
  }
  /**
   * Print the given value in a field of the given width. If the length required by the value is
   * greater than the field width, then the field width and alignment will be ignored. Otherwise,
   * the alignment will be used to determine whether the spaces used to pad the value to the given
   * field width will be placed on the left or the right.
   *
   * @param value the value to be printed
   * @param fieldWidth the width of the field in which it is to be printed
   * @param alignment the alignment of the value in the field
   */
  public void print(String value, int fieldWidth, int alignment) {
    int padding;

    padding = fieldWidth - value.length();
    if (padding > 0) {
      if (alignment == ALIGN_LEFT) {
        print(value);
        for (int i = 0; i < padding; i++) {
          print(' ');
        }
      } else {
        for (int i = 0; i < padding; i++) {
          print(' ');
        }
        print(value);
      }
    } else {
      print(value);
    }
  }
 /** Assert that the Eclipse .log file does not exist. */
 public static void assertNoLogFile() {
   File logFile = getLogFile();
   if (logFile.exists()) {
     PrintStringWriter writer = new PrintStringWriter();
     try {
       String contents = FileUtilities.getContents(logFile);
       writer.println("Non-empty log file. Log file contents:");
       writer.println();
       writer.print(contents);
     } catch (IOException exception) {
       writer.println("Non-empty log file. Could not access contents of log file.");
       writer.println();
       exception.printStackTrace(writer);
     }
     Assert.fail(writer.toString());
   }
 }
 /**
  * Print the given value the given number of times.
  *
  * @param count the number of times the value is to be printed
  * @param value the value to be written
  */
 public void printMultiple(int count, String value) {
   for (int i = 0; i < count; i++) {
     print(value);
   }
 }
 /**
  * Print the given value in a field of the given width. If the length required by the value is
  * greater than the field width, then the field width and alignment will be ignored. Otherwise,
  * the alignment will be used to determine whether the spaces used to pad the value to the given
  * field width will be placed on the left or the right.
  *
  * @param value the value to be printed
  * @param fieldWidth the width of the field in which it is to be printed
  * @param alignment the alignment of the value in the field
  */
 public void print(int value, int fieldWidth, int alignment) {
   print(Integer.toString(value), fieldWidth, alignment);
 }
 /**
  * Assert that the number of errors that have been gathered matches the number of errors that are
  * given and that they have the expected error codes. The order in which the errors were gathered
  * is ignored.
  *
  * @param errorCodes the errors that should have been gathered
  * @throws AssertionFailedError with
  */
 private void fail(AnalysisError[] expectedErrors) {
   PrintStringWriter writer = new PrintStringWriter();
   writer.print("Expected ");
   writer.print(expectedErrors.length);
   writer.print(" errors:");
   for (AnalysisError error : expectedErrors) {
     Source source = error.getSource();
     File file = source == null ? null : source.getFile();
     LineInfo lineInfo = lineInfoMap.get(source);
     writer.println();
     if (lineInfo == null) {
       int offset = error.getOffset();
       writer.printf(
           "  %s %s (%d..%d)",
           file == null ? "" : file.getName(),
           error.getErrorCode(),
           offset,
           offset + error.getLength());
     } else {
       LineInfo.Location location = lineInfo.getLocation(error.getOffset());
       writer.printf(
           "  %s %s (%d, %d/%d)",
           source == null ? "" : source.getFile().getName(),
           error.getErrorCode(),
           location.getLineNumber(),
           location.getColumnNumber(),
           error.getLength());
     }
   }
   writer.println();
   writer.print("found ");
   writer.print(errors.size());
   writer.print(" errors:");
   for (AnalysisError error : errors) {
     Source source = error.getSource();
     File file = source == null ? null : source.getFile();
     LineInfo lineInfo = lineInfoMap.get(source);
     writer.println();
     if (lineInfo == null) {
       int offset = error.getOffset();
       writer.printf(
           "  %s %s (%d..%d): %s",
           file == null ? "" : file.getName(),
           error.getErrorCode(),
           offset,
           offset + error.getLength(),
           error.getMessage());
     } else {
       LineInfo.Location location = lineInfo.getLocation(error.getOffset());
       writer.printf(
           "  %s %s (%d, %d/%d): %s",
           source == null ? "" : source.getFile().getName(),
           error.getErrorCode(),
           location.getLineNumber(),
           location.getColumnNumber(),
           error.getLength(),
           error.getMessage());
     }
   }
   Assert.fail(writer.toString());
 }