@Override
  public Object getValueAt(int rowIndex, int columnIndex) {

    Precondition.param(rowIndex, "rowIndex").noLessThan(0);
    Precondition.param(rowIndex, "rowIndex").lessThan(getRowCount());
    Precondition.param(columnIndex, "columnIndex").noLessThan(0);
    Precondition.param(columnIndex, "columnIndex").lessThan(getColumnCount());

    AudioFile audioFile = audioFileCollection.get(rowIndex);
    if (columnIndex < AudioFileAccess.values().length) {
      return AudioFileAccess.values()[columnIndex].get(audioFile);
    } else {
      AudioTagField audioTagField =
          AudioTagField.values()[columnIndex - AudioFileAccess.values().length];
      return audioFile.getTag().getField(audioTagField);
    }
  }
  @Override
  public void setValueAt(Object aValue, int rowIndex, int columnIndex) {

    Precondition.param(rowIndex, "rowIndex").noLessThan(0);
    Precondition.param(rowIndex, "rowIndex").lessThan(getRowCount());
    Precondition.param(columnIndex, "columnIndex").noLessThan(0);
    Precondition.param(columnIndex, "columnIndex").lessThan(getColumnCount());
    Precondition.assertParam(
        isCellEditable(rowIndex, columnIndex),
        "Cell not editable: " + rowIndex + "," + columnIndex);

    AudioFile audioFile = audioFileCollection.get(rowIndex);
    if (columnIndex < AudioFileAccess.values().length) {
      AudioFileAccess.values()[columnIndex].set(audioFile, aValue);
    } else {
      AudioTagField audioTagField =
          AudioTagField.values()[columnIndex - AudioFileAccess.values().length];
      audioFile.getTag().setField(audioTagField, aValue);
    }
    super.fireTableRowsUpdated(rowIndex, rowIndex);
  }
  @Override
  public int getRowCount() {

    return audioFileCollection.size();
  }