/// <summary>
        /// Validates the specific.
        /// </summary>
        /// <param name="mutableObject">
        /// The mutable object.
        /// </param>
        /// <param name="structureType">
        /// Type of the structure.
        /// </param>
        /// <param name="stubs">
        /// if set to <c>true</c> [stubs].
        /// </param>
        /// <param name="specificStructureType">
        /// Type of the specific structure.
        /// </param>
        /// <param name="structureReference">
        /// The structure reference.
        /// </param>
        private static void ValidateSpecific(
            IMutableObjects mutableObject, 
            BaseConstantType<SdmxStructureEnumType> structureType, 
            bool stubs, 
            BaseConstantType<SdmxStructureEnumType> specificStructureType, 
            IStructureReference structureReference)
        {
            switch (structureType.EnumType)
            {
                case SdmxStructureEnumType.Categorisation:
                    switch (specificStructureType.EnumType)
                    {
                        case SdmxStructureEnumType.Categorisation:
                            break;
                        case SdmxStructureEnumType.CategoryScheme:
                            Assert.IsNotEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.CodeList:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.ConceptScheme:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.Dataflow:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.Dsd:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.HierarchicalCodelist:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                    }

                    break;
                case SdmxStructureEnumType.CategoryScheme:

                    // if we have stubs then no categorisations can be retrieved. 
                    // as a result we cannot get other structures.
                    if (!stubs)
                    {
                        switch (specificStructureType.EnumType)
                        {
                            case SdmxStructureEnumType.Categorisation:
                                Assert.IsNotEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                                Assert.IsNotEmpty(mutableObject.Categorisations, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                                break;
                            case SdmxStructureEnumType.CategoryScheme:
                                Assert.IsNotEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                                break;
                            case SdmxStructureEnumType.CodeList:
                                Assert.IsNotEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                                Assert.IsNotEmpty(mutableObject.Codelists, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                                break;
                            case SdmxStructureEnumType.ConceptScheme:
                                Assert.IsNotEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                                Assert.IsNotEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                                break;
                            case SdmxStructureEnumType.Dataflow:
                                Assert.IsNotEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                                Assert.IsNotEmpty(mutableObject.Dataflows, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                                break;
                            case SdmxStructureEnumType.Dsd:
                                Assert.IsNotEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                                Assert.IsNotEmpty(mutableObject.DataStructures, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                                break;
                            case SdmxStructureEnumType.HierarchicalCodelist:
                                Assert.IsNotEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                                Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                                break;
                        }
                    }

                    break;
                case SdmxStructureEnumType.CodeList:
                    switch (specificStructureType.EnumType)
                    {
                        case SdmxStructureEnumType.Categorisation:
                            if (!stubs)
                            {
                                Assert.IsNotEmpty(mutableObject.Categorisations, structureReference.ToString());
                            }

                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());

                            break;
                        case SdmxStructureEnumType.CategoryScheme:
                            if (!stubs)
                            {
                                Assert.IsNotEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            }

                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.CodeList:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.ConceptScheme:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.Dataflow:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.Dsd:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.HierarchicalCodelist:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());

                            // Assert.IsNotEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                    }

                    break;
                case SdmxStructureEnumType.ConceptScheme:
                    switch (specificStructureType.EnumType)
                    {
                        case SdmxStructureEnumType.Categorisation:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.CategoryScheme:
                            Assert.IsNotEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.CodeList:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.ConceptScheme:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.Dataflow:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.Dsd:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.HierarchicalCodelist:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                    }

                    break;
                case SdmxStructureEnumType.Dataflow:
                    switch (specificStructureType.EnumType)
                    {
                        case SdmxStructureEnumType.Categorisation:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.CategoryScheme:
                            Assert.IsNotEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.CodeList:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.ConceptScheme:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.Dataflow:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.Dsd:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.HierarchicalCodelist:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                    }

                    break;
                case SdmxStructureEnumType.Dsd:
                    switch (specificStructureType.EnumType)
                    {
                        case SdmxStructureEnumType.Categorisation:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.CategoryScheme:
                            Assert.IsNotEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.CodeList:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.ConceptScheme:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.Dataflow:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.Dsd:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.HierarchicalCodelist:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                    }

                    break;
                case SdmxStructureEnumType.HierarchicalCodelist:
                    switch (specificStructureType.EnumType)
                    {
                        case SdmxStructureEnumType.Categorisation:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.CategoryScheme:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.CodeList:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.ConceptScheme:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.Dataflow:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.Dsd:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                        case SdmxStructureEnumType.HierarchicalCodelist:
                            Assert.IsEmpty(mutableObject.CategorySchemes, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Categorisations, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Dataflows, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.DataStructures, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.Codelists, structureReference.ToString());
                            Assert.IsEmpty(mutableObject.ConceptSchemes, structureReference.ToString());
                            Assert.IsNotEmpty(mutableObject.HierarchicalCodelists, structureReference.ToString());
                            break;
                    }

                    break;
            }
        }
        /// <summary>
        /// The validate parents.
        /// </summary>
        /// <param name="mutableObject">
        /// The mutable object.
        /// </param>
        /// <param name="structureType">
        /// The structure type.
        /// </param>
        /// <param name="stubs">
        /// if we deal with stubs
        /// </param>
        /// <param name="structureReference">
        /// The structure Reference.
        /// </param>
        private static void ValidateParents(IMutableObjects mutableObject, BaseConstantType<SdmxStructureEnumType> structureType, bool stubs, IStructureReference structureReference)
        {
            switch (structureType.EnumType)
            {
                case SdmxStructureEnumType.Categorisation:
                    break;
                case SdmxStructureEnumType.CategoryScheme:
                    {
                        Assert.IsNotEmpty(mutableObject.Categorisations, structureReference.ToString());
                        if (!stubs)
                        {
                            var referencedByParent =
                                (from m in mutableObject.Categorisations select new StructureReferenceImpl(m.CategoryReference.MaintainableReference, m.CategoryReference.MaintainableStructureEnumType))
                                    .Distinct().ToArray();
                            var got = from o in mutableObject.CategorySchemes select _fromMutable.Build(o);
                            if (referencedByParent.Length > 0)
                            {
                                CollectionAssert.IsSubsetOf(referencedByParent, got, structureReference.ToString());
                            }
                        }
                    }

                    break;
                case SdmxStructureEnumType.CodeList:
                    {
                        if (!mutableObject.Codelists.All(o => "MA".Equals(o.AgencyId)))
                        {
                            Assert.IsTrue(mutableObject.DataStructures.Count + mutableObject.HierarchicalCodelists.Count > 0, structureReference.ToString());
                        }

                        if (!stubs)
                        {
                            var referencedByParent = GetComponentReferences(mutableObject, structureType);
                            var got = (from o in mutableObject.Codelists select _fromMutable.Build(o)).Distinct<IStructureReference>().ToArray();

                            CollectionAssert.IsSubsetOf(superset: referencedByParent, subset: got, message: structureReference.ToString());
                            if (mutableObject.HierarchicalCodelists.Count > 0)
                            {
                                var hclReferences =
                                    (from m in mutableObject.HierarchicalCodelists from codelistRefMutableObject in m.CodelistRef select codelistRefMutableObject.CodelistReference).Distinct()
                                        .ToArray();

                                CollectionAssert.IsSubsetOf(superset: hclReferences, subset: got, message: structureReference.ToString());
                            }
                        }
                    }

                    break;
                case SdmxStructureEnumType.ConceptScheme:
                    {
                        Assert.IsNotEmpty(mutableObject.DataStructures, structureReference.ToString());
                        if (!stubs)
                        {
                            var referencedByParent = GetComponentReferences(mutableObject, structureType);
                            var got = from o in mutableObject.ConceptSchemes select _fromMutable.Build(o);

                            CollectionAssert.IsSubsetOf(superset: referencedByParent, subset: got, message: structureReference.ToString());
                        }
                    }

                    break;
                case SdmxStructureEnumType.Dataflow:
                    {
                        Assert.IsNotEmpty(mutableObject.Categorisations, structureReference.ToString());
                        if (!stubs)
                        {
                            var referencedByParent = (from m in mutableObject.Categorisations select m.StructureReference).Distinct().ToArray();
                            var got = (from o in mutableObject.Dataflows select _fromMutable.Build(o)).Distinct<IStructureReference>().ToArray();

                            if (referencedByParent.Length > 0)
                            {
                                CollectionAssert.IsSubsetOf(referencedByParent, got, structureReference.ToString());
                            }
                        }
                    }

                    break;
                case SdmxStructureEnumType.Dsd:
                    {
                        Assert.IsNotEmpty(mutableObject.Dataflows, structureReference.ToString());
                        if (!stubs)
                        {
                            var referencedByParent = (from m in mutableObject.Dataflows select m.DataStructureRef).Distinct().ToArray();
                            var got = from o in mutableObject.DataStructures select _fromMutable.Build(o);

                            CollectionAssert.IsSubsetOf(referencedByParent, got, structureReference.ToString());
                        }
                    }

                    break;
                case SdmxStructureEnumType.HierarchicalCodelist:
                    break;
            }
        }
        /// <summary>
        /// Extracts the information.
        /// </summary>
        /// <param name="structureReference">The structure reference.</param>
        /// <returns>The info from <paramref name="structureReference"/></returns>
        private static string ExtractInfo(IStructureReference structureReference)
        {
            var info = new StringBuilder(structureReference.ToString());
            var constrainableStructureReference = structureReference as IConstrainableStructureReference;
            if (constrainableStructureReference != null)
            {
                foreach (var keyValuese in constrainableStructureReference.ConstraintObject.IncludedCubeRegion.KeyValues)
                {
                    info.AppendFormat("Key: {0}, Values : [{1}]\n", keyValuese.Id, string.Join(",", keyValuese.Values));
                }
            }

            return info.ToString();
        }