class MetaDataInfoProvider {

    public MetaDataInfo createMetaDataInfo(List<DataTypeInfo> mergedLayers, List<MergedDataRow> data)
    {
        DefaultMetaDataInfo metadataInfo = new DefaultMetaDataInfo();

        Map<String, Class<?>> columnsToTypes = new LinkedHashMap<>();
        for (MergedDataRow row : data)
        {
            for (Entry<String, Serializable> entry : row.getData().entrySet())
            {
                Class<?> type = String.class;
                if (entry.getValue() != null)
                {
                    type = entry.getValue().getClass();
                    if (!type.equals(columnsToTypes.get(entry.getKey())))
                    {
                        columnsToTypes.put(entry.getKey(), type);
                    }
                }
                else
                {
                    columnsToTypes.put(entry.getKey(), type);
                }
            }
        }

        for (Entry<String, Class<?>> column : columnsToTypes.entrySet())
        {
            metadataInfo.addKey(column.getKey(), column.getValue(), this);
        }

        addSpecialKeys(metadataInfo, mergedLayers);
        metadataInfo.copyKeysToOriginalKeys();

        return metadataInfo;
    }

    public  MetaDataInfoProvider(ColumnMappingController controller);

}