public static function getNewDatasetName ( $datasetUuid, $datasets ) {
        $logicalDatasetUuid = StarSchemaNamingConvention::findFactsOwner($datasetUuid);

        if (isset($logicalDatasetUuid)) {
            $dataset = GD_DatasetMetaModelLoaderHelper::getDatasetByUUID($datasets, $logicalDatasetUuid);
            return StarSchemaNamingConvention::getFactsRelatedName($dataset->name);
        } else {
            $dataset = GD_DatasetMetaModelLoaderHelper::getDatasetByUUID($datasets,$datasetUuid);
            return $dataset->name;
        }
    }
    protected function processConfig ( &$config ) {
        //  TODO Services casts everything to array not objects
        $config = (object) $config;
        $config->model = (object) $config->model;
        $metamodel = data_controller_get_metamodel();
        if ( !empty($config->model->datasets) ) {
            foreach ( $config->model->datasets as $key => $datasetIdentifier ) {
                $dataset = GD_DatasetMetaModelLoaderHelper::findDatasetByUUID($this->datasets,$datasetIdentifier);
                if (!isset($dataset)) {
                    $datasetName = NameSpaceHelper::addNameSpace(gd_datasource_get_active(), $datasetIdentifier);
                    $dataset = $metamodel->getDataset($datasetName);
                }
                $config->model->datasets[$key] = $dataset->name;
            }
        }

        // update columns
        if ( !empty($config->model->columns) ) {
            foreach ( $config->model->columns as $key => $value ) {
                $config->model->columns[$key] = DatasetImportHelper::getNewColumnName($value,$this->datasets);
            }
        }

        // update column configs
        if ( !empty($config->columnConfigs) ) {
            foreach ( $config->columnConfigs as $key => $value ) {
                $config->columnConfigs[$key]->columnId = DatasetImportHelper::getNewColumnName($value->columnId,$this->datasets);
            }
        }

        // update column orders
        if ( !empty($config->model->columnOrder) ) {
            foreach ( $config->model->columnOrder as $key => $value ) {
                $config->model->columnOrder[$key] = DatasetImportHelper::getNewColumnName($value,$this->datasets);
            }
        }

        // update column sorts
        if ( !empty($config->model->orderBy) ) {
            foreach ( $config->model->orderBy as $key => $value ) {
                $config->model->orderBy[$key]->column = DatasetImportHelper::getNewColumnName($value->column,$this->datasets);
            }
        }

        // update filters
        if ( !empty($config->model->filters) ) {
            foreach ( $config->model->filters as $key => $value ) {
                $config->model->filters[$key]->column = DatasetImportHelper::getNewColumnName($value->column,$this->datasets);
            }
        }

        // update visual series
        if ( !empty($config->visual->series) ) {
            $newSeries = array();
            foreach ( $config->visual->series as $key => $value ) {
                $newSeries[DatasetImportHelper::getNewColumnName($key,$this->datasets)] = $value;
            }
            $config->visual->series = $newSeries;
        }

        // update traffic column
        if ( !empty($config->visual->trafficColumn) ) {
            $config->visual->trafficColumn = DatasetImportHelper::getNewColumnName($config->visual->trafficColumn,$this->datasets);
        }

        // update color column
        if ( !empty($config->visual->useColumnDataForColor) ) {
            $config->visual->useColumnDataForColor = DatasetImportHelper::getNewColumnName($config->visual->useColumnDataForColor,$this->datasets);
        }

        // update traffic columns
        if ( !empty($config->visual->traffic) ) {
            $newTraffic = array();
            foreach ( $config->visual->traffic as $key => $value ) {
                $newName = DatasetImportHelper::getNewColumnName($key,$this->datasets);
                $value->trafficColumn = $newName;
                $newTraffic[$newName] = $value;
            }
            $config->visual->traffic = $newTraffic;
        }
    }
    public function finalize(AbstractMetaModel $metamodel) {
        parent::finalize($metamodel);

        $loaderName = $this->getName();

        // initializing all cubes. We separated registration from initialization to support inter-cube references
        $loadedDatasets = NULL;
        foreach ($metamodel->datasets as $dataset) {
            // working only with datasets which are created by this loader
            if ($dataset->loaderName != $loaderName) {
                continue;
            }

            StarSchemaCubeMetaData::registerFromDataset($metamodel, $dataset);

            $loadedDatasets[$dataset->nid] = $dataset;
        }

        if (isset($loadedDatasets)) {
            $dataset_nids = array_keys($loadedDatasets);

            // loading measures
            $measureNodes = gd_measure_get_measures_4_dataset($dataset_nids, LOAD_ENTITY);
            // grouping measures in context of dataset
            $datasetsMeasureNodes = $this->groupNodesByDataset($measureNodes, 'field_measure_dataset');

            // creating cubes for all datasets
            foreach ($loadedDatasets as $dataset) {
                // preparing corresponding cube
                $cube = StarSchemaCubeMetaData::initializeFromDataset($metamodel, $dataset);
                // assigning a loader which created the cube
                $cube->factsDataset->loaderName = $loaderName;
                $cube->loaderName = $loaderName;
                // preparing additional measures
                $datasetMeasureNodes = isset($datasetsMeasureNodes[$dataset->nid]) ? $datasetsMeasureNodes[$dataset->nid] : NULL;
                if (isset($datasetMeasureNodes)) {
                    foreach ($datasetMeasureNodes as $measureNode) {
                        $measure = $cube->registerMeasure(get_node_field_value($measureNode, 'field_measure_sysname', 0, 'value', TRUE));
                        $measure->publicName = $measureNode->title;
                        $measure->description = get_node_field_value($measureNode, 'field_measure_desc');
                        $measure->function = get_node_field_value($measureNode, 'field_measure_function', 0, 'value', TRUE);
                    }
                }
            }
        }

        // processing references
        $referenceNodes = gd_reference_get_references(LOAD_ENTITY);
        $referencePointNodes = isset($referenceNodes) ? gd_reference_get_reference_points(LOAD_ENTITY) : NULL;
        if (isset($referencePointNodes)) {
            foreach ($referenceNodes as $referenceNode) {
                GD_DatasetMetaModelLoaderHelper::prepareReference($metamodel, $referenceNode, $referencePointNodes);
            }
        }
    }
    protected function update(Import\ImportStream $stream, Import\ImportContext $context) {
        $datasets = $stream->get('datasets');
        if (empty($datasets)) {
            return;
        }

        gd_datasource_set_active($context->get('datasourceName'));
        $metamodel = data_controller_get_metamodel();

        $environment_metamodel = data_controller_get_environment_metamodel();
        $datasource = $environment_metamodel->getDataSource($context->get('datasourceName'));

        foreach ( $datasets as $dataset ) {
            $existingDataset = GD_DatasetMetaModelLoaderHelper::findDatasetByUUID($metamodel->datasets, $dataset->uuid);
            if ( !$existingDataset ) {

                // map for re-linking dependent objects
                $dataset->originalName = $dataset->name;

                // create new name
                $newDatasetName = GD_NamingConvention::generateDatasetName();
                $dataset->name = $newDatasetName;
                $dataset->source = $newDatasetName;
                $dataset->datasourceName = $datasource->name;
            } else {
                // map for re-linking dependent objects
                $dataset->originalName = $dataset->name;

                $dataset->name = $existingDataset->name;
                $dataset->source = $existingDataset->source;
                $dataset->datasourceName = $existingDataset->datasourceName;
            }
        }

        // prepare dataset columns for import
        $this->prepareColumns($datasets);

        // prepares the metadata object, has to be of type RecordMetaData
        foreach ( $datasets as $key => $dataset ) {
            $metadata = new DatasetMetaData();
            $metadata->initializeFrom($dataset);
            $datasets[$key] = $metadata;
        }

        // ensure datasets are created in order to satisfy dependencies
        usort($datasets, array(new ReferencedDatasetComparator(), 'compare'));

        foreach ( $datasets as $dataset ) {
            $existingDataset = GD_DatasetMetaModelLoaderHelper::findDatasetByUUID($metamodel->datasets, $dataset->uuid);
            if ($existingDataset) {
                gd_data_controller_ddl_modify_dataset($dataset);
            } else {
                MetaModelFactory::getInstance()->startGlobalModification();
                try {
                    $transaction = db_transaction();
                    try {
                        gd_data_controller_ddl_create_dataset($dataset);
                    } catch (Exception $e) {
                        $transaction->rollback();
                        throw $e;
                    }
                } catch (Exception $e) {
                    MetaModelFactory::getInstance()->finishGlobalModification(false);
                    throw $e;
                }
                MetaModelFactory::getInstance()->finishGlobalModification(true);
            }
        }

        $stream->set('datasets',$datasets);
    }