/// <summary>
        /// Initialize component mappings for coded components and time dimension used in mappings in the dataflow
        /// </summary>
        /// <param name="dataflowRef">
        /// The dataflow Ref.
        /// </param>
        /// <remarks>
        /// This method should be called only once
        /// </remarks>
        private void Initialize(Sdmx.Model.Registry.DataflowRefBean dataflowRef)
        {
            this._mappingSet = DataAccess.GetMappingSet(
                this._connectionStringSettings, 
                dataflowRef.Id, 
                dataflowRef.Version, 
                dataflowRef.AgencyID, 
                this._allowedDataflows);
            if (this._mappingSet == null)
            {
                return;
            }

            NormallizeDatabaseProvider(this._connectionStringSettings);
            this._mastoreAccess = new StructureAccess(this._connectionStringSettings);
            this._xsMeasureDimensionConstraints.Clear();

            this._componentMapping = new Dictionary<string, ComponentInfo>(this._mappingSet.Mappings.Count);
            this._innerSqlQuery = this._mappingSet.DataSet.Query;
            this._measureComponent = null;
            this._timeTranscoder = null;
            this._timeMapping = null;
            this._timeDimension = null;
            bool measureDimensionMapped = false;

            foreach (MappingEntity mapping in this._mappingSet.Mappings)
            {
                foreach (ComponentEntity component in mapping.Components)
                {
                    if (component.ComponentType == SdmxComponentType.TimeDimension)
                    {
                        this._timeTranscoder = TimeDimensionMapping.Create(
                            mapping, this._mappingSet.DataSet.Connection.DBType);
                        this._timeMapping = mapping;
                        this._timeDimension = component.Concept.Id;
                    }
                    else if (component.CodeList != null)
                    {
                        if (component.MeasureDimension)
                        {
                            measureDimensionMapped = true;
                        }

                        var compInfo = new ComponentInfo();
                        compInfo.Mapping = mapping;
                        compInfo.ComponentMapping = ComponentMapping.CreateComponentMapping(component, mapping);
                        compInfo.CodelistRef.Id = component.CodeList.Id;
                        compInfo.CodelistRef.Version = component.CodeList.Version;
                        compInfo.CodelistRef.AgencyID = component.CodeList.Agency;
                        this._componentMapping.Add(component.Concept.Id, compInfo);
                    }
                }
            }

            if (!measureDimensionMapped)
            {
                foreach (ComponentEntity component in this._mappingSet.Dataflow.Dsd.Dimensions)
                {
                    if (component.MeasureDimension)
                    {
                        this._measureComponent = component.Concept.Id;
                    }
                }

                foreach (ComponentEntity xsMeasure in this._mappingSet.Dataflow.Dsd.CrossSectionalMeasures)
                {
                    this._xsMeasureDimensionConstraints.Add(xsMeasure.Concept.Id, xsMeasure);
                }
            }
        }
        /// <summary>
        /// Parse the specified DataflowRefBean object and populate the <see cref="_requestedComponent"/> and <see cref="_criteria"/> fields
        /// </summary>
        /// <param name="d">
        /// The DataflowRefBean to parse
        /// </param>
        private void ParserDataflowRef(Sdmx.Model.Registry.DataflowRefBean d)
        {
            if (d.Constraint != null)
            {
                foreach (CubeRegionBean cube in d.Constraint.CubeRegion)
                {
                    foreach (MemberBean member in cube.Members)
                    {
                        if (member.MemberValue.Count == 0)
                        {
                            this._requestedComponent = member.ComponentRef;
                        }
                        else
                        {
                            this._criteria.Add(member);
                        }
                    }
                }

                this._referencePeriod = d.Constraint.ReferencePeriod;
            }
        }
        /// <summary>
        /// Initializes a new instance of the AvailableDataRetriever class
        /// </summary>
        /// <param name="dataflow">
        /// The datflow to get the available data for
        /// </param>
        /// <param name="connectionStringSettings">
        /// The Mapping Store connection string settings
        /// </param>
        /// <param name="logger">
        /// The logger to log information, warnings and errors. It can be null
        /// </param>
        /// <param name="allowedDataflows">
        /// The collection of allowed dataflows
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// connectionStringSettings is null
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// dataflow is null
        /// </exception>
        /// <exception cref="StructureRetrieverException">
        /// Parsing error or mapping store exception error
        /// </exception>
        public AvailableDataRetriever(
            Sdmx.Model.Registry.DataflowRefBean dataflow, 
            ConnectionStringSettings connectionStringSettings, 
            Log logger, 
            ICollection<DataflowRefBean> allowedDataflows)
        {
            if (connectionStringSettings == null)
            {
                throw new ArgumentNullException("connectionStringSettings");
            }

            if (dataflow == null)
            {
                throw new ArgumentNullException("dataflow");
            }

            this._connectionStringSettings = connectionStringSettings;
            this._allowedDataflows = allowedDataflows;
            this._logger = logger ?? new Log();

            this.ParserDataflowRef(dataflow);
            try
            {
                this.Initialize(dataflow);
            }
            catch (StructureRetrieverException)
            {
                throw;
            }
            catch (DbException e)
            {
                string mesage = "Mapping Store connection error." + e.Message;
                this._logger.LogError(mesage);
                this._logger.LogError(e.ToString());
                throw new StructureRetrieverException(
                    StructureRetrieverErrorTypes.MappingStoreConnectionError, mesage, e);
            }
            catch (Exception e)
            {
                string mesage = string.Format(
                    CultureInfo.CurrentCulture, 
                    ErrorMessages.ErrorRetrievingMappingSetFormat4, 
                    dataflow.AgencyID, 
                    dataflow.Id, 
                    dataflow.Version, 
                    e.Message);
                this._logger.LogError(mesage);
                this._logger.LogError(e.ToString());
                throw new StructureRetrieverException(
                    StructureRetrieverErrorTypes.MappingStoreConnectionError, mesage, e);
            }
        }