protected static function prepareReferencedElementName($referencePath, $datasetName, $elementName) {
        $referencedElementName = $elementName;
        if (isset($referencePath)) {
            $nestedReference = ReferencePathHelper::assembleReference($datasetName, $elementName);
            $referencedElementName = ReferencePathHelper::assembleReferencePath(array($nestedReference, $referencePath));
        }

        return $referencedElementName;
    }
    protected static function prepareListColumnMappings(array $cubes = NULL, array $parsedUIMetaDataNames) {
        $columnMappings = NULL;

        foreach ($parsedUIMetaDataNames as $columnName => $parsedUIMetaDataName) {
            $datasetColumnName = NULL;
            if ($parsedUIMetaDataName instanceof AttributeParsedUIMetaDataName) {
                $cube = isset($cubes[$parsedUIMetaDataName->datasetName]) ? $cubes[$parsedUIMetaDataName->datasetName] : NULL;
                if (isset($cube)) {
                    $dimension = $cube->getDimension($parsedUIMetaDataName->name);

                    $references = NULL;
                    if (isset($parsedUIMetaDataName->columnName)) {
                        $column = $cube->factsDataset->getColumn($dimension->attributeColumnName);
                        $branch = $column->findBranch($parsedUIMetaDataName->columnName);
                        // the dimension column can be a branch, not a dimension dataset column
                        if (!isset($branch) && isset($dimension->datasetName)) {
                            list($adjustedDimensionDatasetName) = gd_data_controller_metamodel_adjust_dataset_name($dimension->datasetName);
                            $references[] = ReferencePathHelper::assembleReference($adjustedDimensionDatasetName, $parsedUIMetaDataName->columnName);
                        }
                    }

                    if (isset($references)) {
                        $references[] = ReferencePathHelper::assembleReference($cube->factsDatasetName, $dimension->attributeColumnName);
                        $datasetColumnName = ReferencePathHelper::assembleReferencePath($references);
                    }
                    else {
                        $datasetColumnName = isset($parsedUIMetaDataName->columnName)
                            ? $parsedUIMetaDataName->columnName
                            : $dimension->attributeColumnName;
                    }
                }
                else {
                    $datasetColumnName = $parsedUIMetaDataName->name;
                }
            }
            elseif ($parsedUIMetaDataName instanceof FormulaAttributeParsedUIMetaDataName) {
                $datasetColumnName = $parsedUIMetaDataName->name;
            }
            elseif ($parsedUIMetaDataName instanceof FormulaMeasureParsedUIMetaDataName) {
                $datasetColumnName = $parsedUIMetaDataName->name;
            }

            if (isset($datasetColumnName)) {
                $columnMappings[$columnName] = $datasetColumnName;
            }
        }

        return $columnMappings;
    }
    public static function selectReferencedColumnNames4ReferenceLink(array $linkExecutionStack, array $columnNames = NULL) {
        if (!isset($columnNames)) {
            return NULL;
        }

        $selectedColumnNames = NULL;

        $linkExecutionStackSize = count($linkExecutionStack);

        foreach ($columnNames as $columnName) {
            $columnNameReferences = ReferencePathHelper::splitReferencePath($columnName);
            $referenceSegmentCount = count($columnNameReferences);

            for ($referenceSegmentIndex = $referenceSegmentCount - 1, $stackPreviousIndex = -1; $referenceSegmentIndex >= 0; $referenceSegmentIndex--) {
                $reference = $columnNameReferences[$referenceSegmentIndex];
                list($referencedDatasetName, $referencedColumnName) = ReferencePathHelper::splitReference($reference);

                if (isset($referencedDatasetName)) {
                    // looking for related link in stack
                    $foundInStack = FALSE;
                    for ($stackIndex = ($stackPreviousIndex + 1); ($stackIndex < $linkExecutionStackSize) && !$foundInStack; $stackIndex++) {
                        $stackLink = $linkExecutionStack[$stackIndex];
                        if ($referencedDatasetName != $stackLink->dataset->name) {
                            continue;
                        }

                        // checking parent column name
                        if (($stackIndex < $linkExecutionStackSize - 1) && ($referenceSegmentIndex > 0)) {
                            $nextStackLine = $linkExecutionStack[$stackIndex + 1];
                            // checking number of columns. It has to be single column
                            if (count($nextStackLine->parentColumnNames) > 1) {
                                break;
                            }

                            // checking if the parent column matches
                            if (!in_array($referencedColumnName, $nextStackLine->parentColumnNames)) {
                                break;
                            }
                        }

                        $stackPreviousIndex = $stackIndex;
                        $foundInStack = TRUE;
                    }
                    if (!$foundInStack) {
                        break;
                    }

                    // we did not reach end of the execution stack
                    if ($stackPreviousIndex < ($linkExecutionStackSize - 1)) {
                        continue;
                    }
                }
                else {
                    if ($linkExecutionStackSize > 1) {
                        // this column belongs to root link but we are working with nested link
                        break;
                    }
                }

                // original column name would be only the portion of the reference path
                $adjustedColumnName = ReferencePathHelper::assembleReferencePath(array_slice($columnNameReferences, $referenceSegmentIndex));
                $selectedColumnNames[$adjustedColumnName] = $referencedColumnName;
                break;
            }
        }

        return $selectedColumnNames;
    }