public Table parseFile() throws IOException, ArrayIndexOutOfBoundsException {
    // initialize buffered reader for parsing the file
    BufferedReader br = new BufferedReader(new FileReader(this.file));
    // skip lines before parsing
    for (int i = 0; i < linesToSkip; i++)
      br.readLine();
    // parse first line to get columns number
    String line = br.readLine();
    String[] firstLine = parseLine(line, false);
    // create new table and add all columns
    Table table = new Table();
    table.addColumns(firstLine.length - Table.DEFAULT_COLS);
    // if row header parsing is enabled, rename all columns
    // else fill first row
    for (int i = 0; i < firstLine.length; i++)
    {
      if (this.parsingRowHeaders) table.setColumnName(i, firstLine[i]);
      else table.set(i, 0, firstLine[i]);
    }
    // initialize variables for convenience
    int row = parsingRowHeaders ? 0 : 1;
    String[] tokens;
    // parse remaining line in the file
    while ((line = br.readLine()) != null)
    {
      // parse current line and check if element number is equal to columns
      tokens = parseLine(line, false);
      if (tokens.length != table.columns()) throw new IOException(
                "Number of elements on line " + row
                + "not compatible with parsing.");
      // add new row at the end of the table and set elements
      table.addRow();
      for (int i = 0; i < tokens.length; i++)
        table.set(i, row, tokens[i]);
      // update row number
      row++;
    }
    // trim number of rows
    table.removeRows(row, table.rows() - row);
    // try to convert table columns to numeric values
    for (int i = 0; i < table.columns(); i++)
      if (table.isColumnConvertible(i, DataTypes.NUMERIC))
        table.convertColumn(i, DataTypes.NUMERIC);
    // close and return the table
    br.close();
    return table;
  }