private static Tuple <ICollection <IHypermediaPath>, ResourcePathMode> CreateResourcePathParts(Type clrResourceType, IResourceType resourceType, ICollection <IHypermediaPath> resourceBasePath, IRelationshipInfo resourcePreviousRelationship)
        {
            Contract.Requires(clrResourceType != null);
            Contract.Requires(resourceType != null);

            ResourcePathMode resourcePathMode;

            if (resourcePreviousRelationship == null)
            {
                var apiCollectionPathSegment = resourceType.HypermediaInfo.ApiCollectionPathSegment;

                var hypermediaPath = default(IHypermediaPath);
                if (!resourceType.IsSingleton())
                {
                    hypermediaPath   = new ResourceCollectionHypermediaPath(clrResourceType, apiCollectionPathSegment);
                    resourcePathMode = ResourcePathMode.IncludeApiId;
                }
                else
                {
                    hypermediaPath   = new SingletonHypermediaPath(clrResourceType, apiCollectionPathSegment);
                    resourcePathMode = ResourcePathMode.IgnoreApiId;
                }

                resourceBasePath.Add(hypermediaPath);
            }
            else
            {
                var previousRelationshipCardinality = resourcePreviousRelationship.ToCardinality;
                var apiRelationshipRelPathSegment   = resourcePreviousRelationship.ApiRelPathSegment;
                switch (previousRelationshipCardinality)
                {
                case RelationshipCardinality.ToOne:
                {
                    var toOneResourceHypermediaPath = new ToOneResourceHypermediaPath(clrResourceType, apiRelationshipRelPathSegment);
                    resourceBasePath.Add(toOneResourceHypermediaPath);
                    resourcePathMode = ResourcePathMode.IgnoreApiId;
                }
                break;

                case RelationshipCardinality.ToMany:
                {
                    var toManyResourceHypermediaPath = new ToManyResourceCollectionHypermediaPath(clrResourceType, apiRelationshipRelPathSegment);
                    resourceBasePath.Add(toManyResourceHypermediaPath);
                    resourcePathMode = ResourcePathMode.IncludeApiId;
                }
                break;

                default:
                {
                    var detail = InfrastructureErrorStrings.InternalErrorExceptionDetailUnknownEnumerationValue
                                 .FormatWith(typeof(RelationshipCardinality).Name, previousRelationshipCardinality);
                    throw new InternalErrorException(detail);
                }
                }
            }

            var resourcePathParts = new Tuple <ICollection <IHypermediaPath>, ResourcePathMode>(resourceBasePath, resourcePathMode);

            return(resourcePathParts);
        }
        public static void MapClrIdToDomResource(this IResourceType resourceType, DomReadWriteResource domResource, object clrResource)
        {
            Contract.Requires(resourceType != null);
            Contract.Requires(domResource != null);

            if (resourceType.IsSingleton())
            {
                return;
            }

            if (clrResource == null)
            {
                return;
            }

            domResource.CreateAndAddNode(() => DomId.CreateFromClrResource(resourceType, clrResource));
        }
        private static void AddPath(IResourceType resourceType,
                                    Type clrResourceType,
                                    string apiId,
                                    IRelationshipInfo nextRelationship,
                                    ref List <IHypermediaPath> resourceBasePath,
                                    ref ResourcePathMode resourcePathMode,
                                    ref IRelationshipInfo resourcePreviousRelationship)
        {
            Contract.Requires(resourceType != null);
            Contract.Requires(clrResourceType != null);
            Contract.Requires(String.IsNullOrWhiteSpace(apiId) == false);
            Contract.Requires(nextRelationship != null);
            Contract.Requires(resourceBasePath != null);

            if (resourcePreviousRelationship == null)
            {
                var apiCollectionPathSegment = resourceType.HypermediaInfo.ApiCollectionPathSegment;

                var hypermediaPath = default(IHypermediaPath);
                if (!resourceType.IsSingleton())
                {
                    hypermediaPath   = new ResourceHypermediaPath(clrResourceType, apiCollectionPathSegment, apiId);
                    resourcePathMode = ResourcePathMode.IncludeApiId;
                }
                else
                {
                    hypermediaPath   = new SingletonHypermediaPath(clrResourceType, apiCollectionPathSegment);
                    resourcePathMode = ResourcePathMode.IgnoreApiId;
                }

                resourceBasePath.Add(hypermediaPath);
                resourcePreviousRelationship = nextRelationship;
                return;
            }

            var previousRelationshipCardinality = resourcePreviousRelationship.ToCardinality;
            var apiRelationshipRelPathSegment   = resourcePreviousRelationship.ApiRelPathSegment;

            switch (previousRelationshipCardinality)
            {
            case RelationshipCardinality.ToOne:
            {
                var toOneResourceHypermediaPath = new ToOneResourceHypermediaPath(clrResourceType, apiRelationshipRelPathSegment);

                resourceBasePath.Add(toOneResourceHypermediaPath);
                resourcePathMode = ResourcePathMode.IgnoreApiId;
            }
            break;

            case RelationshipCardinality.ToMany:
            {
                var toManyResourceHypermediaPath = new ToManyResourceHypermediaPath(clrResourceType, apiRelationshipRelPathSegment, apiId);

                resourceBasePath.Add(toManyResourceHypermediaPath);
                resourcePathMode = ResourcePathMode.IncludeApiId;
            }
            break;

            default:
            {
                var detail = InfrastructureErrorStrings.InternalErrorExceptionDetailUnknownEnumerationValue
                             .FormatWith(typeof(RelationshipCardinality).Name, previousRelationshipCardinality);
                throw new InternalErrorException(detail);
            }
            }

            resourcePreviousRelationship = nextRelationship;
        }