// <summary>
        // Starting at the <paramref name="member" />, recursively generates <see cref="MemberPath" />s for the fields embedded in it.
        // </summary>
        // <param name="member"> corresponds to a value of an Entity or Complex or Association type </param>
        // <param name="needKeysOnly"> indicates whether we need to only collect members that are keys </param>
        private static void GatherPartialSignature(
            MemberProjectionIndex index, EdmItemCollection edmItemCollection, MemberPath member, bool needKeysOnly)
        {
            var memberType        = member.EdmType;
            var complexTypemember = memberType as ComplexType;

            Debug.Assert(
                complexTypemember != null ||
                memberType is EntityType ||      // for entity sets
                memberType is AssociationType || // For association sets
                memberType is RefType,           // for association ends
                "GatherPartialSignature can be called only for complex types, entity sets, association ends");

            if (memberType is ComplexType && needKeysOnly)
            {
                // Check if the complex type needs to be traversed or not. If not, just return
                // from here. Else we need to continue to the code below. Right now, we do not
                // allow keys inside complex types
                return;
            }

            // Make sure that this member is in the slot map before any of its embedded objects.
            index.CreateIndex(member);

            // Consider each possible type value -- each type value conributes to a tuple in the result.
            // For that possible type, add all the type members into the signature.
            foreach (var possibleType in MetadataHelper.GetTypeAndSubtypesOf(memberType, edmItemCollection, false /*includeAbstractTypes*/))
            {
                var possibleStructuralType = possibleType as StructuralType;
                Debug.Assert(possibleStructuralType != null, "Non-structural subtype?");

                GatherSignatureFromTypeStructuralMembers(index, edmItemCollection, member, possibleStructuralType, needKeysOnly);
            }
        }
        private static void GatherPartialSignature(
            MemberProjectionIndex index,
            EdmItemCollection edmItemCollection,
            MemberPath member,
            bool needKeysOnly)
        {
            EdmType edmType1 = member.EdmType;

            if (edmType1 is ComplexType && needKeysOnly)
            {
                return;
            }
            index.CreateIndex(member);
            foreach (EdmType edmType2 in MetadataHelper.GetTypeAndSubtypesOf(edmType1, (ItemCollection)edmItemCollection, false))
            {
                StructuralType possibleType = edmType2 as StructuralType;
                MemberProjectionIndex.GatherSignatureFromTypeStructuralMembers(index, edmItemCollection, member, possibleType, needKeysOnly);
            }
        }
        // <summary>
        // Given the <paramref name="member" /> and one of its <paramref name="possibleType" />s, determine the attributes that are relevant
        // for this <paramref name="possibleType" /> and return a <see cref="MemberPath" /> signature corresponding to the
        // <paramref
        //     name="possibleType" />
        // and the attributes.
        // If <paramref name="needKeysOnly" />=true, collect the key fields only.
        // </summary>
        // <param name="possibleType">
        // the <paramref name="member" /> 's type or one of its subtypes
        // </param>
        private static void GatherSignatureFromTypeStructuralMembers(
            MemberProjectionIndex index,
            EdmItemCollection edmItemCollection,
            MemberPath member,
            StructuralType possibleType,
            bool needKeysOnly)
        {
            // For each child member of this type, collect all the relevant scalar fields
            foreach (EdmMember structuralMember in Helper.GetAllStructuralMembers(possibleType))
            {
                if (MetadataHelper.IsNonRefSimpleMember(structuralMember))
                {
                    if (!needKeysOnly ||
                        MetadataHelper.IsPartOfEntityTypeKey(structuralMember))
                    {
                        var nonStructuredMember = new MemberPath(member, structuralMember);
                        // Note: scalarMember's parent has already been added to the projectedSlotMap
                        index.CreateIndex(nonStructuredMember);
                    }
                }
                else
                {
                    Debug.Assert(
                        structuralMember.TypeUsage.EdmType is ComplexType ||
                        structuralMember.TypeUsage.EdmType is RefType, // for association ends
                        "Only non-scalars expected - complex types, association ends");

                    var structuredMember = new MemberPath(member, structuralMember);
                    GatherPartialSignature(
                        index,
                        edmItemCollection,
                        structuredMember,
                        // Only keys are required for entities referenced by association ends of an association.
                        needKeysOnly || Helper.IsAssociationEndMember(structuralMember));
                }
            }
        }
 private static void GatherSignatureFromTypeStructuralMembers(
     MemberProjectionIndex index,
     EdmItemCollection edmItemCollection,
     MemberPath member,
     StructuralType possibleType,
     bool needKeysOnly)
 {
     foreach (EdmMember structuralMember in (IEnumerable)Helper.GetAllStructuralMembers((EdmType)possibleType))
     {
         if (MetadataHelper.IsNonRefSimpleMember(structuralMember))
         {
             if (!needKeysOnly || MetadataHelper.IsPartOfEntityTypeKey(structuralMember))
             {
                 MemberPath member1 = new MemberPath(member, structuralMember);
                 index.CreateIndex(member1);
             }
         }
         else
         {
             MemberPath member1 = new MemberPath(member, structuralMember);
             MemberProjectionIndex.GatherPartialSignature(index, edmItemCollection, member1, needKeysOnly || Helper.IsAssociationEndMember(structuralMember));
         }
     }
 }
        /// <summary>
        ///     Given the <paramref name="member" /> and one of its <paramref name="possibleType" />s, determine the attributes that are relevant
        ///     for this <paramref name="possibleType" /> and return a <see cref="MemberPath" /> signature corresponding to the
        ///     <paramref
        ///         name="possibleType" />
        ///     and the attributes.
        ///     If <paramref name="needKeysOnly" />=true, collect the key fields only.
        /// </summary>
        /// <param name="possibleType">
        ///     the <paramref name="member" /> 's type or one of its subtypes
        /// </param>
        private static void GatherSignatureFromTypeStructuralMembers(
            MemberProjectionIndex index,
            EdmItemCollection edmItemCollection,
            MemberPath member,
            StructuralType possibleType,
            bool needKeysOnly)
        {
            // For each child member of this type, collect all the relevant scalar fields
            foreach (EdmMember structuralMember in Helper.GetAllStructuralMembers(possibleType))
            {
                if (MetadataHelper.IsNonRefSimpleMember(structuralMember))
                {
                    if (!needKeysOnly
                        || MetadataHelper.IsPartOfEntityTypeKey(structuralMember))
                    {
                        var nonStructuredMember = new MemberPath(member, structuralMember);
                        // Note: scalarMember's parent has already been added to the projectedSlotMap
                        index.CreateIndex(nonStructuredMember);
                    }
                }
                else
                {
                    Debug.Assert(
                        structuralMember.TypeUsage.EdmType is ComplexType ||
                        structuralMember.TypeUsage.EdmType is RefType, // for association ends
                        "Only non-scalars expected - complex types, association ends");

                    var structuredMember = new MemberPath(member, structuralMember);
                    GatherPartialSignature(
                        index,
                        edmItemCollection,
                        structuredMember,
                        // Only keys are required for entities referenced by association ends of an association.
                        needKeysOnly || Helper.IsAssociationEndMember(structuralMember));
                }
            }
        }
        /// <summary>
        ///     Starting at the <paramref name="member" />, recursively generates <see cref="MemberPath" />s for the fields embedded in it.
        /// </summary>
        /// <param name="member"> corresponds to a value of an Entity or Complex or Association type </param>
        /// <param name="needKeysOnly"> indicates whether we need to only collect members that are keys </param>
        private static void GatherPartialSignature(
            MemberProjectionIndex index, EdmItemCollection edmItemCollection, MemberPath member, bool needKeysOnly)
        {
            var memberType = member.EdmType;
            var complexTypemember = memberType as ComplexType;
            Debug.Assert(
                complexTypemember != null ||
                memberType is EntityType || // for entity sets
                memberType is AssociationType || // For association sets
                memberType is RefType, // for association ends
                "GatherPartialSignature can be called only for complex types, entity sets, association ends");

            if (memberType is ComplexType && needKeysOnly)
            {
                // Check if the complex type needs to be traversed or not. If not, just return 
                // from here. Else we need to continue to the code below. Right now, we do not
                // allow keys inside complex types
                return;
            }

            // Make sure that this member is in the slot map before any of its embedded objects.
            index.CreateIndex(member);

            // Consider each possible type value -- each type value conributes to a tuple in the result.
            // For that possible type, add all the type members into the signature.
            foreach (var possibleType in MetadataHelper.GetTypeAndSubtypesOf(memberType, edmItemCollection, false /*includeAbstractTypes*/))
            {
                var possibleStructuralType = possibleType as StructuralType;
                Debug.Assert(possibleStructuralType != null, "Non-structural subtype?");

                GatherSignatureFromTypeStructuralMembers(index, edmItemCollection, member, possibleStructuralType, needKeysOnly);
            }
        }