/// <summary>
        /// Add the properties for an entity.
        /// </summary>
        /// <param name="meta"></param>
        /// <param name="pClass"></param>
        /// <param name="dataList">will be populated with the data properties of the entity</param>
        /// <param name="navList">will be populated with the navigation properties of the entity</param>
        void AddClassProperties(IClassMetadata meta, PersistentClass pClass, List<Dictionary<string, object>> dataList, List<Dictionary<string, object>> navList)
        {
            // maps column names to their related data properties.  Used in MakeAssociationProperty to convert FK column names to entity property names.
            var relatedDataPropertyMap = new Dictionary<string, Dictionary<string, object>>();

            var persister = meta as AbstractEntityPersister;
            var type = pClass.MappedClass;

            var propNames = meta.PropertyNames;
            var propTypes = meta.PropertyTypes;
            var propNull = meta.PropertyNullability;
            for (int i = 0; i < propNames.Length; i++)
            {
                var propName = propNames[i];
                var pClassProp = pClass.GetProperty(propName);
                if (!hasOwnProperty(pClass, pClassProp)) continue;  // skip property defined on superclass

                var propType = propTypes[i];
                if (!propType.IsAssociationType)    // skip association types until we handle all the data types, so the relatedDataPropertyMap will be populated.
                {
                    var propColumns = pClassProp.ColumnIterator.ToList();
                    if (propType.IsComponentType)
                    {
                        // complex type
                        var compType = (ComponentType)propType;
                        var complexTypeName = AddComponent(compType, propColumns);
                        var compMap = new Dictionary<string, object>();
                        compMap.Add("nameOnServer", propName);
                        compMap.Add("complexTypeName", complexTypeName);
                        compMap.Add("isNullable", propNull[i]);
                        dataList.Add(compMap);
                    }
                    else
                    {
                        // data property
                        var col = propColumns.Count() == 1 ? propColumns[0] as Column : null;
                        var isKey = meta.HasNaturalIdentifier && meta.NaturalIdentifierProperties.Contains(i);
                        var isVersion = meta.IsVersioned && i == meta.VersionProperty;

                        var dmap = MakeDataProperty(propName, propType.Name, propNull[i], col, isKey, isVersion);
                        dataList.Add(dmap);

                        var columnNameString = GetPropertyColumnNames(persister, propName); 
                        relatedDataPropertyMap.Add(columnNameString, dmap);
                    }
                }
            }


            // Hibernate identifiers are excluded from the list of data properties, so we have to add them separately
            if (meta.HasIdentifierProperty && hasOwnProperty(pClass, meta.IdentifierPropertyName))
            {
                var dmap = MakeDataProperty(meta.IdentifierPropertyName, meta.IdentifierType.Name, false, null, true, false);
                dataList.Insert(0, dmap);

                var columnNameString = GetPropertyColumnNames(persister, meta.IdentifierPropertyName);
                relatedDataPropertyMap.Add(columnNameString, dmap);
            }
            else if (meta.IdentifierType != null && meta.IdentifierType.IsComponentType 
                && pClass.Identifier is Component && ((Component)pClass.Identifier).Owner == pClass)
            {
                // composite key is a ComponentType
                var compType = (ComponentType)meta.IdentifierType;
                var compNames = compType.PropertyNames;
                for (int i = 0; i < compNames.Length; i++)
                {
                    var compName = compNames[i];

                    var propType = compType.Subtypes[i];
                    if (!propType.IsAssociationType)
                    {
                        var dmap = MakeDataProperty(compName, propType.Name, compType.PropertyNullability[i], null, true, false);
                        dataList.Insert(0, dmap);
                    }
                    else
                    {
                        var manyToOne = propType as ManyToOneType;
                        //var joinable = manyToOne.GetAssociatedJoinable(this._sessionFactory);
                        var propColumnNames = GetPropertyColumnNames(persister, compName);

                        var assProp = MakeAssociationProperty(type, (IAssociationType)propType, compName, propColumnNames, pClass, relatedDataPropertyMap, true);
                        navList.Add(assProp);
                    }
                }
            }

            // We do the association properties after the data properties, so we can do the foreign key lookups
            for (int i = 0; i < propNames.Length; i++)
            {
                var propName = propNames[i];
                if (!hasOwnProperty(pClass, propName)) continue;  // skip property defined on superclass 

                var propType = propTypes[i];
                if (propType.IsAssociationType)
                {
                    // navigation property
                    var propColumnNames = GetPropertyColumnNames(persister, propName);
                    var assProp = MakeAssociationProperty(type, (IAssociationType)propType, propName, propColumnNames, pClass, relatedDataPropertyMap, false);
                    navList.Add(assProp);
                }
            }
        }
		private IDictionary<string, string[]> BindPropertyResults(string alias, HbmReturnDiscriminator discriminatorSchema,
			HbmReturnProperty[] returnProperties, PersistentClass pc)
		{
			Dictionary<string, string[]> propertyresults = new Dictionary<string, string[]>();
			// maybe a concrete SQLpropertyresult type, but Map is exactly what is required at the moment

			if (discriminatorSchema != null)
			{
				propertyresults["class"] = GetResultColumns(discriminatorSchema).ToArray();
			}

			List<HbmReturnProperty> properties = new List<HbmReturnProperty>();
			List<string> propertyNames = new List<string>();

			foreach (HbmReturnProperty returnPropertySchema in returnProperties ?? new HbmReturnProperty[0])
			{
				string name = returnPropertySchema.name;
				if (pc == null || name.IndexOf('.') == -1)
				{
					//if dotted and not load-collection nor return-join
					//regular property
					properties.Add(returnPropertySchema);
					propertyNames.Add(name);
				}
				else
				{
					// Reorder properties
					// 1. get the parent property
					// 2. list all the properties following the expected one in the parent property
					// 3. calculate the lowest index and insert the property

					int dotIndex = name.LastIndexOf('.');
					string reducedName = name.Substring(0, dotIndex);
					IValue value = pc.GetRecursiveProperty(reducedName).Value;
					IEnumerable<Mapping.Property> parentPropIter;
					if (value is Component)
					{
						Component comp = (Component) value;
						parentPropIter = comp.PropertyIterator;
					}
					else if (value is ToOne)
					{
						ToOne toOne = (ToOne) value;
						PersistentClass referencedPc = mappings.GetClass(toOne.ReferencedEntityName);
						if (toOne.ReferencedPropertyName != null)
							try
							{
								parentPropIter =
									((Component) referencedPc.GetRecursiveProperty(toOne.ReferencedPropertyName).Value).PropertyIterator;
							}
							catch (InvalidCastException e)
							{
								throw new MappingException("dotted notation reference neither a component nor a many/one to one", e);
							}
						else
							try
							{
								parentPropIter = ((Component) referencedPc.IdentifierProperty.Value).PropertyIterator;
							}
							catch (InvalidCastException e)
							{
								throw new MappingException("dotted notation reference neither a component nor a many/one to one", e);
							}
					}
					else
						throw new MappingException("dotted notation reference neither a component nor a many/one to one");
					bool hasFollowers = false;
					List<string> followers = new List<string>();
					foreach (Mapping.Property prop in parentPropIter)
					{
						string currentPropertyName = prop.Name;
						string currentName = reducedName + '.' + currentPropertyName;
						if (hasFollowers)
							followers.Add(currentName);
						if (name.Equals(currentName))
							hasFollowers = true;
					}

					int index = propertyNames.Count;
					int followersSize = followers.Count;
					for (int loop = 0; loop < followersSize; loop++)
					{
						string follower = followers[loop];
						int currentIndex = GetIndexOfFirstMatchingProperty(propertyNames, follower);
						index = currentIndex != -1 && currentIndex < index ? currentIndex : index;
					}
					propertyNames.Insert(index, name);
					properties.Insert(index, returnPropertySchema);
				}
			}

			var uniqueReturnProperty = new HashSet<string>();
			foreach (HbmReturnProperty returnPropertySchema in properties)
			{
				string name = returnPropertySchema.name;
				if ("class".Equals(name))
					throw new MappingException(
						"class is not a valid property name to use in a <return-property>, use <return-discriminator> instead"
						);
				//TODO: validate existing of property with the chosen name. (secondpass )
				List<string> allResultColumns = GetResultColumns(returnPropertySchema);

				if (allResultColumns.Count == 0)
					throw new MappingException(
						"return-property for alias " + alias +
							" must specify at least one column or return-column name"
						);
				if (uniqueReturnProperty.Contains(name))
					throw new MappingException(
						"duplicate return-property for property " + name +
							" on alias " + alias
						);
				uniqueReturnProperty.Add(name);

				// the issue here is that for <return-join/> representing an entity collection,
				// the collection element values (the property values of the associated entity)
				// are represented as 'element.{propertyname}'.  Thus the StringHelper.root()
				// here puts everything under 'element' (which additionally has significant
				// meaning).  Probably what we need to do is to something like this instead:
				//      String root = StringHelper.root( name );
				//      String key = root; // by default
				//      if ( !root.equals( name ) ) {
				//	        // we had a dot
				//          if ( !root.equals( alias ) {
				//              // the root does not apply to the specific alias
				//              if ( "elements".equals( root ) {
				//                  // we specifically have a <return-join/> representing an entity collection
				//                  // and this <return-property/> is one of that entity's properties
				//                  key = name;
				//              }
				//          }
				//      }
				// but I am not clear enough on the intended purpose of this code block, especially
				// in relation to the "Reorder properties" code block above... 
				//			String key = StringHelper.root( name );
				string key = name;
				string[] intermediateResults;
				if (!propertyresults.TryGetValue(key,out intermediateResults))
					propertyresults[key] = allResultColumns.ToArray();
				else
				{
					throw new NotImplementedException();
					// 2013-02-24: In 89994bc113e1bb35bf6bcd0b7408d08340bfbccd, 2008-05-29, the intermediateResults
					// variable was changed from ArrayList to string[]. The following code line was there before.
					// Since an array cannot be modified, it seems this code line has never been hit since then.
					// While working on NH-3345, I'm adding an ambigous overload for AddAll(), and I don't want to
					// try to understand this code right now, so comment it out instead. /Oskar
					//ArrayHelper.AddAll(intermediateResults, allResultColumns); // TODO: intermediateResults not used after this
				}
			}

			Dictionary<string, string[]> newPropertyResults = new Dictionary<string, string[]>();

			foreach (KeyValuePair<string, string[]> entry in propertyresults)
			{
				newPropertyResults[entry.Key] = entry.Value;
			}
			return newPropertyResults.Count == 0 ? (IDictionary<string, string[]>)new CollectionHelper.EmptyMapClass<string, string[]>() : newPropertyResults;
		}