Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / Structures / MemberPath.cs / 1305376 / MemberPath.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System; using System.Data.Common.Utils; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Data.Mapping.ViewGeneration.CqlGeneration; using System.Data.Metadata.Edm; using System.Linq; namespace System.Data.Mapping.ViewGeneration.Structures { // A class that corresponds to a path in some extent, e.g., Person, // Person.addr, Person.addr.state internal class MemberPath : InternalBase, IEquatable{ #region Fields private readonly EntitySetBase m_extent; // The base entity set and list of members in the path private readonly List m_path; internal static readonly IEqualityComparer EqualityComparer = new MemberPathComparer(); #endregion #region Constructors // effects: Creates a memberpath that corresponds to path in some // extent (or an extent itself) internal MemberPath(EntitySetBase extent, IEnumerable path) { m_extent = extent; m_path = path.ToList(); } // effects: Creates a memberpath that corresponds to path in some // extent (or an extent itself) internal MemberPath(EntitySetBase extent) : this(extent, Enumerable.Empty ()) { } // effects: Creates the path corresponding to "extent.member" internal MemberPath(EntitySetBase extent, EdmMember member) : this(extent, Enumerable.Repeat (member, 1)) { } // effects: Given a path "prefix" and a member "last", // creates a memberpath corresponding to the path "prefix.last" internal MemberPath(MemberPath prefix, EdmMember last) { m_extent = prefix.m_extent; m_path = new List (prefix.m_path); m_path.Add(last); } #endregion #region Properties internal string LeafEdmMemberName { get { if (m_path.Count == 0) { return m_extent.Name; } else { return LeafEdmMember.Name; } } } /// /// Tells whether the first member is a computed member, as /// internal bool IsComputed { get { if (m_path.Count == 0) { return false; } else { return RootEdmMember.IsStoreGeneratedComputed; } } } // effects: Returns the default value stored in the metadata for // this. If no default value is present, returns null internal object DefaultValue { get { if (m_path.Count == 0) { return null; } Facet facet; if (LeafEdmMember.TypeUsage.Facets.TryGetValue(EdmProviderManifest.DefaultValueFacetName, false, out facet)) { return facet.Value; } return null; } } // effects: Returns true if the last element of this is part of the key internal bool IsPartOfKey { get { if (m_path.Count == 0) { return false; } EdmProperty property = LeafEdmMember as EdmProperty; Debug.Assert(property != null || LeafEdmMember is AssociationEndMember); return MetadataHelper.IsPartOfEntityTypeKey(property); } } internal bool IsNullable { get { if (m_path.Count == 0) { return false; } return MetadataHelper.IsMemberNullable(LeafEdmMember); } } // requires: this corresponds to an entity set or an association set end internal EntitySet EntitySet { get { Debug.Assert(m_path.Count <= 1); if (m_path.Count == 0) { return (EntitySet)m_extent; // Require clause says it is an entity set } else { AssociationEndMember endMember = (AssociationEndMember)RootEdmMember; EntitySet result = MetadataHelper.GetEntitySetAtEnd((AssociationSet)m_extent, endMember); return result; } } } internal EntitySetBase Extent { get { return m_extent; } } // effects: Returns the type of attribute denoted by the path // For example, member type of Person.addr.zip would be integer. For // extent, it is the element type internal EdmType EdmType { get { if (m_path.Count > 0) { return LeafEdmMember.TypeUsage.EdmType; } else { return m_extent.ElementType; } } } // requires: this has at least one element below the extent // effects: Returns the last property in this path internal EdmMember LeafEdmMember { get { Debug.Assert(m_path.Count > 0); return m_path[m_path.Count - 1]; } } // requires: this has at least one element below the extent // effects: Returns the first property in this path internal EdmMember RootEdmMember { get { Debug.Assert(m_path.Count > 0); return m_path[0]; } } // effects: Given a memberpath and block alias, returns a valid Cql // identifier of the form "blockAlias.identfier". If tableAlias is // null, just returns identifier internal string CqlFieldAlias { get { string alias = PathToString(true); if (false == alias.Contains("_")) { // if alias the member does not contain any _, we can replace // the . with _ so that we can get a simple identifier alias = alias.Replace('.', '_'); } StringBuilder builder = new StringBuilder(); CqlWriter.AppendEscapedName(builder, alias); return builder.ToString(); } } // effects: returns false iff this is // * A descendant of some nullable property // * A descendant of an optional composition/collection // * A descendant of a property that does not belong to the // basetype/rootype of its parent internal bool IsAlwaysDefined(Dictionary> inheritanceGraph) { if (m_path.Count == 0) { // Extents are always defined return true; } EdmMember member = m_path.Last(); //Dont check last member, thats the property we are testing for (int i = 0; i < m_path.Count - 1; i++) { EdmMember current = m_path[i]; // If member is nullable then "this" will not always be defined if (MetadataHelper.IsMemberNullable(current)) { return false; } } //Now check if there are any concrete types other than all subtypes of Type defining this member //by definition association types member are always present since they are IDs if (m_path[0].DeclaringType is AssociationType) { return true; } EntityType entitySetType = m_extent.ElementType as EntityType; if (entitySetType == null) //association type { return true; } //well, we handle the first case because we don't knwo how to get to subtype (i.e. the edge to avoid) EntityType memberDeclaringType = m_path[0].DeclaringType as EntityType; EntityType parentType = memberDeclaringType.BaseType as EntityType; if (entitySetType.EdmEquals(memberDeclaringType) || MetadataHelper.IsParentOf(memberDeclaringType, entitySetType) || parentType == null) { return true; } else if (!parentType.Abstract && !MetadataHelper.DoesMemberExist(parentType, member)) { return false; } bool result = !RecurseToFindMemberAbsentInConcreteType(parentType, memberDeclaringType, member, entitySetType, inheritanceGraph); return result; } private static bool RecurseToFindMemberAbsentInConcreteType(EntityType current, EntityType avoidEdge, EdmMember member, EntityType entitySetType, Dictionary > inheritanceGraph) { Set edges = inheritanceGraph[current]; //for each outgoing edge (from current) where the edge is not the one to avoid, // navigate depth-first foreach (var edge in edges.Where(type => !type.EdmEquals(avoidEdge))) { //Dont traverse above the EntitySet's Element type if (entitySetType.BaseType != null && entitySetType.BaseType.EdmEquals(edge)) { continue; } if (!edge.Abstract && !MetadataHelper.DoesMemberExist(edge, member)) { //found it.. I'm the concrete type that has member absent. return true; } if (RecurseToFindMemberAbsentInConcreteType(edge, current /*avoid traversing down back here*/, member, entitySetType, inheritanceGraph)) { //one of the edges reachable from me found it return true; } } //no body found this counter example return false; } #endregion #region Methods // effects: Determines all the identifiers used in this and adds them to identifiers internal void GetIdentifiers(CqlIdentifiers identifiers) { // Get the extent name and extent type name identifiers.AddIdentifier(m_extent.Name); identifiers.AddIdentifier(m_extent.ElementType.Name); foreach (EdmMember member in m_path) { identifiers.AddIdentifier(member.Name); } } // effects: Returns true iff all members are nullable properties, i.e., if even one // of them is non-nullable, returns false internal static bool AreAllMembersNullable(IEnumerable members) { foreach (MemberPath path in members) { if (path.m_path.Count == 0) { return false; // Extents are not nullable } if (path.IsNullable == false) { return false; } } return true; } // effects: Returns a string that has the list of properties in // members (i.e., just the last name) if fullPath is false. Else the // fullPAth is added internal static string PropertiesToUserString(IEnumerable members, bool fullPath) { bool isFirst = true; StringBuilder builder = new StringBuilder(); foreach (MemberPath path in members) { if (isFirst == false) { builder.Append(", "); } isFirst = false; if (fullPath) { builder.Append(path.PathToString(false)); } else { builder.Append(path.LeafEdmMemberName); } } return builder.ToString(); } // effects: Given a member path and an alias, returns a string // correspondng to the fully-qualified name tableAlias.path // e.g., T1.Address.Phone.Zip. If a subcomponent belongs to // subclass, generates a treat for it, e.g. TREAT(T1 as Customer).Address // Or even TREAT(TREAT(T1 AS Customer).Address as USAddress).Zip // Returns the modified builder internal StringBuilder AsCql(StringBuilder inputBuilder, string blockAlias) { // Due to the TREAT stuff, we cannot build incrementally. So we use a local // StringBuilder -- it should not be that inefficient (one extra copy) StringBuilder builder = new StringBuilder(); CqlWriter.AppendEscapedName(builder, blockAlias); // Keep track of the previous type so that we can determine if we // need to cast or not EdmType prevType = m_extent.ElementType; foreach (EdmMember member in m_path) { // If prevType is a ref (e.g., ref to CPerson), we need to get the // type that it is pointing to and then look for this member in that StructuralType prevStructuralType; RefType refType = null; if (Helper.IsRefType(prevType)) { refType = (RefType)prevType; prevStructuralType = refType.ElementType; } else { prevStructuralType = (StructuralType)prevType; } // Check whether the prevType has the present member in it. // If not, we will need to cast the prev type to the // appropriate subtype bool found = MetadataHelper.DoesMemberExist(prevStructuralType, member); // For reference types, the key must be present in the element type itself. // E.g., if we have Ref(CPerson), the key must be present as CPerson.pid // or CPerson.Address.Phone.Number (i.e., in a complex type). Note that it cannot // be present in the subtype of address or phone either, i.e., this path // better not have any TREAT calls // We are at CPerson right now. So if we say Key(CPerson), we will get a row with // all the key elements. Then we can continue going down the path in CPerson if (refType != null) { Debug.Assert(found == true, "We did not find the key property in " + "a ref's element type - it cannot be in a subtype"); // Emit an extract key from the ref builder.Insert(0, "Key("); builder.Append(")"); } else if (false == found) { // Need to add Treat(... as ...) expression in the // beginning. Note that it does handle cases like // TREAT(TREAT(T1 AS Customer).Address as USAddress).Zip Debug.Assert(!Helper.IsRefType(prevType), "We do not allow subtyping in key extraction from Refs"); builder.Insert(0, "TREAT("); builder.Append(" AS "); CqlWriter.AppendEscapedTypeName(builder, member.DeclaringType); builder.Append(')'); } // Add the member's name. We had a path "T1.A.B" till now builder.Append('.'); CqlWriter.AppendEscapedName(builder, member.Name); prevType = member.TypeUsage.EdmType; } inputBuilder.Append(builder.ToString()); return inputBuilder; } public bool Equals(MemberPath right) { return EqualityComparer.Equals(this, right); } public override bool Equals(object obj) { MemberPath right = obj as MemberPath; if (obj == null) { return false; } return Equals(right); } public override int GetHashCode() { return EqualityComparer.GetHashCode(this); } // effects: Returns true if the element denoted by the path corresponds to a scalar (primitive or enum) internal bool IsScalarType() { return EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType || EdmType.BuiltInTypeKind == BuiltInTypeKind.EnumType; } internal static IEnumerable GetKeyMembers(EntitySetBase extent, MemberDomainMap domainMap) { MemberPath extentPath = new MemberPath(extent); List keyAttributes = new List ( extentPath.GetMembers(extentPath.Extent.ElementType, null /* isScalar */, null /* isConditional */, true /* isPartOfKey */, domainMap)); Debug.Assert(keyAttributes.Any(), "No key attributes?"); return keyAttributes; } internal IEnumerable GetMembers(EdmType edmType, bool? isScalar, bool? isConditional, bool? isPartOfKey, MemberDomainMap domainMap) { MemberPath currentPath = this; StructuralType structuralType = (StructuralType)edmType; foreach (EdmMember edmMember in structuralType.Members) { if (edmMember is AssociationEndMember) { // get end's keys foreach (MemberPath endKey in new MemberPath(currentPath, edmMember).GetMembers( ((RefType)edmMember.TypeUsage.EdmType).ElementType, isScalar, isConditional, true /*isPartOfKey*/, domainMap)) { yield return endKey; } } bool isActuallyScalar = MetadataHelper.IsNonRefSimpleMember(edmMember); if (isScalar == null || isScalar == isActuallyScalar) { EdmProperty childProperty = edmMember as EdmProperty; if (childProperty != null) { bool isActuallyKey = MetadataHelper.IsPartOfEntityTypeKey(childProperty); if (isPartOfKey == null || isPartOfKey == isActuallyKey) { MemberPath childPath = new MemberPath(currentPath, childProperty); bool isActuallyConditional = domainMap.IsConditionMember(childPath); if (isConditional == null || isConditional == isActuallyConditional) { yield return childPath; } } } } } } // effects: Returns true if this and path1 are equivalent on the C-side via a referential constraint internal bool IsEquivalentViaRefConstraint(MemberPath path1) { MemberPath path0 = this; // Now check if they are equivalent via referential constraint // For example, // * Person.pid and PersonAddress.Person.pid are equivalent // * Person.pid and PersonAddress.Address.pid are equivalent // * Person.pid and Address.pid are equivalent if there is a referential constraint // * PersonAddress.Person.pid and PersonAddress.Address.pid are // equivalent if there is a referential constraint // In short, Person.pid, Address.pid, PersonAddress.Address.pid, // PersonAddress.Person.pid are the same if (path0.EdmType is EntityTypeBase || path1.EdmType is EntityTypeBase || MetadataHelper.IsNonRefSimpleMember(path0.LeafEdmMember) == false || MetadataHelper.IsNonRefSimpleMember(path1.LeafEdmMember) == false) { // If the path corresponds to a top level extent only, ignore // it. Or if it is not a scalar return false; } AssociationSet assocSet0 = path0.Extent as AssociationSet; AssociationSet assocSet1 = path1.Extent as AssociationSet; EntitySet entitySet0 = path0.Extent as EntitySet; EntitySet entitySet1 = path1.Extent as EntitySet; bool result = false; if (assocSet0 != null && assocSet1 != null) { // PersonAddress.Person.pid and PersonAddress.Address.pid case // Check if they are the same association or not if (assocSet0.Equals(assocSet1) == false) { return false; } result = AreAssocationEndPathsEquivalentViaRefConstraint(path0, path1, assocSet0); } else if (entitySet0 != null && entitySet1 != null) { // Person.pid, Address.pid case // Find all the associations between the two sets. If the // fields are equivalent via any association + referential // constraint, return true List assocSets = MetadataHelper.GetAssociationsForEntitySets(entitySet0, entitySet1); foreach (AssociationSet assocSet in assocSets) { // For Person.pid, get PersonAddress.Person.pid or MemberPath assocEndPath0 = path0.GetCorrespondingAssociationPath(assocSet); MemberPath assocEndPath1 = path1.GetCorrespondingAssociationPath(assocSet); if (AreAssocationEndPathsEquivalentViaRefConstraint(assocEndPath0, assocEndPath1, assocSet)) { result = true; break; } } } else { // One of them is an assocSet and the other is an entity set AssociationSet assocSet = assocSet0 != null ? assocSet0 : assocSet1; EntitySet entitySet = entitySet0 != null ? entitySet0 : entitySet1; Debug.Assert(assocSet != null && entitySet != null, "One set must be association and the other must be entity set"); MemberPath assocEndPathA = path0.Extent is AssociationSet ? path0 : path1; MemberPath entityPath = path0.Extent is EntitySet ? path0 : path1; MemberPath assocEndPathB = entityPath.GetCorrespondingAssociationPath(assocSet); if (assocEndPathB == null) { //An EntitySet might participate in multiple AssociationSets //and this might not be the association set that defines the expected referential //constraint //Return false since this does not have any referential constraint specified result = false; } else { result = AreAssocationEndPathsEquivalentViaRefConstraint(assocEndPathA, assocEndPathB, assocSet); } } return result; } // requires: path0 and path1 correspond to paths in assocSet // effects: Returns true if assocPath0 and assocPath1 are // equivalent via a referential constraint in assocSet private static bool AreAssocationEndPathsEquivalentViaRefConstraint(MemberPath assocPath0, MemberPath assocPath1, AssociationSet assocSet) { Debug.Assert(assocPath0.Extent.Equals(assocSet) && assocPath1.Extent.Equals(assocSet), "Extent for paths must be assocSet"); AssociationEndMember end0 = assocPath0.RootEdmMember as AssociationEndMember; AssociationEndMember end1 = assocPath1.RootEdmMember as AssociationEndMember; EdmProperty property0 = assocPath0.LeafEdmMember as EdmProperty; EdmProperty property1 = assocPath1.LeafEdmMember as EdmProperty; if (end0 == null || end1 == null || property0 == null || property1 == null) { return false; } // Now check if these fields are connected via a referential constraint AssociationType assocType = assocSet.ElementType; bool foundConstraint = false; foreach (ReferentialConstraint constraint in assocType.ReferentialConstraints) { bool isFrom0 = end0.Name == constraint.FromRole.Name && end1.Name == constraint.ToRole.Name; bool isFrom1 = end1.Name == constraint.FromRole.Name && end0.Name == constraint.ToRole.Name; if (isFrom0 || isFrom1) { // Found an RI for the two sets. Make sure that the properties are at the same ordinal // isFrom0 is true when end0 corresponds to FromRole and end1 to ToRole ReadOnlyMetadataCollection properties0 = isFrom0 ? constraint.FromProperties : constraint.ToProperties; ReadOnlyMetadataCollection properties1 = isFrom0 ? constraint.ToProperties : constraint.FromProperties; int indexForPath0 = properties0.IndexOf(property0); int indexForPath1 = properties1.IndexOf(property1); if (indexForPath0 == indexForPath1 && indexForPath0 != -1) { foundConstraint = true; break; } } } return foundConstraint; } // Note: this need not correspond to a key field of an entity set E and // assocSet corresponds to an association whose one end is E // // effects: Returns the MemberPath corresponding to that field in the // assocSet. E.g., given Address.pid, returns PersonAddress.Address.pid. // For self-associations, such as ManagerEmployee with referential // constraints (and we have [ , // ]), given Employee.mid, returns // ManagerEmployee.Employee.mid or ManagerEmployee.Manager.mid private MemberPath GetCorrespondingAssociationPath(AssociationSet assocSet) { Debug.Assert(Extent is EntitySet, "path must correspond to entity"); // Find the end corresponding to the entity set AssociationEndMember end = MetadataHelper.GetSomeEndForEntitySet(assocSet, (EntitySet)m_extent); //An EntitySet might participate in multiple AssociationSets //and this might not be the association set that defines the expected referential //constraint if (end == null) { return null; } // Create the new members using the end List newMembers = new List (); newMembers.Add(end); newMembers.AddRange(m_path); // The extent is the assocSet MemberPath result = new MemberPath(assocSet, newMembers); return result; } // effects: If this identifies a relationship end, return its scope. // Otherwise, returns null. internal EntitySet GetScopeOfRelationEnd() { if (m_path.Count == 0) { return null; } AssociationEndMember relationEndMember = LeafEdmMember as AssociationEndMember; if (relationEndMember == null) { return null; } // Yes, it's a reference, determine its entity set refScope AssociationSet associationSet = (AssociationSet)m_extent; EntitySet result = MetadataHelper.GetEntitySetAtEnd(associationSet, relationEndMember); return result; } // effects: Returns a string of the form a.b.c that corresponds to // the "this's" path -- This string can be used for tests or // localization // If forAlias is true, we return a string that is relevant for Cql // aliases, else we return the exact path internal string PathToString(bool? forAlias) { StringBuilder builder = new StringBuilder(); if (forAlias != null) { if (forAlias == true) { // For the 0th entry, we just choose the type of the element in // which the first entry belongs, e.g., if Addr belongs to CCustomer, // we choose CCustomer and not CPerson. if (m_path.Count == 0) { EntityTypeBase type = m_extent.ElementType; return type.Name; } builder.Append(m_path[0].DeclaringType.Name); // Get CCustomer here } else { // Append the extent name builder.Append(m_extent.Name); } } // Just join the path using "." for (int i = 0; i < m_path.Count; i++) { builder.Append('.'); builder.Append(m_path[i].Name); } return builder.ToString(); } // effects: Returns a human-readable string corresponding to this internal override void ToCompactString(StringBuilder builder) { builder.Append(PathToString(false)); } internal void ToCompactString(StringBuilder builder, string instanceToken) { builder.Append(instanceToken + PathToString(null)); } #endregion #region Comparer private class MemberPathComparer : IEqualityComparer { public bool Equals(MemberPath left, MemberPath right) { if (object.ReferenceEquals(left, right)) { return true; } // One of them is non-null at least. So if the other one is // null, we cannot be equal if (left == null || right == null) { return false; } // Both are non-null at this point // Checks that the paths are equal component-wise if (left.m_extent.Equals(right.m_extent) == false || left.m_path.Count != right.m_path.Count) { return false; } for (int i = 0; i < left.m_path.Count; i++) { // Comparing MemberMetadata -- can use Equals if (false == left.m_path[i].Equals(right.m_path[i])) { return false; } } return true; } public int GetHashCode(MemberPath key) { int result = key.m_extent.GetHashCode(); foreach (EdmMember member in key.m_path) { result ^= member.GetHashCode(); } return result; } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RepeaterItemCollection.cs
- EncoderReplacementFallback.cs
- InternalControlCollection.cs
- ListSourceHelper.cs
- StringUtil.cs
- XmlSchemaAll.cs
- PtsPage.cs
- DesignerSerializationOptionsAttribute.cs
- ParameterBinding.cs
- XmlSchemaObjectTable.cs
- ImageList.cs
- ConnectivityStatus.cs
- PropertyChangedEventManager.cs
- SmiMetaData.cs
- OptimizerPatterns.cs
- HashCodeCombiner.cs
- QueryTask.cs
- SamlAdvice.cs
- XmlUtil.cs
- SqlBuffer.cs
- SimpleLine.cs
- HotCommands.cs
- MetadataItem.cs
- __FastResourceComparer.cs
- CustomPopupPlacement.cs
- TraceUtility.cs
- ActivationArguments.cs
- X509IssuerSerialKeyIdentifierClause.cs
- ByteStreamMessage.cs
- IssuerInformation.cs
- InvalidateEvent.cs
- ControlPropertyNameConverter.cs
- DependentTransaction.cs
- PresentationTraceSources.cs
- NestedContainer.cs
- Semaphore.cs
- ProgressBarHighlightConverter.cs
- ImageMapEventArgs.cs
- RemoveStoryboard.cs
- ReflectPropertyDescriptor.cs
- Command.cs
- MappingException.cs
- IDReferencePropertyAttribute.cs
- _BufferOffsetSize.cs
- CodeGroup.cs
- TabControlToolboxItem.cs
- Emitter.cs
- DesigntimeLicenseContext.cs
- Vector3DAnimation.cs
- XsdDuration.cs
- ProbeDuplexCD1AsyncResult.cs
- CompilerCollection.cs
- TextChangedEventArgs.cs
- ResXFileRef.cs
- WorkflowServiceOperationListItem.cs
- ServiceProviders.cs
- ScrollEvent.cs
- XamlBuildProvider.cs
- CaseInsensitiveOrdinalStringComparer.cs
- DataContract.cs
- StagingAreaInputItem.cs
- TextDecoration.cs
- PerfCounterSection.cs
- AssertUtility.cs
- AdornedElementPlaceholder.cs
- XmlUnspecifiedAttribute.cs
- SpoolingTask.cs
- Parameter.cs
- EntityException.cs
- CounterSetInstanceCounterDataSet.cs
- XslCompiledTransform.cs
- ReadOnlyCollectionBuilder.cs
- ToolStripDropDown.cs
- AppDomainProtocolHandler.cs
- URL.cs
- Material.cs
- GridViewSelectEventArgs.cs
- SimpleLine.cs
- DSASignatureDeformatter.cs
- DataRowComparer.cs
- ComPlusServiceLoader.cs
- EpmContentSerializerBase.cs
- ElementUtil.cs
- DiagnosticsConfiguration.cs
- SmtpNegotiateAuthenticationModule.cs
- PathGradientBrush.cs
- PrintDialogException.cs
- Int64Storage.cs
- XPathNavigatorKeyComparer.cs
- PeerEndPoint.cs
- CodeDomSerializerException.cs
- TextMetrics.cs
- Transform.cs
- DataListItem.cs
- KeyTimeConverter.cs
- XamlRtfConverter.cs
- SafeNativeMethodsCLR.cs
- DeviceSpecificDialogCachedState.cs
- BackEase.cs
- Math.cs