private List<RowLayout> alignRows(RowHeights sharedRowHeights,
			Map<Integer, List<RowLayout>> layoutsByRow) {

		List<RowLayout> updatedRows = new ArrayList<>();
		int totalRows = sharedRowHeights.getRowCount(); // total rows shared between all views
		for (int row = 0; row < totalRows; row++) {
			int rowHeight = sharedRowHeights.getHeight(row);
			if (rowHeight == 0) {
				continue; // no rows on either side
			}

			List<RowLayout> rowLayouts = layoutsByRow.get(row);
			if (rowLayouts == null) {
				// No lines for this row.  This side of the diff that has no rows fields for the 
				// given row.  Add empty rows to act as spacers for this side of the diff.
				updatedRows.add(new EmptyRowLayout(row, rowHeight));
				continue;
			}

			// At this point we have one or more lines to add for the current row.  Add each line
			// but the last line.  The last line will consume all remaining height that has not yet
			// been consumed.
			int totalLines = rowLayouts.size();
			int lastLine = totalLines - 1;
			int allButLastLine = lastLine - 1;
			int consumedHeight = 0; // track all height used by each row
			for (int line = 0; line <= allButLastLine; line++) {
				RowLayout layout = rowLayouts.get(line);
				updatedRows.add(layout);
				consumedHeight += layout.getHeight();
			}

			// Process the last line, adding any space to fill the remaining row height.  Having
			// remaining height means that the other side of the diff has more RowLayouts than this
			// side of the diff.
			RowLayout layout = rowLayouts.get(lastLine);
			consumedHeight += layout.getHeight();
			int leftOverHeight = rowHeight - consumedHeight;
			layout.insertSpaceBelow(leftOverHeight);
			updatedRows.add(layout);
		}

		return updatedRows;
	}
Aligns the heights in this MultiRowLayout to match those in the given row heights array.  
This is used by the diff provider to align two sets of rows.  

@param sharedRowHeights the row heights
Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/support/MultiRowLayout.java