protected function generateDatasets(SystemTableMetaModelLoaderCallContext $callcontext, DataSourceMetaData $datasource) {
        $columnsProperties = $this->loadColumnsProperties($callcontext, $datasource);
        if (isset($columnsProperties)) {
            foreach ($columnsProperties as $columnProperties) {
                $tableOwner = $this->adjustOwnerName($columnProperties[self::CN_TABLE_OWNER]);

                $originalTableName = $columnProperties[self::CN_TABLE_NAME];
                $tableName = $this->adjustTableName($originalTableName);
                if (!$this->isTableSupported($callcontext, $tableName)) {
                    continue;
                }

                $tableAccessKey = ArrayHelper::prepareCompositeKey(array($tableOwner, $tableName));

                // checking if we can process the column name
                $originalColumnName = $columnProperties[self::CN_COLUMN_NAME];
                $columnName = $this->adjustColumnName($originalColumnName);
                $generatedColumnName = $this->nameGenerator->generate($columnName);
                // this column cannot be supported by the system
                if ($columnName != $generatedColumnName) {
                    LogHelper::log_warn(t(
                        "Unsupported column name from '@tableName' table: @columnName",
                        array('@tableName' => $originalTableName, '@columnName' => $originalColumnName)));
                    continue;
                }

                // preparing new dataset
                if (!isset($callcontext->datasets[$tableAccessKey])) {
                    $source =  TableReferenceHelper::assembleTableReference($tableOwner, $tableName);

                    $dataset = new DatasetMetaData();
                    $dataset->name = NameSpaceHelper::addNameSpace($datasource->name, $this->nameGenerator->generate($tableName));
                    $dataset->publicName = $this->generateTablePublicName($originalTableName);
                    $dataset->datasourceName = $datasource->name;
                    $dataset->source = $source;
                    $dataset->markAsPrivate();

                    $callcontext->datasets[$tableAccessKey] = $dataset;
                }
                $dataset = $callcontext->datasets[$tableAccessKey];

                // adding new column to the dataset
                $column = $dataset->initiateColumn();
                $column->name = $columnName;
                $column->publicName = $this->generateColumnPublicName($originalColumnName);
                $column->persistence = ColumnMetaData::PERSISTENCE__STORAGE_CREATED;
                $column->columnIndex = $columnProperties[self::CN_COLUMN_INDEX];
                $column->type->databaseType = $columnProperties[self::CN_COLUMN_TYPE];
                if (isset($columnProperties[self::CN_COLUMN_TYPE_LENGTH])) {
                    $column->type->length = $columnProperties[self::CN_COLUMN_TYPE_LENGTH];
                }
                if (isset($columnProperties[self::CN_COLUMN_TYPE_PRECISION])) {
                    $column->type->precision = $columnProperties[self::CN_COLUMN_TYPE_PRECISION];
                }
                if (isset($columnProperties[self::CN_COLUMN_TYPE_SCALE])) {
                    $column->type->scale = $columnProperties[self::CN_COLUMN_TYPE_SCALE];
                }
                $this->generateColumnApplicationType($callcontext, $datasource, $column);

                // adjusting column properties
                if (!isset($column->type->applicationType)) {
                    $column->visible = FALSE;
                    LogHelper::log_warn(t(
                        "Data type is not supported for '@columnName' column from '@tableName' table: @databaseDataType",
                        array(
                            '@tableName' => $originalTableName,
                            '@columnName' => $originalColumnName,
                            '@databaseDataType' => $column->type->databaseType)));
                }
                $this->adjustColumnVisibility($callcontext, $column);

                $dataset->registerColumnInstance($column);
            }
        }

        LogHelper::log_info(t(
            'Processed system meta data about @tableCount table(s) and @columnCount column(s)',
            array('@tableCount' => count($callcontext->datasets), '@columnCount' => count($columnsProperties))));
    }
    protected function prepareDatasets4Update(SystemTableMetaModelLoaderCallContext $callcontext, AbstractMetaModel $metamodel, DataSourceMetaData $datasource) {
        foreach ($metamodel->datasets as $dataset) {
            // the dataset should belong to the selected data source
            if ($dataset->datasourceName !== $datasource->name) {
                continue;
            }

            // the dataset has to be of type table
            if (DatasetSourceTypeFactory::getInstance()->detectSourceType($dataset) !== TableDatasetSourceTypeHandler::SOURCE_TYPE) {
                continue;
            }

            // whole dataset meta data was prepared using different method. There is nothing else needs to be done
            if ($dataset->isComplete()) {
                continue;
            }

            // for now supporting datasets without table owner
            if (TableReferenceHelper::findTableOwner($dataset->source) != NULL) {
                continue;
            }

            // there could be several datasets for one table
            $tableAccessKey = $this->adjustTableName($dataset->source);
            $callcontext->datasets[$tableAccessKey][] = $dataset;
        }
    }