private async Task<Resource[]> QueryReference(IQueryParameters parameters, string correlationIdentifier)
        {
            if (null == parameters)
            {
                throw new ArgumentNullException(FileProvider.ArgumentNameParameters);
            }

            if (string.IsNullOrWhiteSpace(correlationIdentifier))
            {
                throw new ArgumentNullException(FileProvider.ArgumentNameCorrelationIdentifier);
            }

            if (null == parameters.RequestedAttributePaths || !parameters.RequestedAttributePaths.Any())
            {
                throw new NotSupportedException(ProvisioningAgentResources.ExceptionUnsupportedQuery);
            }

            string selectedAttribute = parameters.RequestedAttributePaths.SingleOrDefault();
            if (string.IsNullOrWhiteSpace(selectedAttribute))
            {
                throw new NotSupportedException(ProvisioningAgentResources.ExceptionUnsupportedQuery);
            }
            ProvisioningAgentMonitor.Instance.Inform(selectedAttribute, true, correlationIdentifier);

            if
            (
                !string.Equals(
                    selectedAttribute,
                    Microsoft.SystemForCrossDomainIdentityManagement.AttributeNames.Identifier,
                    StringComparison.OrdinalIgnoreCase)
            )
            {
                throw new NotSupportedException(ProvisioningAgentResources.ExceptionUnsupportedQuery);
            }

            if (null == parameters.AlternateFilters)
            {
                throw new ArgumentException(ProvisioningAgentResources.ExceptionInvalidParameters);
            }

            if (string.IsNullOrWhiteSpace(parameters.SchemaIdentifier))
            {
                throw new ArgumentException(ProvisioningAgentResources.ExceptionInvalidParameters);
            }

            string informationAlternateFilterCount = parameters.AlternateFilters.Count.ToString(CultureInfo.InvariantCulture);
            ProvisioningAgentMonitor.Instance.Inform(informationAlternateFilterCount, true, correlationIdentifier);
            if (parameters.AlternateFilters.Count != 1)
            {
                string exceptionMessage =
                    string.Format(
                        CultureInfo.InvariantCulture,
                        ProvisioningAgentResources.ExceptionFilterCountTemplate,
                        1,
                        parameters.AlternateFilters.Count);
                throw new NotSupportedException(exceptionMessage);
            }

            IReadOnlyCollection<string> requestedColumns = this.IdentifyRequestedColumns(parameters);

            IFilter filterPrimary = parameters.AlternateFilters.Single();
            if (null == filterPrimary.AdditionalFilter)
            {
                throw new ArgumentException(ProvisioningAgentResources.ExceptionInvalidParameters);
            }

            IFilter filterAdditional = filterPrimary.AdditionalFilter;

            if (filterAdditional.AdditionalFilter != null)
            {
                throw new NotSupportedException(ProvisioningAgentResources.ExceptionUnsupportedQuery);
            }

            IReadOnlyCollection<IFilter> filters =
                new IFilter[]
                    {
                        filterPrimary,
                        filterAdditional
                    };

            IFilter filterIdentifier =
                filters
                .SingleOrDefault(
                    (IFilter item) =>
                        string.Equals(
                            AttributeNames.Identifier,
                            item.AttributePath,
                            StringComparison.OrdinalIgnoreCase));
            if (null == filterIdentifier)
            {
                throw new NotSupportedException(ProvisioningAgentResources.ExceptionUnsupportedQuery);
            }

            IRow row;
            IFilter filterReference =
                filters
                .SingleOrDefault(
                    (IFilter item) =>
                            string.Equals(
                                AttributeNames.Members,
                                item.AttributePath,
                                StringComparison.OrdinalIgnoreCase));
            if (filterReference != null)
            {
                Dictionary<string, string> columns =
                new Dictionary<string, string>()
                    {
                        {
                            AttributeNames.Schemas,
                            parameters.SchemaIdentifier
                        },
                        {
                            AttributeNames.Identifier,
                            filterIdentifier.ComparisonValue
                        },
                        {
                            filterReference.AttributePath,
                            filterReference.ComparisonValue
                        }
                    };

                IReadOnlyCollection<IRow> rows = await this.file.Query(columns);
                if (null == rows || !rows.Any())
                {
                    return new Resource[0];
                }

                row = await this.file.ReadRow(filterIdentifier.ComparisonValue);
            }
            else
            {
                filterReference =
                    filters
                    .SingleOrDefault(
                        (IFilter item) =>
                                string.Equals(
                                    AttributeNames.Manager,
                                    item.AttributePath,
                                    StringComparison.OrdinalIgnoreCase));
                if (null == filterReference)
                {
                    throw new NotSupportedException(ProvisioningAgentResources.ExceptionUnsupportedQuery);
                }

                row = await this.file.ReadRow(filterIdentifier.ComparisonValue);
                if
                (
                        null == row.Columns
                    || !row
                        .Columns
                        .Any(
                            (KeyValuePair<string, string> columnItem) =>
                                    string.Equals(columnItem.Key, filterReference.AttributePath, StringComparison.Ordinal)
                                && string.Equals(columnItem.Value, filterReference.ComparisonValue, StringComparison.Ordinal))
                )
                {
                    return new Resource[0];
                }
            }

            string rowSchema = null;
            if
            (
                    !row.Columns.TryGetValue(AttributeNames.Schemas, out rowSchema)
                || !string.Equals(rowSchema, parameters.SchemaIdentifier, StringComparison.Ordinal)
            )
            {
                return new Resource[0];
            }

            IRow reducedRow = FileProvider.FilterColumns(row, requestedColumns);

            ResourceFactory resourceFactory;
            switch (rowSchema)
            {
                case SchemaIdentifiers.Core2EnterpriseUser:
                    resourceFactory = new UserFactory(reducedRow);
                    break;
                case SchemaIdentifiers.WindowsAzureActiveDirectoryGroup:
                    resourceFactory = new GroupFactory(reducedRow);
                    break;
                default:
                    throw new NotSupportedException(parameters.SchemaIdentifier);
            }

            Resource resource = resourceFactory.CreateResource();
            Resource[] results =
                new Resource[]
                {
                    resource
                };
            return results;
        }
        public override async Task<Resource> Retrieve(IResourceRetrievalParameters parameters, string correlationIdentifier)
        {
            if (null == parameters)
            {
                throw new ArgumentNullException(FileProvider.ArgumentNameParameters);
            }

            if (string.IsNullOrWhiteSpace(correlationIdentifier))
            {
                throw new ArgumentNullException(FileProvider.ArgumentNameCorrelationIdentifier);
            }

            if (null == parameters.ResourceIdentifier)
            {
                throw new ArgumentException(ProvisioningAgentResources.ExceptionInvalidParameters);
            }

            if (string.IsNullOrWhiteSpace(parameters.ResourceIdentifier.Identifier))
            {
                throw new ArgumentException(ProvisioningAgentResources.ExceptionInvalidResourceIdentifier);
            }

            if (string.IsNullOrWhiteSpace(parameters.SchemaIdentifier))
            {
                throw new ArgumentException(ProvisioningAgentResources.ExceptionInvalidParameters);
            }

            string informationStarting =
                string.Format(
                    CultureInfo.InvariantCulture,
                    AzureTestProvisioningResources.InformationRetrieving,
                    parameters.SchemaIdentifier,
                    parameters.ResourceIdentifier.Identifier);
            ProvisioningAgentMonitor.Instance.Inform(informationStarting, true, correlationIdentifier);

            IReadOnlyCollection<string> columnNames = this.IdentifyRequestedColumns(parameters);
            
            IRow row = await this.file.ReadRow(parameters.ResourceIdentifier.Identifier);
            if (null == row || null == row.Columns)
            {
                return null;
            }

            string rowSchema = null;
            if
            (
                    !row.Columns.TryGetValue(AttributeNames.Schemas, out rowSchema)
                ||  !string.Equals(rowSchema, parameters.SchemaIdentifier, StringComparison.Ordinal)
            )
            {
                return null;
            }

            IRow reducedRow = FileProvider.FilterColumns(row, columnNames);

            ResourceFactory resourceFactory;
            switch (rowSchema)
            {
                case SchemaIdentifiers.Core2EnterpriseUser:
                    resourceFactory = new UserFactory(reducedRow);
                    break;
                case SchemaIdentifiers.WindowsAzureActiveDirectoryGroup:
                    resourceFactory = new GroupFactory(reducedRow);
                    break;
                default:
                    throw new NotSupportedException(parameters.SchemaIdentifier);
            }

            Resource result = resourceFactory.CreateResource();
            return result;
        }
        public override async Task<Resource[]> Query(IQueryParameters parameters, string correlationIdentifier)
        {
            if (null == parameters)
            {
                throw new ArgumentNullException(FileProvider.ArgumentNameParameters);
            }

            if (string.IsNullOrWhiteSpace(correlationIdentifier))
            {
                throw new ArgumentNullException(FileProvider.ArgumentNameCorrelationIdentifier);
            }

            if (null == parameters.AlternateFilters)
            {
                throw new ArgumentException(ProvisioningAgentResources.ExceptionInvalidParameters);
            }

            if (string.IsNullOrWhiteSpace(parameters.SchemaIdentifier))
            {
                throw new ArgumentException(ProvisioningAgentResources.ExceptionInvalidParameters);
            }

            string informationAlternateFilterCount = parameters.AlternateFilters.Count.ToString(CultureInfo.InvariantCulture);
            ProvisioningAgentMonitor.Instance.Inform(informationAlternateFilterCount, true, correlationIdentifier);
            if (parameters.AlternateFilters.Count != 1)
            {
                string exceptionMessage =
                    string.Format(
                        CultureInfo.InvariantCulture,
                        ProvisioningAgentResources.ExceptionFilterCountTemplate,
                        1,
                        parameters.AlternateFilters.Count);
                throw new NotSupportedException(exceptionMessage);
            }

            Resource[] results;
            IFilter queryFilter = parameters.AlternateFilters.Single();
            if (queryFilter.AdditionalFilter != null)
            {
                results = await this.QueryReference(parameters, correlationIdentifier);
                return results;
            }

            IReadOnlyCollection<string> requestedColumns = this.IdentifyRequestedColumns(parameters);

            if (string.IsNullOrWhiteSpace(queryFilter.AttributePath))
            {
                throw new ArgumentException(ProvisioningAgentResources.ExceptionInvalidParameters);
            }

            if (string.IsNullOrWhiteSpace(queryFilter.ComparisonValue))
            {
                throw new ArgumentException(ProvisioningAgentResources.ExceptionInvalidParameters);
            }

            Dictionary<string, string> columns =
                new Dictionary<string, string>()
                    {
                        {
                            AttributeNames.Schemas,
                            parameters.SchemaIdentifier
                        },
                        {
                            queryFilter.AttributePath,
                            queryFilter.ComparisonValue
                        }
                    };
            IReadOnlyCollection<IRow> rows = await this.file.Query(columns);
            if (null == rows)
            {
                return new Resource[0];
            }

            IList<Resource> resources = new List<Resource>(rows.Count);
            foreach (IRow row in rows)
            {
                string rowSchema = null;
                if
                (
                        !row.Columns.TryGetValue(AttributeNames.Schemas, out rowSchema)
                    ||  !string.Equals(rowSchema, parameters.SchemaIdentifier, StringComparison.Ordinal)
                )
                {
                    continue;
                }

                IRow reducedRow = FileProvider.FilterColumns(row, requestedColumns);

                ResourceFactory resourceFactory;
                switch (rowSchema)
                {
                    case SchemaIdentifiers.Core2EnterpriseUser:
                        resourceFactory = new UserFactory(reducedRow);
                        break;
                    case SchemaIdentifiers.WindowsAzureActiveDirectoryGroup:
                        resourceFactory = new GroupFactory(reducedRow);
                        break;
                    default:
                        throw new NotSupportedException(parameters.SchemaIdentifier);
                }

                Resource resource = resourceFactory.CreateResource();
                resources.Add(resource);
            }

            results = resources.ToArray();
            return results;
        }