/// <summary>
 /// Get the list of "desired" propertyrefs for the specified type and operation
 /// </summary>
 /// <param name="typeInfo"></param>
 /// <param name="opKind"></param>
 /// <returns></returns>
 private IEnumerable<PropertyRef> GetPropertyRefs(TypeInfo typeInfo, OperationKind opKind)
 {
     PlanCompiler.Assert(opKind != OperationKind.All, "unexpected attempt to GetPropertyRefs(...,OperationKind.All)");
     if (opKind == OperationKind.GetKeys)
     {
         return typeInfo.GetKeyPropertyRefs();
     }
     else if (opKind == OperationKind.GetIdentity)
     {
         return typeInfo.GetIdentityPropertyRefs();
     }
     else
     {
         return GetPropertyRefsForComparisonAndIsNull(typeInfo, opKind);
     }
 }
        /// <summary>
        /// Identify the list of property refs for comparison and isnull semantics
        /// </summary>
        /// <param name="typeInfo"></param>
        /// <param name="opKind"></param>
        /// <returns></returns>
        private IEnumerable<PropertyRef> GetPropertyRefsForComparisonAndIsNull(TypeInfo typeInfo, OperationKind opKind)
        {
            PlanCompiler.Assert(opKind == OperationKind.IsNull || opKind == OperationKind.Equality,
                "Unexpected opKind: " + opKind + "; Can only handle IsNull and Equality");

            md.TypeUsage currentType = typeInfo.Type;

            md.RowType recordType = null;
            if (TypeHelpers.TryGetEdmType<md.RowType>(currentType, out recordType))
            {
                if (opKind == OperationKind.IsNull && typeInfo.HasNullSentinelProperty)
                {
                    yield return NullSentinelPropertyRef.Instance;
                }
                else
                    foreach (md.EdmProperty m in recordType.Properties)
                    {
                        if (!TypeUtils.IsStructuredType(md.Helper.GetModelTypeUsage(m)))
                        {
                            yield return new SimplePropertyRef(m);
                        }
                        else
                        {
                            TypeInfo nestedTypeInfo = m_typeInfo.GetTypeInfo(md.Helper.GetModelTypeUsage(m));
                            foreach (PropertyRef p in GetPropertyRefs(nestedTypeInfo, opKind))
                            {
                                PropertyRef nestedPropertyRef = p.CreateNestedPropertyRef(m);
                                yield return nestedPropertyRef;
                            }
                        }
                    }
                yield break;
            }

            md.EntityType entityType = null;
            if (TypeHelpers.TryGetEdmType<md.EntityType>(currentType, out entityType))
            {
                if (opKind == OperationKind.Equality ||
                    (opKind == OperationKind.IsNull && !typeInfo.HasTypeIdProperty))
                {
                    foreach (PropertyRef p in typeInfo.GetIdentityPropertyRefs())
                    {
                        yield return p;
                    }
                }
                else
                {
                    yield return TypeIdPropertyRef.Instance;
                }
                yield break;
            }

            md.ComplexType complexType = null;
            if (TypeHelpers.TryGetEdmType<md.ComplexType>(currentType, out complexType))
            {
                PlanCompiler.Assert(opKind == OperationKind.IsNull, "complex types not equality-comparable");
                PlanCompiler.Assert(typeInfo.HasNullSentinelProperty, "complex type with no null sentinel property: can't handle isNull");
                yield return NullSentinelPropertyRef.Instance;
                yield break;
            }

            md.RefType refType = null;
            if (TypeHelpers.TryGetEdmType<md.RefType>(currentType, out refType))
            {
                foreach (PropertyRef p in typeInfo.GetAllPropertyRefs())
                {
                    yield return p;
                }
                yield break;
            }

            PlanCompiler.Assert(false, "Unknown type");
        }