context: using System;
  using System.Collections;
  using NHibernate.Engine;
  using NHibernate.SqlCommand;
  using NHibernate.Util;
  using System.Collections.Generic;
  using System.Collections.ObjectModel;
  using System.Linq;
  
  namespace NHibernate.Mapping
  {
  	/// <summary>
  	/// Base class for the <see cref="RootClazz" /> mapped by <c>&lt;class&gt;</c> and a 
  	/// <see cref="Subclass"/> that is mapped by <c>&lt;subclass&gt;</c> or 
  	/// <c>&lt;joined-subclass&gt;</c>.
  	/// </summary>
  	[Serializable]
  	public abstract class PersistentClass : IFilterable, IMetaAttributable, ISqlCustomizable
  	{
  		private static readonly Alias PKAlias = new Alias(15, "PK");
  
  		/// <summary></summary>
  		public const string NullDiscriminatorMapping = "null";
  
  		/// <summary></summary>
  		public const string NotNullDiscriminatorMapping = "not null";
  
  		private string entityName;
  		private string className;
  		private string proxyInterfaceName;
  		private string discriminatorValue;
  		private bool lazy;
  		private readonly List<Property> properties = new List<Property>();
  		private readonly List<Subclass> subclasses = new List<Subclass>();
  		private readonly List<Property> subclassProperties = new List<Property>();
  		private readonly List<Table> subclassTables = new List<Table>();
  		private bool dynamicInsert;
  		private bool dynamicUpdate;
  		private int? batchSize;
  		private bool selectBeforeUpdate;
  		private IDictionary<string, MetaAttribute> metaAttributes;
  		private readonly List<Join> joins = new List<Join>();
  		private readonly List<Join> subclassJoins = new List<Join>();
  		private readonly IDictionary<string, string> filters = new Dictionary<string, string>();
  		private readonly ISet<string> synchronizedTables = new HashSet<string>();
  		private string loaderName;
  		private bool? isAbstract;
  		private bool hasSubselectLoadableCollections;
  		private Component identifierMapper;
  		private SqlString customSQLInsert;
  		private bool customInsertCallable;
  		private ExecuteUpdateResultCheckStyle insertCheckStyle;
  		private SqlString customSQLUpdate;
  		private bool customUpdateCallable;
  		private ExecuteUpdateResultCheckStyle updateCheckStyle;
  		private SqlString customSQLDelete;
  		private bool customDeleteCallable;
  		private ExecuteUpdateResultCheckStyle deleteCheckStyle;
  		private string temporaryIdTableName;
  		private string temporaryIdTableDDL;
  
  		private IDictionary<EntityMode, string> tuplizerImpls;
  
  		private Versioning.OptimisticLock optimisticLockMode;
  
  		private System.Type mappedClass;
  		private System.Type proxyInterface;
  
  		public string ClassName
  		{
  			get { return className; }
  			set
  			{
  				className = value == null ? null : string.Intern(value);
  				mappedClass = null;
  			}
  		}
  
  		public string ProxyInterfaceName
  		{
  			get { return proxyInterfaceName; }
  			set
  			{
  				proxyInterfaceName = value;
  				proxyInterface = null;
  			}
  		}
  
  		/// <summary>
  		/// Gets the <see cref="System.Type"/> that is being mapped.
  		/// </summary>
  		/// <value>The <see cref="System.Type"/> that is being mapped.</value>
  		/// <remarks>
  		/// The value of this is set by the <c>name</c> attribute on the <c>&lt;class&gt;</c> 
  		/// element.
  		/// </remarks>
  		public virtual System.Type MappedClass
  		{
  			get
  			{
  				if (mappedClass == null)
  				{
  					if (className == null)
  						return null;
  					try
  					{
  						mappedClass = ReflectHelper.ClassForName(className);
  					}
  					catch (Exception cnfe)
  					{
  						throw new MappingException("entity class not found: " + className, cnfe);
  					}
  				}
  				return mappedClass;
  			}
  		}
  
  		/// <summary>
  		/// Gets or sets the <see cref="System.Type"/> to use as a Proxy.
  		/// </summary>
  		/// <value>The <see cref="System.Type"/> to use as a Proxy.</value>
  		/// <remarks>
  		/// The value of this is set by the <c>proxy</c> attribute. 
  		/// </remarks>
  		public virtual System.Type ProxyInterface
  		{
  			get
  			{
  				if (proxyInterface == null)
  				{
  					if (proxyInterfaceName == null)
  						return null;
  					try
  					{
  						proxyInterface = ReflectHelper.ClassForName(proxyInterfaceName);
  					}
  					catch (Exception cnfe)
  					{
  						throw new MappingException("proxy class not found: " + proxyInterfaceName, cnfe);
  					}
  				}
  				return proxyInterface;
  			}
  		}
  
  		public abstract int SubclassId { get; }
  
  		/// <summary>
  		/// Gets or Sets if the Insert Sql is built dynamically.
  		/// </summary>
  		/// <value><see langword="true" /> if the Sql is built at runtime.</value>
  		/// <remarks>
  		/// The value of this is set by the <c>dynamic-insert</c> attribute. 
  		/// </remarks>
  		public virtual bool DynamicInsert
  		{
  			get { return dynamicInsert; }
  			set { dynamicInsert = value; }
  		}
  
  		/// <summary>
  		/// Gets or Sets if the Update Sql is built dynamically.
  		/// </summary>
  		/// <value><see langword="true" /> if the Sql is built at runtime.</value>
  		/// <remarks>
  		/// The value of this is set by the <c>dynamic-update</c> attribute. 
  		/// </remarks>
  		public virtual bool DynamicUpdate
  		{
  			get { return dynamicUpdate; }
  			set { dynamicUpdate = value; }
  		}
  
  		/// <summary>
  		/// Gets or Sets the value to use as the discriminator for the Class.
  		/// </summary>
  		/// <value>
  		/// A value that distinguishes this subclass in the database.
  		/// </value>
  		/// <remarks>
  		/// The value of this is set by the <c>discriminator-value</c> attribute.  Each <c>&lt;subclass&gt;</c>
  		/// in a hierarchy must define a unique <c>discriminator-value</c>.  The default value 
  		/// is the class name if no value is supplied.
  		/// </remarks>
  		public virtual string DiscriminatorValue
  		{
  			get { return discriminatorValue; }
  			set { discriminatorValue = value; }
  		}
  
  		/// <summary>
  		/// Gets the number of subclasses that inherit either directly or indirectly.
  		/// </summary>
  		/// <value>The number of subclasses that inherit from this PersistentClass.</value>
  		public virtual int SubclassSpan
  		{
  			get
  			{
  				int n = subclasses.Count;
  				foreach (Subclass sc in subclasses)
  					n += sc.SubclassSpan;
  
  				return n;
  			}
  		}
  
  		/// <summary>
  		/// Iterate over subclasses in a special 'order', most derived subclasses first.
  		/// </summary>
  		/// <value>
  		/// It will recursively go through Subclasses so that if a SubclassType has Subclasses
  		/// it will pick those up also.
  		/// </value>
  		public virtual IEnumerable<Subclass> SubclassIterator
  		{
  			get
  			{
  				IEnumerable<Subclass>[] iters = new IEnumerable<Subclass>[subclasses.Count + 1];
  				int i = 0;
  				foreach (Subclass subclass in subclasses)
  					iters[i++] = subclass.SubclassIterator;
  
  				iters[i] = subclasses;
  				return new JoinedEnumerable<Subclass>(iters);
  			}
  		}
  
  		public virtual IEnumerable<PersistentClass> SubclassClosureIterator
  		{
  			get
  			{
  				List<IEnumerable<PersistentClass>> iters = new List<IEnumerable<PersistentClass>>();
  				iters.Add(new SingletonEnumerable<PersistentClass>(this));
  				foreach (Subclass clazz in SubclassIterator)
  					iters.Add(clazz.SubclassClosureIterator);
  
  				return new JoinedEnumerable<PersistentClass>(iters);
  			}
  
  		}
  
  		public virtual Table IdentityTable
  		{
  			get { return RootTable; }
  		}
  
  		/// <summary>
  		/// Gets an <see cref="IEnumerable"/> of <see cref="Subclass"/> objects
  		/// that directly inherit from this PersistentClass.
  		/// </summary>
  		/// <value>
  		/// An <see cref="IEnumerable"/> of <see cref="Subclass"/> objects
  		/// that directly inherit from this PersistentClass.
  		/// </value>
  		public virtual IEnumerable<Subclass> DirectSubclasses
  		{
  			get { return subclasses; }
  		}
  
  		public virtual string EntityName
  		{
  			get { return entityName; }
  			set { entityName = value == null ? null : String.Intern(value); }
  		}
  
  		/// <summary>
  		/// When implemented by a class, gets a boolean indicating if this
  		/// mapped class is inherited from another. 
  		/// </summary>
  		/// <value>
  		/// <see langword="true" /> if this class is a <c>subclass</c> or <c>joined-subclass</c>
  		/// that inherited from another <c>class</c>.
  		/// </value>
  		public abstract bool IsInherited { get; }
  
  		/// <summary>
  		/// When implemented by a class, gets a boolean indicating if the mapped class
  		/// has a version property.
  		/// </summary>
  		/// <value><see langword="true" /> if there is a <c>&lt;version&gt;</c> property.</value>
  		public abstract bool IsVersioned { get; }
  
  		/// <summary>
  		/// When implemented by a class, gets an <see cref="IEnumerable"/> 
  		/// of <see cref="Property"/> objects that this mapped class contains.
  		/// </summary>
  		/// <value>
  		/// An <see cref="IEnumerable"/> of <see cref="Property"/> objects that 
  		/// this mapped class contains.
  		/// </value>
  		/// <remarks>
  		/// This is all of the properties of this mapped class and each mapped class that
  		/// it is inheriting from.
  		/// </remarks>
  		public abstract IEnumerable<Property> PropertyClosureIterator { get; }
  
  		/// <summary>
  		/// When implemented by a class, gets an <see cref="IEnumerable"/> 
  		/// of <see cref="Table"/> objects that this mapped class reads from
  		/// and writes to.
  		/// </summary>
  		/// <value>
  		/// An <see cref="IEnumerable"/> of <see cref="Table"/> objects that 
  		/// this mapped class reads from and writes to.
  		/// </value>
  		/// <remarks>
  		/// This is all of the tables of this mapped class and each mapped class that
  		/// it is inheriting from.
  		/// </remarks>
  		public abstract IEnumerable<Table> TableClosureIterator { get; }
  
  		public abstract IEnumerable<IKeyValue> KeyClosureIterator { get; }
  
  		/// <summary>
  		/// Gets an <see cref="IEnumerable"/> of <see cref="Property"/> objects that
  		/// this mapped class contains and that all of its subclasses contain.
  		/// </summary>
  		/// <value>
  		/// An <see cref="IEnumerable"/> of <see cref="Property"/> objects that
  		/// this mapped class contains and that all of its subclasses contain.
  		/// </value>
  		public virtual IEnumerable<Property> SubclassPropertyClosureIterator
  		{
  			get
  			{
  				List<IEnumerable<Property>> iters = new List<IEnumerable<Property>>();
  				iters.Add(PropertyClosureIterator);
  				iters.Add(subclassProperties);
  				foreach (Join join in subclassJoins)
  					iters.Add(join.PropertyIterator);
  
  				return new JoinedEnumerable<Property>(iters);
  			}
  		}
  
  		public virtual IEnumerable<Join> SubclassJoinClosureIterator
  		{
  			get { return new JoinedEnumerable<Join>(JoinClosureIterator, subclassJoins); }
  		}
  
  		/// <summary>
  		/// Gets an <see cref="IEnumerable"/> of all of the <see cref="Table"/> objects that the 
  		/// subclass finds its information in.  
  		/// </summary>
  		/// <value>An <see cref="IEnumerable"/> of <see cref="Table"/> objects.</value>
  		/// <remarks>It adds the TableClosureIterator and the subclassTables into the IEnumerable.</remarks>
  		public virtual IEnumerable<Table> SubclassTableClosureIterator
  		{
  			get { return new JoinedEnumerable<Table>(TableClosureIterator, subclassTables); }
  		}
  
  		public bool IsLazy
  		{
  			get { return lazy; }
  			set { lazy = value; }
  		}
  
  		/// <summary>
  		/// When implemented by a class, gets or sets the <see cref="System.Type"/> of the Persister.
  		/// </summary>
  		public abstract System.Type EntityPersisterClass { get; set; }
  
  		/// <summary>
  		/// When implemented by a class, gets the <see cref="Table"/> of the class
  		/// that is mapped in the <c>class</c> element.
  		/// </summary>
  		/// <value>
  		/// The <see cref="Table"/> of the class that is mapped in the <c>class</c> element.
  		/// </value>
  		public abstract Table RootTable { get; }
  
  		/// <summary>
  		/// 
  		/// </summary>
  		public int? BatchSize
  		{
  			get { return batchSize; }
  			set { batchSize = value; }
  		}
  
  		/// <summary>
  		/// 
  		/// </summary>
  		public bool SelectBeforeUpdate
  		{
  			get { return selectBeforeUpdate; }
  			set { selectBeforeUpdate = value; }
  		}
  
  		/// <summary>
  		/// Build a collection of properties which are "referenceable".
  		/// </summary>
  		/// <remarks>
  		/// See <see cref="GetReferencedProperty"/> for a discussion of "referenceable".
  		/// </remarks>
  		public virtual IEnumerable<Property> ReferenceablePropertyIterator
  		{
  			get { return PropertyClosureIterator; }
  		}
  
  		/// <summary>
  		/// 
  		/// </summary>
  		public bool IsDiscriminatorValueNotNull
  		{
  			get { return NotNullDiscriminatorMapping.Equals(DiscriminatorValue); }
  		}
  
  		/// <summary>
  		/// 
  		/// </summary>
  		public bool IsDiscriminatorValueNull
  		{
  			get { return NullDiscriminatorMapping.Equals(DiscriminatorValue); }
  		}
  
  		public IDictionary<string, MetaAttribute> MetaAttributes
  		{
  			get { return metaAttributes; }
  			set { metaAttributes = value; }
  		}
  
  		public virtual IEnumerable<Join> JoinIterator
  		{
  			get { return joins; }
  		}
  
  		public virtual IEnumerable<Join> JoinClosureIterator
  		{
  			get { return joins; }
  		}
  
  		public virtual int JoinClosureSpan
  		{
  			get { return joins.Count; }
  		}
  
  		public virtual int PropertyClosureSpan
  		{
  			get { return properties.Count + joins.Sum(j => j.PropertySpan); }
  		}
  
  		/// <summary> 
  		/// Build an iterator over the properties defined on this class.  The returned
  		/// iterator only accounts for "normal" properties (i.e. non-identifier
  		/// properties).
  		/// </summary>
  		/// <value>
  		/// An <see cref="IEnumerable"/> of <see cref="Property"/> objects.
  		/// </value>
  		/// <remarks>
  		/// Differs from <see cref="UnjoinedPropertyIterator"/> in that the iterator
  		/// we return here will include properties defined as part of a join.
  		/// </remarks>
  		public virtual IEnumerable<Property> PropertyIterator
  		{
  			get
  			{
  				List<IEnumerable<Property>> iterators = new List<IEnumerable<Property>>();
  				iterators.Add(properties);
  				foreach (Join join in joins)
  					iterators.Add(join.PropertyIterator);
  
  				return new JoinedEnumerable<Property>(iterators);
  			}
  		}
  
  		/// <summary> 
  		/// Build an enumerable over the properties defined on this class <b>which
  		/// are not defined as part of a join</b>.  
  		/// As with <see cref="PropertyIterator"/> the returned iterator only accounts 
  		/// for non-identifier properties.
  		/// </summary>
  		/// <returns> An enumerable over the non-joined "normal" properties.</returns>
  		public virtual IEnumerable<Property> UnjoinedPropertyIterator
  		{
  			get { return properties; }
  		}
  
  		public bool IsCustomInsertCallable
  		{
  			get { return customInsertCallable; }
  		}
  
  		public ExecuteUpdateResultCheckStyle CustomSQLInsertCheckStyle
  		{
  			get { return insertCheckStyle; }
  		}
  
  		public bool IsCustomUpdateCallable
  		{
  			get { return customUpdateCallable; }
  		}
  
  		public ExecuteUpdateResultCheckStyle CustomSQLUpdateCheckStyle
  		{
  			get { return updateCheckStyle; }
  		}
  
  		public bool IsCustomDeleteCallable
  		{
  			get { return customDeleteCallable; }
  		}
  
  		public ExecuteUpdateResultCheckStyle CustomSQLDeleteCheckStyle
  		{
  			get { return deleteCheckStyle; }
  		}
  
  		public virtual IDictionary<string, string> FilterMap
  		{
  			get { return filters; }
  		}
  
  		/// <summary>
  		/// 
  		/// </summary>
  		public abstract bool IsJoinedSubclass { get; }
  
  		public string LoaderName
  		{
  			get { return loaderName; }
  			set { loaderName = value == null ? null : string.Intern(value); }
  		}
  
  		public virtual ISet<string> SynchronizedTables
  		{
  			get
  			{
  				return synchronizedTables;
  			}
  		}
  
  		protected internal virtual IEnumerable<Property> NonDuplicatedPropertyIterator
  		{
  			get { return UnjoinedPropertyIterator; }
  		}
  
  		protected virtual internal IEnumerable<ISelectable> DiscriminatorColumnIterator
  		{
  			get { return new CollectionHelper.EmptyEnumerableClass<ISelectable>(); }
  		}
  
  		public virtual bool HasSubselectLoadableCollections
  		{
  			get { return hasSubselectLoadableCollections; }
  			set { hasSubselectLoadableCollections = value; }
  		}
  
  		public string TemporaryIdTableName
  		{
  			get { return temporaryIdTableName; }
  		}
  
  		public string TemporaryIdTableDDL
  		{
  			get { return temporaryIdTableDDL; }
  		}
  
  		public virtual IDictionary<EntityMode, string> TuplizerMap
  		{
  			get
  			{
  				return tuplizerImpls == null ? null : new ReadOnlyDictionary<EntityMode, string>(tuplizerImpls);
  			}
  		}
  
  
gt: 		internal abstract int NextSubclassId();