/// <summary>
 /// Initializes a new instance of the <see cref="AttributeMutableCore"/> class.
 /// </summary>
 /// <param name="objTarget">
 /// The agencySchemeMutable target. 
 /// </param>
 public AttributeMutableCore(IAttributeObject objTarget)
     : base(objTarget)
 {
     this._dimensionReferences = new List<string>();
     this._conceptRoles = new List<IStructureReference>();
     this._attachmentLevel = objTarget.AttachmentLevel;
     this._assignmentStatus = objTarget.AssignmentStatus;
     this._attachmentGroup = objTarget.AttachmentGroup;
     this._dimensionReferences = objTarget.DimensionReferences;
     this._primaryMeasureReference = objTarget.PrimaryMeasureReference;
     if (objTarget.ConceptRoles != null)
     {
         foreach (ICrossReference currentConceptRole in objTarget.ConceptRoles)
         {
             this._conceptRoles.Add(currentConceptRole.CreateMutableInstance());
         }
     }
 }
        /// <summary>
        ///   The validate attributeObject attributes.
        /// </summary>
        /// <exception cref="SdmxSemmanticException">Throws Validate exception.</exception>
        protected internal void ValidateAttributeAttributes()
        {
            if (this.attachmentLevel == AttributeAttachmentLevel.Null)
            {
                throw new SdmxSemmanticException(
                    ExceptionCode.ObjectMissingRequiredAttribute, this.StructureType, "attachmentLevel");
            }

            if (this.attachmentLevel == AttributeAttachmentLevel.Observation)
            {
                if (!ObjectUtil.ValidCollection(this.dimensionReferences))
                {
                    // Ensure that the primary measure reference is set if the dimension references are empty
                    this.primaryMeasureReference = PrimaryMeasure.FixedId;
                }
                else
                {
                    var parentDsd = (IDataStructureObject)this.MaintainableParent;
                    IDimension timeDimension = parentDsd.TimeDimension;
                    if (timeDimension == null)
                    {
                        // This is not an observation attributeObject as it does not include the time dimension
                        this.attachmentLevel = AttributeAttachmentLevel.DimensionGroup;
                    }
                    else
                    {
                        string timeDimensionId = timeDimension.Id;
                        if (!this.dimensionReferences.Contains(timeDimensionId))
                        {
                            // This is not an observation attributeObject as it does not include the time dimension
                            this.attachmentLevel = AttributeAttachmentLevel.DimensionGroup;
                        }
                    }
                }
            }

            if (this.assignmentStatus == null)
            {
                throw new SdmxSemmanticException(
                    ExceptionCode.ObjectMissingRequiredAttribute, this.StructureType, "assignmentStatus");
            }
            //TODO: Check err messages
            if (string.IsNullOrWhiteSpace(this.attachmentGroup) && this.attachmentLevel == AttributeAttachmentLevel.Group)
            {
                throw new SdmxSemmanticException(
                    "Attribute has specified attachment level specified as Group, but specifies the attachment groups. Either change the attachment level to group, or remove the attachment groups off the attributeObject : "
                    + this.Id);
            }

            if (!string.IsNullOrWhiteSpace(this.attachmentGroup) && this.attachmentLevel != AttributeAttachmentLevel.Group)
            {
                throw new SdmxSemmanticException(
                    "Attribute specifies an attachment group of '" + this.attachmentGroup
                    + "', but the the attachement level is not set to GROUP, it is set to  '" + this.attachmentLevel
                    + "'.  Either remove the attributeObject's reference to the '" + this.attachmentGroup
                    + "' or change the attributeObject's attachment level to GROUP");
            }

            if (this.attachmentLevel == AttributeAttachmentLevel.DimensionGroup)
            {
                if (!ObjectUtil.ValidCollection(this.dimensionReferences))
                {
                    throw new SdmxSemmanticException(
                        "Attribute specifies attachment level of 'Dimensions Group' but does not specify any dimensions");
                }
            }

            foreach (ICrossReference conceptRole in conceptRoles)
            {
                if (conceptRole.TargetReference != SdmxStructureType.GetFromEnum(SdmxStructureEnumType.Concept))
                {
                    throw new SdmxSemmanticException("Illegal concept role '" + conceptRole.TargetUrn + "'.  Concept Role must reference a concept.");
                }
            }
        }
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////BUILD FROM V1 SCHEMA                 //////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Initializes a new instance of the <see cref="AttributeObjectCore"/> class.
        /// </summary>
        /// <param name="attribute">
        /// The attributeObject. 
        /// </param>
        /// <param name="parent">
        /// The parent. 
        /// </param>
        /// <exception cref="SdmxSemmanticException">
        /// Throws Validate exception.
        /// </exception>
        /// ///
        /// <exception cref="SdmxNotImplementedException">
        /// Throws Unsupported Exception.
        /// </exception>
        public AttributeObjectCore(
            Org.Sdmx.Resources.SdmxMl.Schemas.V10.structure.AttributeType attribute, IAttributeList parent)
            : base(
                attribute, 
                SdmxStructureType.GetFromEnum(SdmxStructureEnumType.DataAttribute), 
                attribute.Annotations, 
                attribute.codelist, 
                attribute.concept, 
                parent)
        {
            this.dimensionReferences = new List<string>();
            this.conceptRoles = new List<ICrossReference>();

            if (attribute.AttachmentGroup != null)
            {
                if (attribute.AttachmentGroup.Count > 1)
                {
                    throw new SdmxSemmanticException(
                        ExceptionCode.Unsupported, "Attribute with more then one group attachment");
                }

                if (attribute.AttachmentGroup.Count == 1)
                {
                    this.attachmentGroup = attribute.AttachmentGroup[0];
                }
            }

            AttributeAttachmentLevel attachmentLevel0 = default(AttributeAttachmentLevel);
            var parentDsd = (IDataStructureObject)this.MaintainableParent;

            switch (attribute.attachmentLevel)
            {
                case Org.Sdmx.Resources.SdmxMl.Schemas.V10.structure.AttachmentLevelTypeConstants.DataSet:
                    attachmentLevel0 = AttributeAttachmentLevel.DataSet;
                    break;
                case Org.Sdmx.Resources.SdmxMl.Schemas.V10.structure.AttachmentLevelTypeConstants.Group:
                    attachmentLevel0 = AttributeAttachmentLevel.Group;
                    break;
                case Org.Sdmx.Resources.SdmxMl.Schemas.V10.structure.AttachmentLevelTypeConstants.Observation:
                    attachmentLevel0 = AttributeAttachmentLevel.Observation;
                    this.primaryMeasureReference = parentDsd.PrimaryMeasure.Id;
                    break;
                case Org.Sdmx.Resources.SdmxMl.Schemas.V10.structure.AttachmentLevelTypeConstants.Series:
                    attachmentLevel0 = AttributeAttachmentLevel.DimensionGroup;
                    {
                        foreach (IDimension currentDimension in parentDsd.GetDimensions(SdmxStructureEnumType.Dimension))
                        {
                            if (!this.dimensionReferences.Contains(currentDimension.Id))
                            {
                                this.dimensionReferences.Add(currentDimension.Id);
                            }
                        }
                    }

                    break;
                default:
                    throw new SdmxNotImplementedException(ExceptionCode.Unsupported, "Attachment:" + attribute.attachmentLevel);
            }

            this.attachmentLevel = attachmentLevel0;
            this.assignmentStatus = attribute.assignmentStatus;

            try
            {
                this.ValidateAttributeAttributes();
            }
            catch (Exception th)
            {
                throw new SdmxSemmanticException("IsError creating structure: " + this.ToString(), th);
            }
        }
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////BUILD FROM V2.1 SCHEMA                 //////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Initializes a new instance of the <see cref="AttributeObjectCore"/> class.
        /// </summary>
        /// <param name="attribute">
        /// The attributeObject. 
        /// </param>
        /// <param name="parent">
        /// The parent. 
        /// </param>
        /// <exception cref="SdmxSemmanticException">
        /// Throws Validate exception.
        /// </exception>
        public AttributeObjectCore(AttributeType attribute, IAttributeList parent)
            : base(attribute, SdmxStructureType.GetFromEnum(SdmxStructureEnumType.DataAttribute), parent)
        {
            this.dimensionReferences = new List<string>();
            this.conceptRoles = new List<ICrossReference>();
            if (attribute.AttributeRelationship != null)
            {
                AttributeRelationshipType attRelationShip = attribute.AttributeRelationship;
                if (attRelationShip.Group != null)
                {
                    // FUNC - this can also be attached to a dimension list
                    this.attachmentGroup = RefUtil.CreateLocalIdReference(attRelationShip.Group);
                    this.attachmentLevel = AttributeAttachmentLevel.Group;
                }
                else if (ObjectUtil.ValidCollection(attRelationShip.Dimension))
                {
                    // DEFAULT TO DIMENSION GROUP
                    this.attachmentLevel = AttributeAttachmentLevel.DimensionGroup;

                    foreach (LocalDimensionReferenceType dim in attRelationShip.Dimension)
                    {
                        this.dimensionReferences.Add(RefUtil.CreateLocalIdReference(dim));
                    }

                    var parentDsd = (IDataStructureObject)this.MaintainableParent;

                    foreach (IDimension currentDimension in parentDsd.GetDimensions())
                    {
                        if (this.dimensionReferences.Contains(currentDimension.Id))
                        {
                            if (currentDimension.TimeDimension)
                            {
                                // REFERENCING THE TIME DIMENSION THEREFOR OBSERVATION LEVEL
                                this.attachmentLevel = AttributeAttachmentLevel.Observation;
                                break;
                            }
                        }
                    }

                    if (ObjectUtil.ValidCollection(attRelationShip.AttachmentGroup))
                    {
                        this.attachmentGroup = RefUtil.CreateLocalIdReference(attRelationShip.AttachmentGroup.First());
                        this.attachmentLevel = AttributeAttachmentLevel.Group;
                    }
                }
                else if (attRelationShip.PrimaryMeasure != null)
                {
                    this.primaryMeasureReference = RefUtil.CreateLocalIdReference(attRelationShip.PrimaryMeasure);
                    this.attachmentLevel = AttributeAttachmentLevel.Observation;
                }
                else
                {
                    this.attachmentLevel = AttributeAttachmentLevel.DataSet;
                }
            }

            this.assignmentStatus = attribute.assignmentStatus;
            if (attribute.ConceptRole != null)
            {
                foreach (ConceptReferenceType conceptRef in attribute.ConceptRole)
                {
                    this.conceptRoles.Add(RefUtil.CreateReference(this, conceptRef));
                }
            }

            try
            {
                this.ValidateAttributeAttributes();
            }
            catch (Exception th)
            {
                throw new SdmxSemmanticException("IsError creating structure: " + this.ToString(), th);
            }
        }
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////BUILD FROM MUTABLE OBJECTS              //////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="AttributeObjectCore"/> class.
        /// </summary>
        /// <param name="attribute">
        /// The attributeObject. 
        /// </param>
        /// <param name="parent">
        /// The parent. 
        /// </param>
        /// <exception cref="SdmxSemmanticException">
        /// Throws Validate exception.
        /// </exception>
        public AttributeObjectCore(IAttributeMutableObject attribute, IAttributeList parent)
            : base(attribute, parent)
        {
            this.dimensionReferences = new List<string>();
            this.conceptRoles = new List<ICrossReference>();
            try
            {
                this.attachmentLevel = attribute.AttachmentLevel;
                this.assignmentStatus = attribute.AssignmentStatus;
                this.attachmentGroup = attribute.AttachmentGroup;
                if (attribute.DimensionReferences != null)
                {
                    this.dimensionReferences = new List<string>(attribute.DimensionReferences);
                }

                if (attribute.ConceptRoles != null)
                {
                    foreach (IStructureReference currentConceptRole in attribute.ConceptRoles)
                    {
                        this.conceptRoles.Add(new CrossReferenceImpl(this, currentConceptRole));
                    }
                }

                this.primaryMeasureReference = attribute.PrimaryMeasureReference;
                this.ValidateAttributeAttributes();
            }
            catch (Exception th)
            {
                throw new SdmxSemmanticException("IsError creating structure: " + this.ToString(), th);
            }
        }
		private IList<IAttributeObjectBase> GetAttribute(
				AttributeAttachmentLevel type) {
			IList<IAttributeObjectBase> returnList = new List<IAttributeObjectBase>();
			/* foreach */
			foreach (IAttributeObjectBase currentAttribtue  in  _attributes) {
				if (currentAttribtue.AttachmentLevel.Equals(type)) {
					returnList.Add(currentAttribtue);
				}
			}
			return returnList;
		}