@SuppressWarnings("unchecked")
	// Each cast is checked below (see notes)
	//@formatter:off
	private static <COLUMN_ROW_TYPE, TABLE_ROW_TYPE, COLUMN_TYPE, DATA_SOURCE>
		Collection<DynamicTableColumn<TABLE_ROW_TYPE, COLUMN_TYPE, DATA_SOURCE>> getTableColumnForTypes(
			Class<TABLE_ROW_TYPE> rowTypeClass, DynamicTableColumn<?, ?, ?> tableColumn) {

	//@formatter:on

		Set<DynamicTableColumn<TABLE_ROW_TYPE, COLUMN_TYPE, DATA_SOURCE>> set = new HashSet<>();

		// first, check for a direct match
		Class<?> supportedRowType = tableColumn.getSupportedRowType();
		if (supportedRowType == rowTypeClass) {
			// Safe cast:
			// We know that TABLE_ROW_TYPE is correct, since we just checked the classes for '=='
			set.add((DynamicTableColumn<TABLE_ROW_TYPE, COLUMN_TYPE, DATA_SOURCE>) tableColumn);
			return set;
		}

		// next, check to see if we can find a mapper to convert the actual ROW_TYPE
		// to the COLUMN_ROW_TYPE
		Collection<TableRowMapper<TABLE_ROW_TYPE, COLUMN_ROW_TYPE, DATA_SOURCE>> mappers =
			getTableRowObjectMapper(rowTypeClass, supportedRowType);
		if (mappers.isEmpty()) {
			return Collections.emptySet();
		}

		// Safe cast:
		// 1) We already know that COLUMN_ROW_TYPE is the same as 'supportedRowType',
		//    since the mapper is not null and that is one of the criteria for finding
		//    a mapper
		// 2) We don't know what COLUMN_ROW_TYPE actually is, but we don't care, as it is
		//    just a placeholder
		DynamicTableColumn<COLUMN_ROW_TYPE, COLUMN_TYPE, DATA_SOURCE> castColumn =
			(DynamicTableColumn<COLUMN_ROW_TYPE, COLUMN_TYPE, DATA_SOURCE>) tableColumn;
		return createMappedTableColumn(mappers, castColumn);
	}
If the given <code>DynamicTableColumn</code> is a match for the given <code>rowTypeClass</code>, then
it will be added to the given list.
<p>
<u>Implementation Notes:</u>
This method does some odd things with Java Generics.  Specifically, it declares three
generic types, but only relies on the caller of the method to provide one of those types.
Further, in some cases the method uses the Generic wildcard '?' feature.  In one case it
does not use this feature, since we need to create a new object, and the
compiler requires that we have a type and not a wildcard to do this.  In this usage, we are
just guaranteeing that the created type matches our needs, even though we don't know what
that type actually is.

@param <COLUMN_ROW_TYPE> A placeholder type for discovered column row types
                         that may differ from the given TABLE_ROW_TYPE.
@param <TABLE_ROW_TYPE>  The class of the table's row data
@param <COLUMN_TYPE>     The type of object that the column generates from the call to
                         column's <tt>getValue()</t> method.
@param rowTypeClass      The class of the table's row data (with the same type as
						    COLUMN_ROW_TYPE)
@param tableColumn       The column to add to the given collection if it supports the
                         given <code>rowTypeClass</code>.
Ghidra/Framework/Docking/src/main/java/docking/widgets/table/DiscoverableTableUtils.java