Ejemplo n.º 1
0
		/// <summary>
		/// Constructor
		/// Creates a UniquenessConstraintIncludesColumn link in the same Partition as the given UniquenessConstraint
		/// </summary>
		/// <param name="source">UniquenessConstraint to use as the source of the relationship.</param>
		/// <param name="target">Column to use as the target of the relationship.</param>
		public UniquenessConstraintIncludesColumn(UniquenessConstraint source, Column target)
			: base((source != null ? source.Partition : null), new DslModeling::RoleAssignment[]{new DslModeling::RoleAssignment(UniquenessConstraintIncludesColumn.UniquenessConstraintDomainRoleId, source), new DslModeling::RoleAssignment(UniquenessConstraintIncludesColumn.ColumnDomainRoleId, target)}, null)
		{
		}
Ejemplo n.º 2
0
		public static DslModeling::LinkedElementCollection<UniquenessConstraint> GetUniquenessConstraints(Column element)
		{
			return new DslModeling::LinkedElementCollection<UniquenessConstraint>(element, ColumnDomainRoleId);
		}
Ejemplo n.º 3
0
		public static PredefinedDataType GetPredefinedDataType(Column element)
		{
			return DslModeling::DomainRoleInfo.GetLinkedElement(element, ColumnDomainRoleId) as PredefinedDataType;
		}
Ejemplo n.º 4
0
		public static void SetPredefinedDataType(Column element, PredefinedDataType newPredefinedDataType)
		{
			DslModeling::DomainRoleInfo.SetLinkedElement(element, ColumnDomainRoleId, newPredefinedDataType);
		}
Ejemplo n.º 5
0
		/// <summary>
		/// Constructor
		/// Creates a ColumnHasPredefinedDataType link in the same Partition as the given Column
		/// </summary>
		/// <param name="source">Column to use as the source of the relationship.</param>
		/// <param name="target">PredefinedDataType to use as the target of the relationship.</param>
		public ColumnHasPredefinedDataType(Column source, PredefinedDataType target)
			: base((source != null ? source.Partition : null), new DslModeling::RoleAssignment[]{new DslModeling::RoleAssignment(ColumnHasPredefinedDataType.ColumnDomainRoleId, source), new DslModeling::RoleAssignment(ColumnHasPredefinedDataType.PredefinedDataTypeDomainRoleId, target)}, null)
		{
		}
Ejemplo n.º 6
0
		public static void SetColumn(PredefinedDataType element, Column newColumn)
		{
			DslModeling::DomainRoleInfo.SetLinkedElement(element, PredefinedDataTypeDomainRoleId, newColumn);
		}
Ejemplo n.º 7
0
		public static Domain GetDomain(Column element)
		{
			return DslModeling::DomainRoleInfo.GetLinkedElement(element, ColumnDomainRoleId) as Domain;
		}
Ejemplo n.º 8
0
				string IDatabaseNameGenerator.GenerateColumnName(Column column, int phase)
				{
					return GenerateColumnName(column, phase);
				}
Ejemplo n.º 9
0
		public static void SetTable(Column element, Table newTable)
		{
			DslModeling::DomainRoleInfo.SetLinkedElement(element, ColumnDomainRoleId, newTable);
		}
Ejemplo n.º 10
0
		/// <summary>
		/// Constructor
		/// Creates a ColumnHasDomain link in the same Partition as the given Column
		/// </summary>
		/// <param name="source">Column to use as the source of the relationship.</param>
		/// <param name="target">Domain to use as the target of the relationship.</param>
		public ColumnHasDomain(Column source, Domain target)
			: base((source != null ? source.Partition : null), new DslModeling::RoleAssignment[]{new DslModeling::RoleAssignment(ColumnHasDomain.ColumnDomainRoleId, source), new DslModeling::RoleAssignment(ColumnHasDomain.DomainDomainRoleId, target)}, null)
		{
		}
Ejemplo n.º 11
0
		public static Table GetTable(Column element)
		{
			return DslModeling::DomainRoleInfo.GetLinkedElement(element, ColumnDomainRoleId) as Table;
		}
Ejemplo n.º 12
0
		/// <summary>
		/// Constructor
		/// Creates a TableContainsColumn link in the same Partition as the given Table
		/// </summary>
		/// <param name="source">Table to use as the source of the relationship.</param>
		/// <param name="target">Column to use as the target of the relationship.</param>
		public TableContainsColumn(Table source, Column target)
			: base((source != null ? source.Partition : null), new DslModeling::RoleAssignment[]{new DslModeling::RoleAssignment(TableContainsColumn.TableDomainRoleId, source), new DslModeling::RoleAssignment(TableContainsColumn.ColumnDomainRoleId, target)}, null)
		{
		}
Ejemplo n.º 13
0
				private string GenerateColumnName(Column column, int phase)
				{
					if (phase > 1)
					{
						return null;
					}
					bool decorateWithPredicateText = phase == 1;
					LinkedNode<ColumnPathStep> currentNode = GetColumnPath(column);

					NameGenerator generator = ColumnNameGenerator;

					if (currentNode == null)
					{
						return GetFinalName(ResourceStrings.NameGenerationValueTypeValueColumn, null, generator);
					}

					// Prepare for adding name parts. The single NamePart string is used when
					// possible to avoid using the list for a single entry
					NamePart singleName = default(NamePart);
					List<NamePart> nameCollection = null;
					AddNamePart addPart = delegate(NamePart newPart, int? insertIndex)
						{
							AddToNameCollection(ref singleName, ref nameCollection, newPart, insertIndex.HasValue ? insertIndex.Value : -1, true);
						};
					ObjectType previousResolvedSupertype = null;
					ObjectType previousResolvedObjectType = null;
					ConceptType primaryConceptType = TableIsPrimarilyForConceptType.GetConceptType(column.Table);
					if (primaryConceptType != null)
					{
						previousResolvedSupertype = previousResolvedObjectType = ConceptTypeIsForObjectType.GetObjectType(primaryConceptType);
					}
					ObjectType previousPreviousResolvedSupertype = null;
					ObjectType previousPreviousResolvedObjectType = null;
					bool firstPass = true;
					bool treatNextIdentifierAsFirstStep = false;
					bool lastStepConsumedNextNode = false;
					bool lastStepUsedExplicitRoleName = false;
					do
					{
						LinkedNode<ColumnPathStep> nextLoopNode = currentNode.Next;
						ColumnPathStep step = currentNode.Value;
						ColumnPathStepFlags stepFlags = step.Flags;
						if (treatNextIdentifierAsFirstStep)
						{
							treatNextIdentifierAsFirstStep = false;
							if (0 != (stepFlags & ColumnPathStepFlags.IsIdentifier))
							{
								firstPass = true;
							}
						}
						if (0 != (stepFlags & ColumnPathStepFlags.ForwardAssimilation))
						{
							if (!(lastStepConsumedNextNode || lastStepUsedExplicitRoleName) || currentNode.Previous.Value.TargetObjectType != step.StartingObjectType)
							{
								ReferenceModeNaming.SeparateObjectTypeParts(step.ResolvedSupertype, generator, addPart);
								lastStepConsumedNextNode = false;
								lastStepUsedExplicitRoleName = false;
							}
							// Note that there is no else clause to reset the flags, keep them with their current values
						}
						else if (0 != (stepFlags & ColumnPathStepFlags.ReverseAssimilation))
						{
							// Don't add names for reverse path types
							lastStepConsumedNextNode = false;
							lastStepUsedExplicitRoleName = false;
							treatNextIdentifierAsFirstStep = firstPass;
							if (nextLoopNode == null)
							{
								// Unusual, but can happen with a ValueType with its own table
								ReferenceModeNaming.SeparateObjectTypeParts(step.ResolvedSupertype, generator, addPart);
							}
						}
						else
						{
							bool decorate = 0 != (stepFlags & ColumnPathStepFlags.RequiresDecoration);
							ColumnPathStep nextAssimilationStep;
							bool incorporateNextAssimilation = nextLoopNode != null && (0 != (ColumnPathStepFlags.ForwardAssimilation & (nextAssimilationStep = nextLoopNode.Value).Flags)) && nextAssimilationStep.StartingObjectType == step.TargetObjectType;
							if (decorate ||
								incorporateNextAssimilation || 
								(nextLoopNode == null && (0 == (stepFlags & ColumnPathStepFlags.IsIdentifier) || !(lastStepConsumedNextNode || lastStepUsedExplicitRoleName))))
							{
								LinkedNode<ColumnPathStep> nextNode = nextLoopNode;
								if (!decorate &&
									nextNode == null &&
									0 != (stepFlags & ColumnPathStepFlags.IsIdentifier))
								{
									LinkedNode<ColumnPathStep> previousNode = currentNode.Previous;
									if (previousNode != null)
									{
										ColumnPathStep previousStep = previousNode.Value;
										ColumnPathStepFlags previousFlags = previousStep.Flags;
										if (0 == (previousFlags & (ColumnPathStepFlags.RequiresDecoration | ColumnPathStepFlags.ForwardAssimilation | ColumnPathStepFlags.ReverseAssimilation)) &&
											previousResolvedSupertype.ReferenceModePattern != null)
										{
											// Special condition when the last node is a simple identifier:
											// Back up one step to enable picking up the role or hyphen-bound
											// name instead of just the predicate text.
											stepFlags = previousFlags;
											step = previousStep;
											nextNode = currentNode;
											previousResolvedSupertype = previousPreviousResolvedSupertype;
											previousResolvedObjectType = previousPreviousResolvedObjectType;
										}
									}
								}
								Role nearRole = step.FromRole;
								Role farRole = (0 == (stepFlags & ColumnPathStepFlags.ObjectifiedFactType)) ?
									nearRole.OppositeRoleAlwaysResolveProxy.Role :
									nearRole.OppositeRole.Role;
								string explicitFarRoleName = farRole.Name;
								FactType factType = nearRole.FactType;
								LinkedElementCollection<RoleBase> factTypeRoles = factType.RoleCollection;
								int? unaryRoleIndex = FactType.GetUnaryRoleIndex(factTypeRoles);
								bool isUnary = unaryRoleIndex.HasValue;
								LinkedElementCollection<ReadingOrder> readingOrders = null;
								IReading reading = null;
								if ((decorate && decorateWithPredicateText) || (isUnary && string.IsNullOrEmpty(explicitFarRoleName)))
								{
									readingOrders = factType.ReadingOrderCollection;
									reading = factType.GetMatchingReading(readingOrders, null, nearRole, null, factTypeRoles, MatchingReadingOptions.NoFrontText | (isUnary ? MatchingReadingOptions.AllowAnyOrder : MatchingReadingOptions.None));
								}
								lastStepConsumedNextNode = false;
								lastStepUsedExplicitRoleName = false;
								if (reading != null && !reading.IsDefault)
								{
									string readingText = string.Format(CultureInfo.CurrentCulture, reading.Text, isUnary ? "\x1" : "", "\x1");
									int splitPosition = readingText.LastIndexOf('\x1');
									if (splitPosition > 0)
									{
										addPart(readingText.Substring(0, splitPosition), null);
									}
									if (!isUnary)
									{
										if (nextNode != null)
										{
											ColumnPathStep nextStep = nextNode.Value;
											ColumnPathStepFlags nextFlags;
											if (incorporateNextAssimilation ||
												(0 != ((nextFlags = nextStep.Flags) & ColumnPathStepFlags.RequiresDecoration) &&
												0 != (nextFlags & (ColumnPathStepFlags.ForwardAssimilation | ColumnPathStepFlags.ReverseAssimilation)) &&
												step.TargetObjectType == nextStep.StartingObjectType))
											{
												// Note that this does not interfere with the earlier 'back up one step'
												// because the checked flags are different.
												nextLoopNode = nextNode.Next;
												lastStepConsumedNextNode = ReferenceModeNaming.ResolveObjectTypeName(
													nextStep.ResolvedObjectType,
													(nextLoopNode != null) ? nextLoopNode.Value.TargetObjectType : null,
													nextStep.ResolvedSupertypeVerifyPreferred,
													true,
													ReferenceModeNamingUse.ReferenceToEntityType,
													generator,
													addPart);
											}
											else
											{
												lastStepConsumedNextNode = ReferenceModeNaming.ResolveObjectTypeName(
													step.ResolvedObjectType,
													nextNode.Value.TargetObjectType,
													step.ResolvedSupertypeVerifyPreferred,
													true,
													ReferenceModeNamingUse.ReferenceToEntityType,
													generator,
													addPart);
											}
										}
										else
										{
											ReferenceModeNaming.ResolveObjectTypeName(
												(!firstPass || 0 != (stepFlags & ColumnPathStepFlags.IsIdentifier)) ? previousResolvedSupertype : null,
												step.TargetObjectType,
												previousResolvedObjectType,
												false,
												firstPass ? ReferenceModeNamingUse.PrimaryIdentifier : ReferenceModeNamingUse.ReferenceToEntityType, // Ignored if first parameter is null
												generator,
												addPart);
										}
									}
									if ((readingText.Length - splitPosition) > 1)
									{
										addPart(readingText.Substring(splitPosition + 1), null);
									}
								}
								else if (!string.IsNullOrEmpty(explicitFarRoleName))
								{
									addPart(explicitFarRoleName, null);
									lastStepUsedExplicitRoleName = true;
								}
								else
								{
									// Find an appropriate hyphen bind in the available readings
									string hyphenBoundFormatString = null;
									if (readingOrders == null)
									{
										readingOrders = factType.ReadingOrderCollection;
									}
									ReadingOrder readingOrder;
									if (0 != (readingOrders ?? (readingOrders = factType.ReadingOrderCollection)).Count &&
										null != (readingOrder = isUnary ? readingOrders[0] : FactType.FindMatchingReadingOrder(readingOrders, new RoleBase[] { nearRole, farRole })))
									{
										foreach (Reading testReading in readingOrder.ReadingCollection)
										{
											hyphenBoundFormatString = VerbalizationHyphenBinder.GetFormatStringForHyphenBoundRole(testReading, farRole, unaryRoleIndex);
											if (hyphenBoundFormatString != null)
											{
												break;
											}
										}
									}
									int splitPosition = 0;
									if (hyphenBoundFormatString != null)
									{
										hyphenBoundFormatString = string.Format(CultureInfo.CurrentCulture, hyphenBoundFormatString, "\x1");
										splitPosition = hyphenBoundFormatString.IndexOf('\x1');
										if (splitPosition != 0)
										{
											addPart(hyphenBoundFormatString.Substring(0, splitPosition), null);
										}
									}
									if (nextNode != null)
									{
											ColumnPathStep nextStep = nextNode.Value;
											ColumnPathStepFlags nextFlags;
											if (incorporateNextAssimilation ||
												(0 != ((nextFlags = nextStep.Flags) & ColumnPathStepFlags.RequiresDecoration) &&
												0 != (nextFlags & (ColumnPathStepFlags.ForwardAssimilation | ColumnPathStepFlags.ReverseAssimilation)) &&
												step.TargetObjectType == nextStep.StartingObjectType))
											{
												// Note that this does not interfere with the earlier 'back up one step'
												// because the checked flags are different.

												// Advance the loop one step
												previousPreviousResolvedSupertype = previousResolvedSupertype;
												previousPreviousResolvedObjectType = previousResolvedObjectType;
												previousResolvedSupertype = (0 != (step.Flags & ColumnPathStepFlags.ReverseAssimilation)) ? step.ResolvedSupertypeVerifyPreferred : step.ResolvedSupertype;
												previousResolvedObjectType = step.ResolvedObjectTypeVerifyPreferred;
												nextLoopNode = nextNode.Next;
												step = nextStep;
												lastStepConsumedNextNode = ReferenceModeNaming.ResolveObjectTypeName(
													nextStep.ResolvedObjectType,
													(nextLoopNode != null) ? nextLoopNode.Value.TargetObjectType : null,
													nextStep.ResolvedSupertypeVerifyPreferred,
													true,
													ReferenceModeNamingUse.ReferenceToEntityType,
													generator,
													addPart);
											}
											else
											{
												lastStepConsumedNextNode = ReferenceModeNaming.ResolveObjectTypeName(
													step.ResolvedObjectType,
													nextNode.Value.TargetObjectType,
													step.ResolvedSupertypeVerifyPreferred,
													true,
													ReferenceModeNamingUse.ReferenceToEntityType,
													generator,
													addPart);
											}
									}
									else
									{
										ReferenceModeNaming.ResolveObjectTypeName(
											(!firstPass || 0 != (stepFlags & ColumnPathStepFlags.IsIdentifier)) ? previousResolvedObjectType : null,
											step.TargetObjectType,
											previousResolvedSupertype,
											false,
											firstPass ? ReferenceModeNamingUse.PrimaryIdentifier : ReferenceModeNamingUse.ReferenceToEntityType, // Ignored if first parameter is null
											generator,
											addPart);
									}
									if (hyphenBoundFormatString != null &&
										(hyphenBoundFormatString.Length - splitPosition) > 1)
									{
										addPart(hyphenBoundFormatString.Substring(splitPosition + 1), null);
									}
								}
							}
							else
							{
								lastStepConsumedNextNode = false;
								lastStepUsedExplicitRoleName = false;
							}
						}
						previousPreviousResolvedSupertype = previousResolvedSupertype;
						previousPreviousResolvedObjectType = previousResolvedObjectType;
						previousResolvedSupertype = (0 != (step.Flags & ColumnPathStepFlags.ReverseAssimilation)) ? step.ResolvedSupertypeVerifyPreferred :  step.ResolvedSupertype;
						previousResolvedObjectType = step.ResolvedObjectTypeVerifyPreferred;
						currentNode = nextLoopNode;
						firstPass = false;
					} while (currentNode != null);
					string finalName = GetFinalName(singleName, nameCollection, generator);
					if (string.IsNullOrEmpty(finalName))
					{
						return (phase == 0) ? "COLUMN" : null;
					}
					return finalName;
				}
Ejemplo n.º 14
0
		/// <summary>
		/// Constructor
		/// Creates a ColumnReference link in the same Partition as the given Column
		/// </summary>
		/// <param name="source">Column to use as the source of the relationship.</param>
		/// <param name="target">Column to use as the target of the relationship.</param>
		public ColumnReference(Column source, Column target)
			: base((source != null ? source.Partition : null), new DslModeling::RoleAssignment[]{new DslModeling::RoleAssignment(ColumnReference.SourceColumnDomainRoleId, source), new DslModeling::RoleAssignment(ColumnReference.TargetColumnDomainRoleId, target)}, null)
		{
		}
Ejemplo n.º 15
0
		public static void SetDomain(Column element, Domain newDomain)
		{
			DslModeling::DomainRoleInfo.SetLinkedElement(element, ColumnDomainRoleId, newDomain);
		}
Ejemplo n.º 16
0
		public static DslModeling::LinkedElementCollection<Column> GetTargetColumnCollection(Column element)
		{
			return new DslModeling::LinkedElementCollection<Column>(element, SourceColumnDomainRoleId);
		}
Ejemplo n.º 17
0
				private LinkedNode<ColumnPathStep> GetColumnPath(Column column)
				{
					Table table = column.Table;
					if (myColumnStepTable == table)
					{
						return myColumnSteps[column];
					}
					Dictionary<Column, LinkedNode<ColumnPathStep>> columnSteps = myColumnSteps;
					if (myColumnStepTable == null)
					{
						myColumnSteps = columnSteps = new Dictionary<Column, LinkedNode<ColumnPathStep>>();
					}
					else
					{
						columnSteps.Clear();
					}
					myColumnStepTable = table;
#if DEBUGCOLUMNPATH
					Debug.WriteLine("Table: " + table.Name);
					Debug.Indent();
					Debug.Indent();
#endif // DEBUGCOLUMNPATH

					// Seed the cross-cutting dictionary and seed it with the main represented
					// ObjectTypes to force decorations on columns that loop back into this table.
					Dictionary<ObjectType, LinkedNode<LinkedNode<ColumnPathStep>>> objectTypeToSteps = new Dictionary<ObjectType, LinkedNode<LinkedNode<ColumnPathStep>>>();
					ConceptType primaryConceptType = TableIsPrimarilyForConceptType.GetConceptType(table);
					if (primaryConceptType != null)
					{
						ObjectType targetObjectType = ConceptTypeIsForObjectType.GetObjectType(primaryConceptType);
						objectTypeToSteps[targetObjectType] = new LinkedNode<LinkedNode<ColumnPathStep>>(new LinkedNode<ColumnPathStep>(new ColumnPathStep(null, targetObjectType, null, ColumnPathStepFlags.None)));
					}
					foreach (ConceptType secondaryConceptType in TableIsAlsoForConceptType.GetConceptType(table))
					{
						ObjectType targetObjectType = ConceptTypeIsForObjectType.GetObjectType(secondaryConceptType);
						objectTypeToSteps[targetObjectType] = new LinkedNode<LinkedNode<ColumnPathStep>>(new LinkedNode<ColumnPathStep>(new ColumnPathStep(null, targetObjectType, null, ColumnPathStepFlags.None)));
					}
					LinkedElementCollection<Column> columns = table.ColumnCollection;
					int columnCount = columns.Count;
					for (int iColumn = 0; iColumn < columnCount; ++iColumn)
					{
						Column currentColumn = columns[iColumn];
#if DEBUGCOLUMNPATH
						Debug.Unindent();
						Debug.WriteLine("Column: " + currentColumn.Name);
						Debug.Indent();
#endif // DEBUGCOLUMNPATH
						LinkedElementCollection<ConceptTypeChild> childPath = ColumnHasConceptTypeChild.GetConceptTypeChildPath(currentColumn);
						int childPathCount = childPath.Count;
						LinkedNode<ColumnPathStep> headNode = null;
						LinkedNode<ColumnPathStep> tailNode = null;
						bool passedIdentifier = false;
						bool processTailDelayed = false;
						ConceptType nextComingFromConceptType = primaryConceptType;
						Objectification assimilationObjectification = null;
						for (int iChild = 0; iChild < childPathCount; ++iChild)
						{
							ConceptType comingFromConceptType = nextComingFromConceptType;
							ConceptTypeChild child = childPath[iChild];
							ConceptTypeAssimilatesConceptType assimilation = child as ConceptTypeAssimilatesConceptType;
							bool reverseAssimilation = false;
							bool forwardToReverseTransition = false;
							bool towardsSubtype = false;
							if (assimilation != null)
							{
								if (comingFromConceptType == assimilation.Parent)
								{
									nextComingFromConceptType = assimilation.ReferencedConceptType;
								}
								else
								{
									towardsSubtype = true;
									nextComingFromConceptType = assimilation.Parent;
								}
#if DEBUGCOLUMNPATH
								Debug.WriteLine("From: " + comingFromConceptType.Name + " To: " + nextComingFromConceptType.Name + "(" + (assimilation.RefersToSubtype && assimilation.IsPreferredForTarget).ToString() + ")");
#endif // DEBUGCOLUMNPATH
								if (tailNode != null)
								{
									// If we're already moving down an assimilation path in a specific direction then keep
									// going that direction
									ColumnPathStep pathStep = tailNode.Value;
									ColumnPathStepFlags stepFlags = pathStep.Flags;
									if (0 != (stepFlags & ColumnPathStepFlags.ForwardAssimilation))
									{
										// Keep going forward
										if (0 != (stepFlags & ColumnPathStepFlags.AssimilationIsSubtype) &&
											AssimilationMapping.GetAbsorptionChoiceFromAssimilation(assimilation) != AssimilationAbsorptionChoice.Absorb &&
											comingFromConceptType == (0 == (stepFlags & ColumnPathStepFlags.AssimilationTowardsSubtype) ? assimilation.AssimilatedConceptType : assimilation.AssimilatorConceptType))
										{
											forwardToReverseTransition = true;
										}
									}
									else if (0 != (stepFlags & ColumnPathStepFlags.ReverseAssimilation))
									{
										// Keep going backward
										reverseAssimilation = true;
									}
									else
									{
										// Figure it out from this step
										reverseAssimilation = AssimilationMapping.GetAbsorptionChoiceFromAssimilation(assimilation) != AssimilationAbsorptionChoice.Absorb;
									}
								}
								else
								{
									reverseAssimilation = AssimilationMapping.GetAbsorptionChoiceFromAssimilation(assimilation) != AssimilationAbsorptionChoice.Absorb;
								}
							}
							else
							{
								nextComingFromConceptType = child.Target as ConceptType;
#if DEBUGCOLUMNPATH
								Debug.WriteLine("From: " + comingFromConceptType.Name + " To: " + ((nextComingFromConceptType != null) ? nextComingFromConceptType.Name : ((InformationTypeFormat)child.Target).Name));
#endif // DEBUGCOLUMNPATH
							}
							LinkedElementCollection<FactType> factTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(child);
							int factTypeCount = factTypes.Count;
							for (int iFactType = 0; iFactType < factTypeCount; ++iFactType)
							{
								FactType factType = factTypes[iFactType];
								Role targetRole = FactTypeMapsTowardsRole.GetTowardsRole(factType).Role;
								ColumnPathStepFlags flags = passedIdentifier ? ColumnPathStepFlags.PassedIdentifier : 0;
								ColumnPathStep pathStep = default(ColumnPathStep);
								bool processPreviousTail = false;
								Objectification previousAssimilationObjectification = assimilationObjectification;
								assimilationObjectification = null;
								bool processAsFactType = true;
								if (assimilation != null)
								{
									Role nonAssimilationTargetRole = targetRole;
									if (!towardsSubtype)
									{
										targetRole = targetRole.OppositeRoleAlwaysResolveProxy.Role;
									}
									processAsFactType = false;
									Objectification objectification;
									bool assimilationIsSubtype = assimilation.RefersToSubtype;
									bool secondarySubtype = assimilationIsSubtype && !assimilation.IsPreferredForTarget;
									if (!assimilationIsSubtype &&
										null != (objectification = factType.ImpliedByObjectification) &&
										objectification.NestingType == targetRole.RolePlayer)
									{
										assimilationObjectification = objectification;
									}
									if (tailNode != null)
									{
										pathStep = tailNode.Value;
										ColumnPathStepFlags tailFlags = pathStep.Flags;
										if (0 != (tailFlags & (ColumnPathStepFlags.ForwardAssimilation | ColumnPathStepFlags.ReverseAssimilation)))
										{
											bool tailIsSubtype = 0 != (tailFlags & ColumnPathStepFlags.AssimilationIsSubtype);
											if (tailIsSubtype && assimilationIsSubtype)
											{
												if (forwardToReverseTransition)
												{
													flags |= ColumnPathStepFlags.DeclinedAssimilation;
													targetRole = towardsSubtype ? targetRole.OppositeRoleAlwaysResolveProxy.Role : nonAssimilationTargetRole;
													processAsFactType = true;
												}
												else
												{
													if (secondarySubtype && 0 == (tailFlags & ColumnPathStepFlags.NonPreferredSubtype))
													{
														tailNode.Value = new ColumnPathStep(pathStep.FromRole, pathStep.ObjectType, pathStep.AlternateObjectType, tailFlags | ColumnPathStepFlags.NonPreferredSubtype);
													}
													// If this is a subtype chain, then keep going, using the first
													// subtype in the chain as a node used in the final name.
													continue;
												}
											}
											else if (assimilationObjectification != null)
											{
												// The type of assimilation has changed, but we have an objectifying object type,
												// so we treat it like a separate link in the chain, or the previous element was
												// also not a subtype.
												tailNode.Value = new ColumnPathStep(pathStep.FromRole, pathStep.ObjectType, nonAssimilationTargetRole.RolePlayer, pathStep.Flags);
												processPreviousTail = processTailDelayed;
											}
											else
											{
												flags |= ColumnPathStepFlags.DeclinedAssimilation;
												targetRole = towardsSubtype ? targetRole.OppositeRoleAlwaysResolveProxy.Role : nonAssimilationTargetRole;
												processAsFactType = true;
											}
										}
									}
									else if (!assimilationIsSubtype && assimilationObjectification == null)
									{
										flags |= ColumnPathStepFlags.DeclinedAssimilation;
										targetRole = towardsSubtype ? targetRole.OppositeRoleAlwaysResolveProxy.Role : nonAssimilationTargetRole;
										processAsFactType = true;
									}
									if (!processAsFactType)
									{
										if (reverseAssimilation)
										{
											flags |= ColumnPathStepFlags.ReverseAssimilation;
										}
										else
										{
											flags |= ColumnPathStepFlags.ForwardAssimilation;
										}
										if (assimilationIsSubtype)
										{
											flags |= ColumnPathStepFlags.AssimilationIsSubtype;
											if (secondarySubtype)
											{
												flags |= ColumnPathStepFlags.NonPreferredSubtype;
											}
											if (towardsSubtype)
											{
												flags |= ColumnPathStepFlags.AssimilationTowardsSubtype;
											}
										}
										pathStep = new ColumnPathStep(
											null,
											towardsSubtype ? ConceptTypeIsForObjectType.GetObjectType(comingFromConceptType) : targetRole.RolePlayer,
											towardsSubtype ? targetRole.RolePlayer : null,
											flags);
										processTailDelayed = true;
									}
								}
								if (processAsFactType)
								{
									bool haveStep = false;
									if (tailNode != null)
									{
										pathStep = tailNode.Value;
										ColumnPathStepFlags tailFlags = pathStep.Flags;
										if (0 != (tailFlags & (ColumnPathStepFlags.ForwardAssimilation | ColumnPathStepFlags.ReverseAssimilation)))
										{
											RoleProxy oppositeProxy;
											Role objectifiedResolvedProxyRole;
											Role objectifiedOppositeRole;
											if (previousAssimilationObjectification != null &&
												factType.ImpliedByObjectification == previousAssimilationObjectification &&
												null != (oppositeProxy = targetRole.OppositeRole as RoleProxy) &&
												null != (objectifiedOppositeRole = (objectifiedResolvedProxyRole = oppositeProxy.Role).OppositeRole as Role))
											{
												flags |= ColumnPathStepFlags.ObjectifiedFactType;
												// Replace both factTypes with the original unobjectified FactType
												ObjectType fromObjectType = objectifiedOppositeRole.RolePlayer;
												if (pathStep.ObjectType == previousAssimilationObjectification.NestingType)
												{
													// Trivial path leading in, remove the subtype completely
													processTailDelayed = false;
													tailNode.Value = new ColumnPathStep(objectifiedOppositeRole, objectifiedResolvedProxyRole.RolePlayer, null, flags);
													ProcessTailNode(tailNode, objectTypeToSteps);
													continue;
												}
												tailNode.Value = new ColumnPathStep(pathStep.FromRole, pathStep.ObjectType, fromObjectType, pathStep.Flags);
												pathStep = new ColumnPathStep(objectifiedOppositeRole, objectifiedResolvedProxyRole.RolePlayer, null, flags);
												haveStep = true;
											}
											else
											{
												// Add a resolved supertype to the forward subtype to
												// allow later steps to be compared to this one.
												tailNode.Value = new ColumnPathStep(pathStep.FromRole, pathStep.ObjectType, targetRole.RolePlayer, pathStep.Flags);
											}
										}
										else if (!processTailDelayed && 0 != (tailFlags & ColumnPathStepFlags.DeclinedAssimilation))
										{
											// Add a resolved supertype to the previous step
											tailNode.Value = new ColumnPathStep(pathStep.FromRole, pathStep.ObjectType, targetRole.RolePlayer, pathStep.Flags);
										}
									}
									if (!haveStep)
									{
										Role oppositeRole = targetRole.OppositeRoleAlwaysResolveProxy.Role;
										ORMUniquenessConstraint pid = targetRole.RolePlayer.PreferredIdentifier;
										if (pid != null && pid.RoleCollection.Contains(oppositeRole))
										{
											flags |= ColumnPathStepFlags.IsIdentifier;
											passedIdentifier = true;
										}
										pathStep = new ColumnPathStep(targetRole, oppositeRole.RolePlayer, null, flags);
									}
									processPreviousTail = processTailDelayed;
									processTailDelayed = false;
								}
								if (processPreviousTail && tailNode != null)
								{
									ProcessTailNode(tailNode, objectTypeToSteps);
								}
								LinkedNode<ColumnPathStep> newNode = new LinkedNode<ColumnPathStep>(pathStep);
								if (tailNode == null)
								{
									headNode = tailNode = newNode;
								}
								else
								{
									tailNode.SetNext(newNode, ref headNode);
									tailNode = newNode;
								}
								if (!processTailDelayed)
								{
									ProcessTailNode(tailNode, objectTypeToSteps);
								}
							}
						}
						if (processTailDelayed)
						{
							ProcessTailNode(tailNode, objectTypeToSteps);
						}
						columnSteps.Add(currentColumn, headNode);
					}
					Debug.Unindent();
					Debug.Unindent();
					return columnSteps[column];
				}