I'm working on an extension, and I ran into an issue getting a cell by index when that index is computed by column name, e.g.
int cellIndex = project.columnModel.getColumnIndexByName(columnName);
Cell cell = project.rows.get(0).getCell(cellIndex);
When I try did this after removing a column via RemoveColumnCommand, project.columnModel.getColumnNames() doesn't return the name of the removed column (as expected), but in each row, the cell value is null at the index of the removed column (see ColumnRemovalChange). So getColumnIndexByName(columnName) returns 2, but the cell index for that data is actually at index 3 in Row.cells.
Yes, cell indices are a confusing aspect of our architecture.
With .getColumnIndexByName(columnName) you are only getting the index of the column in the current list of columns - that's different from the index of its cells in each row, which you can get with .getColumnByName(columnName).getCellIndex(). It's easy to confuse the two!
This system of cell indices was introduced to avoid having to shuffle values and resize lists on many rows when inserting columns. In 4.0 there is no distinction between those indices anymore: rows contain cells in the same order as the columns they belong to, without gaps. The shuffling and resizing this induces is less of a concern given that they are executed lazily.