/// <summary>
        /// Constructs an instance of an <see cref="NavigationSourceLinkBuilderAnnotation" /> class.
        /// </summary>
        /// <param name="navigationSource">The navigation source for which the link builder is being constructed.</param>
        /// <param name="idLinkBuilder">The ID link builder which is used to build the ID link.</param>
        /// <param name="editLinkBuilder">The Edit link builder which is used to build the Edit link.</param>
        /// <param name="readLinkBuilder">The Read link builder which is used to build the Read link.</param>
        public NavigationSourceLinkBuilderAnnotation(
            IEdmNavigationSource navigationSource,
            SelfLinkBuilder <Uri> idLinkBuilder,
            SelfLinkBuilder <Uri> editLinkBuilder,
            SelfLinkBuilder <Uri> readLinkBuilder)
        {
            if (navigationSource == null)
            {
                throw new ArgumentNullException(nameof(navigationSource));
            }

            _idLinkBuilder   = idLinkBuilder;
            _editLinkBuilder = editLinkBuilder;
            _readLinkBuilder = readLinkBuilder;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="NavigationSourceLinkBuilderAnnotation"/> class.
        /// </summary>
        /// <param name="navigationSource">The navigation source for which the link builder is being constructed.</param>
        /// <param name="model">The EDM model that this navigation source belongs to.</param>
        /// <remarks>This constructor creates a link builder that generates URL's that follow OData conventions for the given navigation source.</remarks>
        public NavigationSourceLinkBuilderAnnotation(IEdmNavigationSource navigationSource, IEdmModel model)
        {
            if (navigationSource == null)
            {
                throw Error.ArgumentNull(nameof(navigationSource));
            }

            if (model == null)
            {
                throw Error.ArgumentNull(nameof(model));
            }

            IEdmEntityType elementType = navigationSource.EntityType();
            IEnumerable <IEdmEntityType> derivedTypes = model.FindAllDerivedTypes(elementType).Cast <IEdmEntityType>();

            // Add navigation link builders for all navigation properties of entity.
            foreach (IEdmNavigationProperty navigationProperty in elementType.NavigationProperties())
            {
                Func <ResourceContext, IEdmNavigationProperty, Uri> navigationLinkFactory =
                    (resourceContext, navProperty) => resourceContext.GenerateNavigationPropertyLink(navProperty, includeCast: false);
                AddNavigationPropertyLinkBuilder(navigationProperty, new NavigationLinkBuilder(navigationLinkFactory, followsConventions: true));
            }

            // Add navigation link builders for all navigation properties in derived types.
            bool derivedTypesDefineNavigationProperty = false;

            foreach (IEdmEntityType derivedEntityType in derivedTypes)
            {
                foreach (IEdmNavigationProperty navigationProperty in derivedEntityType.DeclaredNavigationProperties())
                {
                    derivedTypesDefineNavigationProperty = true;
                    Func <ResourceContext, IEdmNavigationProperty, Uri> navigationLinkFactory =
                        (resourceContext, navProperty) => resourceContext.GenerateNavigationPropertyLink(navProperty, includeCast: true);
                    AddNavigationPropertyLinkBuilder(navigationProperty, new NavigationLinkBuilder(navigationLinkFactory, followsConventions: true));
                }
            }

            Func <ResourceContext, Uri> selfLinkFactory =
                (resourceContext) => resourceContext.GenerateSelfLink(includeCast: derivedTypesDefineNavigationProperty);

            IdLinkBuilder = new SelfLinkBuilder <Uri>(selfLinkFactory, followsConventions: true);
        }
        /// <summary>
        /// Sets the Read link builder for the given <see cref="IEdmNavigationSource"/>.
        /// </summary>
        /// <param name="model">The Edm model.</param>
        /// <param name="navigationSource">The navigation source.</param>
        /// <param name="readLinkBuilder">The Read link builder.</param>
        public static void HasReadLink(this IEdmModel model, IEdmNavigationSource navigationSource, SelfLinkBuilder <Uri> readLinkBuilder)
        {
            NavigationSourceLinkBuilderAnnotation annotation = model.GetNavigationSourceLinkBuilder(navigationSource);

            Contract.Assert(annotation != null);
            annotation.ReadLinkBuilder = readLinkBuilder;
        }