/// <summary>
        /// Builds a <see cref="IDataQuery"/> list from a message that contains one or more data queries
        /// </summary>
        /// <param name="dataQueryLocation">
        /// The data location
        /// </param>
        /// <param name="beanRetrievalManager">
        /// optional, if given will retrieve the key family bean the query is for
        /// </param>
        /// <returns>
        /// a <see cref="IDataQuery"/> list
        /// </returns>
        public IList<IDataQuery> BuildDataQuery(
            ISdmxXmlStream dataQueryLocation, ISdmxObjectRetrievalManager beanRetrievalManager)
        {
            if (!dataQueryLocation.HasReader)
            {
                throw new ArgumentException("ISdmxXmlStream doesnt have a Reader", "dataQueryLocation");
            }

            this._log.Debug("DataParseManagerImpl.buildDataQuery");

            switch (dataQueryLocation.SdmxVersion)
            {
                case SdmxSchemaEnumType.VersionOne:
                    QueryMessage queryV1 = MessageFactory.Load<QueryMessage, QueryMessageType>(dataQueryLocation.Reader);
                    return this._dataQueryBuilder.BuildDataQuery(queryV1.Query, beanRetrievalManager);
                case SdmxSchemaEnumType.VersionTwo:
                    Org.Sdmx.Resources.SdmxMl.Schemas.V20.message.QueryMessage queryV2 =
                        Org.Sdmx.Resources.SdmxMl.Schemas.V20.message.QueryMessage.Load(dataQueryLocation.Reader);
                    return this._dataQueryBuilder.BuildDataQuery(queryV2.Query, beanRetrievalManager);
                case SdmxSchemaEnumType.VersionTwoPointOne:
                    throw new ArgumentException("Build Data Query concerns sdmx messages of schema version 1.0 and 2.0 ");
                default:
                    throw new SdmxNotImplementedException(
                        ExceptionCode.Unsupported, "buildDataQuery in version " + dataQueryLocation.SdmxVersion);
            }
        }
        /// <summary>
        /// Processes the SDMX at the given URI and returns a workspace containing the information on what was being queried.
        ///     <p/>
        ///     The Query parsing manager processes queries that are in a RegistryInterface document, this includes queries for
        ///     Provisions, Registrations and Structures.  It also processes Queries that are in a QueryMessage document
        /// </summary>
        /// <param name="dataLocation">
        /// The data location of the query
        /// </param>
        /// <returns>
        /// The <see cref="IQueryWorkspace"/> from <paramref name="dataLocation"/>.
        /// </returns>
        public virtual IQueryWorkspace ParseQueries(ISdmxXmlStream dataLocation)
        {
            LoggingUtil.Debug(_log, "Parse Structure request, for xml at location: " + dataLocation);

            SdmxSchemaEnumType schemaVersion = dataLocation.SdmxVersion;

            // NOTE validation is performed by XmlReader from XMLParser.CreateSdmxMlReader
            ////XMLParser.ValidateXml(dataLocation, schemaVersion);
            LoggingUtil.Debug(_log, "XML VALID");
            MessageEnumType messageType = dataLocation.MessageType;
            using (XmlReader reader = dataLocation.Reader)
            {
                if (schemaVersion == SdmxSchemaEnumType.VersionOne || schemaVersion == SdmxSchemaEnumType.VersionTwo)
                {
                    switch (messageType)
                    {
                        case MessageEnumType.Query:
                            return this.ProcessQueryMessage(reader, schemaVersion);
                        case MessageEnumType.RegistryInterface:
                            {
                                RegistryMessageEnumType registryMessageType = dataLocation.RegistryType;
                                RegistryMessageType registryMessage = RegistryMessageType.GetFromEnum(registryMessageType);
                                if (registryMessage.IsQueryRequest())
                                {
                                    try
                                    {
                                        return this.ProcessRegistryQueryMessage(reader, schemaVersion, registryMessageType);
                                    }
                                    catch (Exception th)
                                    {
                                        throw new ParseException(th, DatasetActionEnumType.Information, false, registryMessage.ArtifactType);
                                    }
                                }

                                throw new SdmxNotImplementedException(ExceptionCode.Unsupported, "Expected query message - type found : " + registryMessageType);
                            }
                    }
                }
                else if (schemaVersion == SdmxSchemaEnumType.VersionTwoPointOne)
                {
                    if (messageType == MessageEnumType.RegistryInterface)
                    {
                        RegistryMessageEnumType registryMessageType = dataLocation.RegistryType;
                        return ProcessRegistryQueryMessage(reader, schemaVersion, registryMessageType);
                    }
                    else
                    {
                        QueryMessageEnumType queryMessageType = dataLocation.QueryMessageTypes.FirstOrDefault(); // Only one *Where element according to 2.1 Schema
                        if (messageType != MessageEnumType.Query)
                        {
                            //TODO should this be IllegalArgumentException?
                            throw new SdmxNotImplementedException(ExceptionCode.Unsupported, "Not a structure query message:" + queryMessageType);
                        }
                        return ProcessQueryMessage(reader, queryMessageType);
                    }
                }
            }

            throw new SdmxNotImplementedException(ExceptionCode.Unsupported, messageType);
        }
        /// <summary>
        /// Parses a structure document OR a Registry document that contains structures.
        /// </summary>
        /// <param name="reader">
        /// The reader.
        /// </param>
        /// <param name="settings">
        /// - addition settings to perform when parsing
        /// </param>
        /// <param name="retrievalManager">
        /// The retrieval manager.
        /// </param>
        /// <returns>
        /// StructureWorkspace - from this structures can be retrieved in any format required
        /// </returns>
        public IStructureWorkspace ParseStructures(ISdmxXmlStream reader, ResolutionSettings settings, ISdmxObjectRetrievalManager retrievalManager)
        {
            if (!reader.HasReader)
            {
                throw new ArgumentException("ISdmxXmlStream doesnt have a Reader", "reader");
            }

            IMutableObjects objects = null;
            switch (reader.MessageType)
            {
                case MessageEnumType.RegistryInterface:
                    IRegistryInfo registryInfo = this._registryReader.Read(reader.Reader);
                    if (registryInfo.HasQueryStructureResponse && registryInfo.QueryStructureResponse.StatusMessage.Status != Status.Error)
                    {
                        objects = registryInfo.QueryStructureResponse.Structure;
                    }

                    break;
                case MessageEnumType.Structure:
                    objects = this._structureReader.Read(reader.Reader);
                    break;
            }

            if (objects == null)
            {
                objects = new MutableObjectsImpl();
            }

            ISdmxObjects immutableBeans = objects.ImmutableObjects;
            return this.BuildWorkspace(immutableBeans, settings, retrievalManager);
        }