/// <summary>
        /// Adds a selection value, either into an existing ComplexDataQuerySelection with the given concept, or a new DataQuerySelection if none exist with the given concept.
        /// </summary>
        /// <param name="complexSelections">
        /// The complex selections.
        /// </param>
        /// <param name="conceptId">
        /// The concept id.
        /// </param>
        /// <param name="value">
        /// The component value.
        /// </param>
        private void AddComponentSelection(ISet<IComplexDataQuerySelection> complexSelections, string conceptId, IComplexComponentValue value)
        {
            foreach (IComplexDataQuerySelection selection in complexSelections)
            {
                if (selection.ComponentId.Equals(conceptId))
                {
                    ((ComplexDataQuerySelectionImpl)selection).Values.Add(value);
                    return;
                }
            }

            IList<IComplexComponentValue> values = new List<IComplexComponentValue>();
            values.Add(value);
            IComplexDataQuerySelection newSelection = new ComplexDataQuerySelectionImpl(conceptId, values);
            complexSelections.Add(newSelection);
        }
        /// <summary>
        /// Maps a component to one or more local columns and it's value to one or more local codes
        /// </summary>
        /// <param name="id">
        /// The DSD Component identifier e.g. FREQ 
        /// </param>
        /// <param name="conditionValue">
        /// The DSD Component condition value (from the SDMX Query) 
        /// </param>
        /// <param name="info">
        /// The current Data Retrieval status 
        /// </param>
        /// <returns>
        /// An string containing the sql query where condition 
        /// </returns>
        private static string GenerateComponentWhere(string id, IComplexComponentValue conditionValue, DataRetrievalInfo info)
        {
            var ret = new StringBuilder();

            // MappingEntity mapping;
            // check if there is a mapping for this component
            if (id != null && conditionValue != null)
            {
                string sOperator = "=";
                if (conditionValue.OrderedOperator != null)
                    sOperator = GetSqlOrderedOperator(conditionValue.OrderedOperator);
                else if (conditionValue.TextSearchOperator != null)
                    sOperator = GetSqlTextSearchOperator(conditionValue.TextSearchOperator);

                IComponentMapping componentMappingType;
                if (info.ComponentIdMap.TryGetValue(id, out componentMappingType))
                {
                    ret.Append(componentMappingType.GenerateComponentWhere(conditionValue.Value, sOperator));
                }
                else if (info.MeasureComponent == null || !id.Equals(info.MeasureComponent.Id))
                {
                    // component is not in the mapping
                    ret.Append(
                        string.Format(
                            CultureInfo.InvariantCulture,
                            " ('{0} is not mapped' " + sOperator + " '{1}') ",
                            id.Replace("'", "''"),
                            conditionValue.Value.Replace("'", "''")));
                }
            }

            return ret.ToString();
        }
 /// <summary>
 /// Sets the simple operator and value.
 /// </summary>
 /// <param name="rootObject">The root object.</param>
 /// <param name="complexComponentValue">The complex component value.</param>
 private static void SetSimpleOperatorAndValue(DataStructureComponentValueQueryType rootObject, IComplexComponentValue complexComponentValue)
 {
     string queryOperator = complexComponentValue.OrderedOperator != null ? complexComponentValue.OrderedOperator.OrdOperator : DefaultEqualOperator;
     var simpleValueType = new SimpleValueType { @operator = queryOperator, TypedValue = complexComponentValue.Value };
     rootObject.Value = new Value(simpleValueType);
 }
	    public void AddValue(IComplexComponentValue value) 
        {
		    this._values.Add(value);
	    }
 /// <summary>
 /// Sets the time operator and value.
 /// </summary>
 /// <param name="rootObject">The root object.</param>
 /// <param name="complexComponentValue">The complex component value.</param>
 private static void SetTimeOperatorAndValue(DataStructureComponentValueQueryType rootObject, IComplexComponentValue complexComponentValue)
 {
     string queryOperator = complexComponentValue.OrderedOperator != null ? complexComponentValue.OrderedOperator.OrdOperator : DefaultEqualOperator;
     var timePeriodValueType = new TimePeriodValueType { @operator = queryOperator, TypedValue = complexComponentValue.Value };
     rootObject.TimeValue.Add(new TimeValue(timePeriodValueType));
 }
 /// <summary>
 /// Sets the simple operator and value.
 /// </summary>
 /// <param name="rootObject">The root object.</param>
 /// <param name="complexComponentValue">The complex component value.</param>
 private static void SetTextOperatorAndValue(DataStructureComponentValueQueryType rootObject, IComplexComponentValue complexComponentValue)
 {
     string queryOperator = complexComponentValue.TextSearchOperator != null ? complexComponentValue.TextSearchOperator.Operator : DefaultEqualOperator;
     var queryTextType = new QueryTextType { @operator = queryOperator, TypedValue = complexComponentValue.Value };
     var textValue = new TextValue(queryTextType);
     rootObject.TextValue.Add(textValue);
 }
 /// <summary>
 /// Sets the numeric operator and value.
 /// </summary>
 /// <param name="rootObject">The root object.</param>
 /// <param name="complexComponentValue">The complex component value.</param>
  private static void SetNumericOperatorAndValue(DataStructureComponentValueQueryType rootObject, IComplexComponentValue complexComponentValue)
 {
      var numericValue = new NumericValue { TypedValue = decimal.Parse(complexComponentValue.Value, CultureInfo.InvariantCulture), @operator = complexComponentValue.OrderedOperator.OrdOperator };
      rootObject.NumericValue.Add(numericValue);
 }
 /// <summary>
 /// Sets the operator and value.
 /// </summary>
 /// <param name="component">The component.</param>
 /// <param name="complexComponentValue">The complex component value.</param>
 /// <param name="dataStructureComponentValueQueryType">Type of the data structure component value query.</param>
 private static void SetOperatorAndValue(IComponent component, IComplexComponentValue complexComponentValue, DataStructureComponentValueQueryType dataStructureComponentValueQueryType)
 {
     var valueType = GetValueType(component, complexComponentValue);
     switch (valueType)
     {
         case ValueType.NumericValue:
             SetNumericOperatorAndValue(dataStructureComponentValueQueryType, complexComponentValue);
             break;
         case ValueType.TextValue:
             SetTextOperatorAndValue(dataStructureComponentValueQueryType, complexComponentValue);
             break;
         case ValueType.TimeValue:
             SetTimeOperatorAndValue(dataStructureComponentValueQueryType, complexComponentValue);
             break;
         case ValueType.Value:
             SetSimpleOperatorAndValue(dataStructureComponentValueQueryType, complexComponentValue);
             break;
     }
 }
        /// <summary>
        /// Gets the type of the value.
        /// </summary>
        /// <param name="component">The component.</param>
        /// <param name="complexComponentValue">The complex component value.</param>
        /// <returns>The value type</returns>
        private static ValueType GetValueType(IComponent component, IComplexComponentValue complexComponentValue)
        {
            if (component.HasCodedRepresentation())
            {
                return ValueType.Value;
            }

            var defaultValueType = ValueType.TextValue;
            if (complexComponentValue.TextSearchOperator != null)
            {
                return ValueType.TextValue;
            }
            
            if (complexComponentValue.OrderedOperator != null)
            {
                switch (complexComponentValue.OrderedOperator.EnumType)
                {
                    case OrderedOperatorEnumType.GreaterThanOrEqual:
                    case OrderedOperatorEnumType.LessThanOrEqual:
                    case OrderedOperatorEnumType.LessThan:
                    case OrderedOperatorEnumType.GreaterThan:
                        defaultValueType = ValueType.NumericValue;
                        break;
                    default:
                        defaultValueType = ValueType.Value;
                        break;
                }
            }

            if (component.Representation != null && component.Representation.TextFormat != null)
            {
                if (component.Representation.TextFormat.TextType != null)
                {
                    switch (component.Representation.TextFormat.TextType.EnumType)
                    {
                        case TextEnumType.BasicTimePeriod:
                        case TextEnumType.DateTime:
                        case TextEnumType.Date:
                        case TextEnumType.Time:
                        case TextEnumType.Year:
                        case TextEnumType.Month:
                        case TextEnumType.Day:
                        case TextEnumType.MonthDay:
                        case TextEnumType.YearMonth:
                        case TextEnumType.Duration:
                        case TextEnumType.Timespan:
                        case TextEnumType.TimePeriod:
                        case TextEnumType.ObservationalTimePeriod:
                        case TextEnumType.GregorianDay:
                        case TextEnumType.GregorianTimePeriod:
                        case TextEnumType.GregorianYear:
                        case TextEnumType.GregorianYearMonth:
                        case TextEnumType.ReportingDay:
                        case TextEnumType.ReportingMonth:
                        case TextEnumType.ReportingQuarter:
                        case TextEnumType.ReportingSemester:
                        case TextEnumType.ReportingTimePeriod:
                        case TextEnumType.ReportingTrimester:
                        case TextEnumType.ReportingWeek:
                        case TextEnumType.ReportingYear:
                        case TextEnumType.StandardTimePeriod:
                        case TextEnumType.TimesRange:
                            return ValueType.TimeValue;
                        case TextEnumType.BigInteger:
                        case TextEnumType.Integer:
                        case TextEnumType.Long:
                        case TextEnumType.Short:
                        case TextEnumType.Decimal:
                        case TextEnumType.Float:
                        case TextEnumType.Double:
                        case TextEnumType.Count:
                        case TextEnumType.Numeric:
                        case TextEnumType.InclusiveValueRange:
                        case TextEnumType.ExclusiveValueRange:
                            return ValueType.NumericValue;
                        case TextEnumType.Boolean:
                            return ValueType.Value;
                    }
                }

                return defaultValueType;
            }

            // try guessing type from component type.
            switch (component.StructureType.EnumType)
            {
                case SdmxStructureEnumType.Dimension:
                    return ValueType.Value;
                case SdmxStructureEnumType.PrimaryMeasure:
                    return ValueType.NumericValue;
                case SdmxStructureEnumType.TimeDimension:
                    return ValueType.TimeValue;
            }

            return defaultValueType;
        }