/// <summary>
        /// Tries to create a type name segment if the given identifier refers to a known type.
        /// </summary>
        /// <param name="previous">previous segment info.</param>
        /// <param name="segment">The segment being interpreted.</param>
        /// <param name="typeNameSegment">The type name segment, if one was created.</param>
        /// <returns>Whether or not a type segment was created for the identifier.</returns>
        private bool TryCreateTypeNameSegment(SegmentInfo previous, ODataPathSegment segment, out SegmentInfo typeNameSegment)
        {
            var typeSegment = segment as TypeSegment;

            if (typeSegment == null || previous.TargetResourceSet == null)
            {
                typeNameSegment = null;
                return(false);
            }

            ResourceType targetResourceType = MetadataProviderUtils.GetResourceType(typeSegment);

            // if the new type segment prevents any results from possibly being returned, then short-circuit and throw a 404.
            ResourceType previousResourceType = previous.TargetResourceType;

            Debug.Assert(previousResourceType != null, "previous.TargetResourceType != null");
            if (!targetResourceType.IsAssignableFrom(previousResourceType) && !previousResourceType.IsAssignableFrom(targetResourceType))
            {
                throw DataServiceException.CreateBadRequestError(Strings.RequestUriProcessor_InvalidTypeIdentifier_UnrelatedType(targetResourceType.FullName, previousResourceType.FullName));
            }

            // Since we allow derived navigation properties or named streams in V1/V2, the server will generate edit links and navigation links with type segment in it.
            // Hence we need to be able to process type segment in the request even when the server MPV is set to V1/V2. But we do not want to expose new functionality
            // like filtering collections based on type, etc on V1/V2 servers. Hence only checking for MPV to be v3 or greater if the previous segment is a collection
            if (!previous.SingleResult)
            {
                VersionUtil.CheckMaxProtocolVersion(VersionUtil.Version4Dot0, this.maxProtocolVersion);
            }

            typeNameSegment = new SegmentInfo
            {
                Identifier         = targetResourceType.FullName,
                Operation          = previous.Operation,
                TargetKind         = previous.TargetKind,
                TargetSource       = previous.TargetSource,
                TargetResourceType = targetResourceType,
                SingleResult       = previous.SingleResult,
                TargetResourceSet  = previous.TargetResourceSet,
                ProjectedProperty  = previous.ProjectedProperty,
                Key = previous.Key,
                RequestExpression       = previous.RequestExpression,
                RequestEnumerable       = previous.RequestEnumerable,
                IsTypeIdentifierSegment = true
            };

            return(true);
        }
        /// <summary>
        /// Load operation imports from model's metadata provider.
        /// </summary>
        /// <param name="qualifiedName">The name of the entity set to be loaded.</param>
        /// <returns>Operation imports that are loaded.</returns>
        internal List <IEdmOperationImport> LazyLoadServiceOperationImports(string qualifiedName)
        {
            List <IEdmOperationImport> operationImports = new List <IEdmOperationImport>();

            OperationWrapper operationWrapper = this.model.MetadataProvider.TryResolveServiceOperation(qualifiedName);

            if (operationWrapper != null)
            {
                IEdmOperationImport foundOperationImport = this.model.EnsureDefaultEntityContainer().EnsureOperationImport(operationWrapper);
                if (foundOperationImport != null)
                {
                    operationImports.Add(foundOperationImport);
                }
            }
            else
            {
                var operationWrapperQaulified = this.model.MetadataProvider.TryResolveServiceOperation(this.containerName + "." + qualifiedName);
                if (operationWrapperQaulified != null)
                {
                    IEdmOperationImport foundOperationImport = this.model.EnsureDefaultEntityContainer().EnsureOperationImport(operationWrapperQaulified);
                    if (foundOperationImport != null)
                    {
                        operationImports.Add(foundOperationImport);
                    }
                }
            }

            // metadata interface in addition to the action provider interface.
            if (this.model.ActionProviderWrapper != null)
            {
                bool nameIsContainerQualified;
                var  operationName = this.model.MetadataProvider.GetNameFromContainerQualifiedName(qualifiedName, out nameIsContainerQualified);
                var  operation     = this.model.ActionProviderWrapper.TryResolveServiceAction(operationName, MetadataProviderUtils.GetResourceType((IEdmType)null));
                if (operation != null)
                {
                    // Only top level actions will have an operation import.
                    IEdmOperationImport foundOperationImport = this.model.EnsureDefaultEntityContainer().EnsureOperationImport(operation);
                    if (foundOperationImport != null)
                    {
                        operationImports.Add(foundOperationImport);
                    }
                }
            }

            return(operationImports);
        }