/// <summary>
        /// Returns the set of cross referenced structures.
        /// </summary>
        /// <param name="retrievalManager">
        /// The retrieval manager
        /// </param>
        /// <param name="constraintBean">
        /// The constraint object
        /// </param>
        /// <returns>
        /// The cross references set.
        /// </returns>
        private ISet<ICrossReference> GetCrossReferences(ISdmxObjectRetrievalManager retrievalManager, IContentConstraintObject constraintBean)
        {
            ISet<ICrossReference> returnReferences = constraintBean.CrossReferences;

            IDictionary<string, IComponent> componentMap = new Dictionary<String, IComponent>();

            foreach (ICrossReference crossRef in constraintBean.ConstraintAttachment.StructureReference)
            {
                switch (crossRef.TargetReference.EnumType)
                {
                    case SdmxStructureEnumType.ProvisionAgreement:
                    case SdmxStructureEnumType.Dataflow:
                    case SdmxStructureEnumType.Dsd:
                        AddComponenents(retrievalManager, crossRef, componentMap);
                        break;
                    case SdmxStructureEnumType.DataProvider:
                        //Important:
                        //It is important to get this from the BeanRetrievalManager and not the ProvisionRetrievalManager
                        //As the ProvisionRetrievalManager relies on CrossReferecnce retrieval, which may not have been built yet (as
                        //This class is responsible for aiding the building of cross references
                        foreach (IProvisionAgreementObject currentProv in _beanRetrievalManager.GetMaintainableObjects<IProvisionAgreementObject>())
                        {
                            if (currentProv.DataproviderRef.TargetUrn.Equals(crossRef.TargetUrn))
                            {
                                AddComponenents(retrievalManager, currentProv.StructureUseage, componentMap);
                            }
                        }
                        foreach (IProvisionAgreementObject currentProv in retrievalManager.GetMaintainableObjects<IProvisionAgreementObject>())
                        {
                            if (currentProv.DataproviderRef.TargetUrn.Equals(crossRef.TargetUrn))
                            {
                                AddComponenents(retrievalManager, currentProv.StructureUseage, componentMap);
                            }
                        }
                        break;
                }
            }

            AddCrossReferencesForCubeRegion(constraintBean, returnReferences, componentMap, constraintBean.IncludedCubeRegion);
            AddCrossReferencesForCubeRegion(constraintBean, returnReferences, componentMap, constraintBean.ExcludedCubeRegion);
            AddCrossReferencesForConstraintKey(constraintBean, returnReferences, componentMap, constraintBean.IncludedSeriesKeys);
            AddCrossReferencesForConstraintKey(constraintBean, returnReferences, componentMap, constraintBean.ExcludedSeriesKeys);

            return returnReferences;
        }
        /// <summary>
        /// Build from a REST query and a bean retrival manager
        /// </summary>
        /// <param name="dataQuery"></param>
        /// <param name="retrievalManager"></param>
        /// <exception cref="SdmxSemmanticException"></exception>
        public DataQueryImpl(IRestDataQuery dataQuery, ISdmxObjectRetrievalManager retrievalManager)
        {
            this._lastUpdated = dataQuery.UpdatedAfter;
            this._dataQueryDetail = dataQuery.QueryDetail ?? DataQueryDetail.GetFromEnum(DataQueryDetailEnumType.Full);

            base.FirstNObservations = dataQuery.FirstNObservations;
            base.LastNObservations = dataQuery.LastNObsertations;
            if (ObjectUtil.ValidString(dataQuery.DimensionAtObservation))
            {
                this.DimensionAtObservation = dataQuery.DimensionAtObservation;
            }

            base.Dataflow = retrievalManager.GetMaintainableObject<IDataflowObject>(dataQuery.FlowRef.MaintainableReference);
            if (base.Dataflow == null)
            {
                throw new SdmxNoResultsException("Data Flow could not be found for query : " + dataQuery.FlowRef);
            }

            base.DataStructure =
                retrievalManager.GetMaintainableObject<IDataStructureObject>(base.Dataflow.DataStructureRef.MaintainableReference);
            if (base.DataStructure == null)
            {
                throw new SdmxNoResultsException("DSD could not be found for query : " + base.Dataflow.DataStructureRef);
            }

            ISet<IDataProvider> dataProviders = new HashSet<IDataProvider>();
            if (dataQuery.ProviderRef != null)
            {
                ISet<IDataProviderScheme> dataProviderSchemes =
                    retrievalManager.GetMaintainableObjects<IDataProviderScheme>(dataQuery.ProviderRef.MaintainableReference);
                foreach (IDataProviderScheme currentDpScheme in dataProviderSchemes)
                {
                    foreach (IDataProvider dataProvider in currentDpScheme.Items)
                    {
                        if (dataProvider.Id.Equals(dataQuery.ProviderRef.ChildReference.Id))
                        {
                            dataProviders.Add(dataProvider);
                        }
                    }
                }
            }
            ISet<IDataQuerySelection> selections = new HashSet<IDataQuerySelection>();
            if (dataQuery.QueryList.Count > 0)
            {
                int i = 0;
                foreach (IDimension dimension in base.DataStructure.GetDimensions(SdmxStructureEnumType.Dimension, SdmxStructureEnumType.MeasureDimension).OrderBy(dimension => dimension.Position))
                {
                    if (dataQuery.QueryList.Count <= i)
                    {
                        throw new SdmxSemmanticException(
                            "Not enough key values in query, expecting "
                            + base.DataStructure.GetDimensions(SdmxStructureEnumType.Dimension, SdmxStructureEnumType.MeasureDimension).Count + " got "
                            + dataQuery.QueryList.Count);
                    }
                    ISet<string> queriesForDimension = dataQuery.QueryList[i];
                    if (queriesForDimension != null && queriesForDimension.Count > 0)
                    {
                        IDataQuerySelection selectionsForDimension =
                            new DataQueryDimensionSelectionImpl(
                                dimension.Id,
                                new HashSet<string>(queriesForDimension));
                        selections.Add(selectionsForDimension);
                    }
                    i++;
                }
            }

            if (ObjectUtil.ValidCollection(selections) || dataQuery.StartPeriod != null || dataQuery.EndPeriod != null)
            {
                _dataQuerySelectionGroups.Add(
                    new DataQuerySelectionGroupImpl(selections, dataQuery.StartPeriod, dataQuery.EndPeriod));
            }
            ValidateQuery();
        }