class InputColumn implements Symbol, Comparable<InputColumn> {

    private final DataType<?> dataType;
    private final int index;

    /**
     * Map each data type to an {@link InputColumn} with an index corresponding to the data type's position in the list.
     */
    public static List<Symbol> mapToInputColumns(List<DataType<?>> dataTypes) {
        List<Symbol> inputColumns = new ArrayList<>(dataTypes.size());
        for (int i = 0; i < dataTypes.size(); i++) {
            inputColumns.add(new InputColumn(i, dataTypes.get(i)));
        }
        return inputColumns;
    }

    /**
     * Map each symbol to an {@link InputColumn} with an index corresponding to the symbol's position in the collection.
     */
    public static List<Symbol> mapToInputColumns(Collection<? extends Symbol> symbols) {<FILL_FUNCTION_BODY>}

    public InputColumn(int index, @Nullable DataType<?> dataType) {
        assert index >= 0 : "index must be >= 0";
        this.index = index;
        this.dataType = Objects.requireNonNullElse(dataType, DataTypes.UNDEFINED);
    }

    public InputColumn(StreamInput in) throws IOException {
        index = in.readVInt();
        dataType = DataTypes.fromStream(in);
    }

    public InputColumn(int index) {
        this(index, null);
    }

    public int index() {
        return index;
    }

    @Override
    public SymbolType symbolType() {
        return SymbolType.INPUT_COLUMN;
    }

    @Override
    public DataType<?> valueType() {
        return dataType;
    }

    @Override
    public String toString() {
        return "INPUT(" + index + ")";
    }

    @Override
    public String toString(Style style) {
        return "INPUT(" + index + ")";
    }

    @Override
    public <C, R> R accept(SymbolVisitor<C, R> visitor, C context) {
        return visitor.visitInputColumn(this, context);
    }

    @Override
    public void writeTo(StreamOutput out) throws IOException {
        out.writeVInt(index);
        DataTypes.toStream(dataType, out);
    }

    @Override
    public int compareTo(InputColumn o) {
        return Integer.compare(index, o.index);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        InputColumn that = (InputColumn) o;

        return index == that.index;
    }

    @Override
    public int hashCode() {
        return index;
    }

    @Override
    public long ramBytesUsed() {
        return IntegerType.INTEGER_SIZE + dataType.ramBytesUsed();
    }
}

        List<Symbol> inputColumns = new ArrayList<>(symbols.size());
        int idx = 0;
        for (Symbol symbol : symbols) {
            inputColumns.add(new InputColumn(idx, symbol.valueType()));
            idx++;
        }
        return inputColumns;
    
<no_super_class>