//NOTE: shouldnt this also load related tables in inheritance scenarios? , eg classtable inheritance?
        protected virtual string GetSelectStatement(object obj, ArrayList propertyNames, string keyPropertyName, object keyValue, IList parameters)
        {
            IPropertyMap propertyMap;
            IClassMap classMap;
            ITableMap tableMap;
            IObjectManager om;
            IColumnMap typeColumnMap;
            string paramName = "";

            classMap = m_SqlEngineManager.Context.DomainMap.MustGetClassMap(obj.GetType());

            tableMap = classMap.MustGetTableMap();
            ISourceMap sourceMap = tableMap.SourceMap;

            SqlSelectStatement select = new SqlSelectStatement(sourceMap) ;

            SqlTableAlias table = select.GetSqlTableAlias(tableMap, "t" + select.GetNextTableAliasIndex());

            foreach (IPropertyMap iPropertyMap in classMap.GetAllPropertyMaps())
            {
                propertyMap = iPropertyMap;
                if (propertyMap.IsCollection)
                {
                    if (this.Context.PersistenceManager.GetListCountLoadBehavior(LoadBehavior.Default, propertyMap) == LoadBehavior.Eager)
                    {
                        if (propertyMap.ReferenceType != ReferenceType.None)
                        {
                            ITableMap listTableMap = propertyMap.GetTableMap();

                            ISourceMap listSourceMap = listTableMap.SourceMap;

                            SqlSelectStatement subSelect = new SqlSelectStatement(listSourceMap);
                            SqlTableAlias listTable = subSelect.GetSqlTableAlias(listTableMap, "t" + select.GetNextTableAliasIndex());

                            SqlCountFunction count = new SqlCountFunction();

                            subSelect.SqlSelectClause.AddSqlAliasSelectListItem(count);

                            subSelect.SqlFromClause.AddSqlAliasTableSource(listTable);

                            foreach (IColumnMap fkIdColumnMap in propertyMap.GetAllIdColumnMaps())
                            {
                                IColumnMap idColumnMap = fkIdColumnMap.MustGetPrimaryKeyColumnMap();

                                SqlColumnAlias fkIdColumn = listTable.GetSqlColumnAlias(fkIdColumnMap);
                                SqlColumnAlias idColumn = table.GetSqlColumnAlias(idColumnMap);
                                SqlSearchCondition search = subSelect.SqlWhereClause.GetNextSqlSearchCondition();

                                search.GetSqlComparePredicate(fkIdColumn, SqlCompareOperatorType.Equals, idColumn);
                            }

                            select.SqlSelectClause.AddSqlAliasSelectListItem(subSelect, propertyMap.Name);
                            propertyNames.Add(propertyMap.Name);
                        }
                    }
                }
                else
                {
                    if (propertyMap.MustGetTableMap() == tableMap)
                    {
                        if (!(propertyMap.GetAllColumnMaps().Count > 1))
                        {
                            if (!(propertyMap.LazyLoad))
                            {
                                IColumnMap columnMap = propertyMap.GetColumnMap();
                                SqlColumnAlias column = table.GetSqlColumnAlias(columnMap);
                                select.SqlSelectClause.AddSqlAliasSelectListItem(column);
                                propertyNames.Add(propertyMap.Name);
                            }
                        }
                    }
                }
            }
            select.SqlFromClause.AddSqlAliasTableSource(table);
            om = m_SqlEngineManager.Context.ObjectManager;
            if (keyPropertyName.Length > 0)
            {
                propertyMap = classMap.MustGetPropertyMap(keyPropertyName);
                IColumnMap columnMap = propertyMap.GetColumnMap();

                SqlColumnAlias column = select.GetSqlColumnAlias(columnMap);
                SqlSearchCondition search = select.SqlWhereClause.GetSqlSearchCondition();

                paramName = GetParameterName(propertyMap, "Id_");

                //SqlParameter param = AddSqlParameter(select, parameters, paramName, obj, propertyMap, om.GetPropertyValue(obj, propertyMap.Name), columnMap);
                SqlParameter param = AddSqlParameter(select, parameters, paramName, obj, propertyMap, keyValue, columnMap, true);

                search.GetSqlComparePredicate(column, SqlCompareOperatorType.Equals, param);
            }
            else
            {
                foreach (IPropertyMap iPropertyMap in classMap.GetIdentityPropertyMaps())
                {
                    propertyMap = iPropertyMap;
                    IColumnMap columnMap = propertyMap.GetColumnMap();

                    SqlColumnAlias column = select.GetSqlColumnAlias(columnMap);
                    SqlSearchCondition search = select.SqlWhereClause.GetNextSqlSearchCondition();

                    paramName = GetParameterName(propertyMap, "Id_");
                    SqlParameter param;

                    if (om.GetPropertyStatus(obj, propertyMap.Name) == PropertyStatus.Dirty)
                        param = AddSqlParameter(select, parameters, paramName, obj, propertyMap, om.GetOriginalPropertyValue(obj, propertyMap.Name), columnMap, true);
                    else
                        param = AddSqlParameter(select, parameters, paramName, obj, propertyMap, om.GetPropertyValue(obj, propertyMap.Name), columnMap);

                    search.GetSqlComparePredicate(column, SqlCompareOperatorType.Equals, param);
                }
                typeColumnMap = classMap.GetTypeColumnMap();
                if (typeColumnMap != null)
                {
                    SqlColumnAlias column = select.GetSqlColumnAlias(typeColumnMap);
                    paramName = GetParameterName(classMap, "Type_");
                    SqlParameter param = AddSqlParameter(select, parameters, paramName, obj, null, classMap.TypeValue, typeColumnMap, true);
                    SqlSearchCondition search = select.SqlWhereClause.GetNextSqlSearchCondition();

                    search.GetSqlComparePredicate(column, SqlCompareOperatorType.Equals, param);
                }
            }
            return GenerateSql(select);;
        }
        protected virtual string GetSelectManyOnePropertyStatement(object obj, IPropertyMap propertyMap, IList idColumns, IList typeColumns, Hashtable hashPropertyColumnMap, IList parameters)
        {
            string colName = "";
            IColumnMap columnMap;
            IClassMap classMap;
            IPropertyMap refPropertyMap;
            ITableMap tableMap;
            ITableMap rootTableMap;
            IColumnMap idColumnMap;
            IPropertyMap myPropertyMap;
            IColumnMap myColumnMap;
            ITableMap myTableMap;
            IColumnMap addIdColumnMap;
            IColumnMap addMyColumnMap;
            ITableMap addMyTableMap;
            IColumnMap typeColumnMap;
            IPropertyMap orderByMap;
            string paramName = "";
            classMap = propertyMap.MustGetReferencedClassMap();

            IClassMap rootClassMap = classMap;
            rootTableMap = classMap.MustGetTableMap();
            tableMap = propertyMap.MustGetTableMap();

            if (tableMap != rootTableMap)
            {
                bool done = false;
                while (done == false && rootClassMap.InheritanceType != InheritanceType.ConcreteTableInheritance)
                {
                    done = true;
                    IClassMap super = rootClassMap.GetInheritedClassMap();
                    if (super != null)
                    {
                        if (super.MustGetTableMap() == rootTableMap)
                        {
                            rootClassMap = super ;
                            done = false;
                        }
                    }
                }
                if (rootClassMap == null)
                {
                    rootClassMap = classMap;
                }
            }

            SqlSelectStatement select = new SqlSelectStatement(tableMap.SourceMap) ;
            SqlTableAlias table = select.GetSqlTableAlias(tableMap);

            idColumnMap = propertyMap.GetIdColumnMap();
            SqlColumnAlias idColumn = table.GetSqlColumnAlias(idColumnMap);

            myTableMap = idColumnMap.MustGetPrimaryKeyTableMap();
            myColumnMap = idColumnMap.MustGetPrimaryKeyColumnMap();

            if (myTableMap == null)
                throw new MappingException("TableMap '" + idColumnMap.PrimaryKeyTable + "' Not Found!"); // do not localize
            if (myColumnMap == null)
                throw new MappingException("ColumnMap '" + idColumnMap.PrimaryKeyColumn + "' Not Found!"); // do not localize

            SqlTableAlias rootTable = table;
            if (tableMap != rootTableMap)
            {
                rootTable = select.GetSqlTableAlias(rootTableMap, "NPersistRootTable");
            }

            SqlTableAlias myTable;
            SqlColumnAlias myColumn;

            IObjectManager om;
            orderByMap = propertyMap.GetOrderByPropertyMap();

            //foreach (IPropertyMap iRefPropertyMap in rootClassMap.GetPrimaryPropertyMaps())
            foreach (IPropertyMap iRefPropertyMap in rootClassMap.GetAllPropertyMaps())
            {
                refPropertyMap = iRefPropertyMap;
                if (refPropertyMap.IsCollection)
                {
                    if (this.Context.PersistenceManager.GetListCountLoadBehavior(LoadBehavior.Default, refPropertyMap) == LoadBehavior.Eager)
                    {
                        if (refPropertyMap.ReferenceType != ReferenceType.None)
                        {
                            ITableMap listTableMap = refPropertyMap.GetTableMap();

                            ISourceMap listSourceMap = listTableMap.SourceMap;

                            SqlSelectStatement subSelect = new SqlSelectStatement(listSourceMap);
                            SqlTableAlias listTable = subSelect.GetSqlTableAlias(listTableMap, "t" + select.GetNextTableAliasIndex());

                            SqlCountFunction count = new SqlCountFunction();

                            subSelect.SqlSelectClause.AddSqlAliasSelectListItem(count);

                            subSelect.SqlFromClause.AddSqlAliasTableSource(listTable);

                            foreach (IColumnMap fkIdColumnMap in refPropertyMap.GetAllIdColumnMaps())
                            {
                                IColumnMap pkIdColumnMap = fkIdColumnMap.MustGetPrimaryKeyColumnMap();

                                SqlColumnAlias fkIdColumn = listTable.GetSqlColumnAlias(fkIdColumnMap);
                                SqlColumnAlias pkIdColumn = table.GetSqlColumnAlias(pkIdColumnMap);
                                SqlSearchCondition searchCount = subSelect.SqlWhereClause.GetNextSqlSearchCondition();

                                searchCount.GetSqlComparePredicate(fkIdColumn, SqlCompareOperatorType.Equals, pkIdColumn);
                            }

                            select.SqlSelectClause.AddSqlAliasSelectListItem(subSelect, refPropertyMap.Name);
                            hashPropertyColumnMap[refPropertyMap.Name] = refPropertyMap.Name;
                        }
                    }
                }
                else
                {
                    if (refPropertyMap.MustGetTableMap() == rootTableMap)
                    {
                        if (!((refPropertyMap.IsCollection || ((refPropertyMap.ReferenceType != ReferenceType.None && refPropertyMap.GetAdditionalColumnMaps().Count > 0) && !(refPropertyMap.IsIdentity)))))
                        {
                            IColumnMap refColumnMap = refPropertyMap.GetColumnMap();
                            //SqlColumnAlias refColumn = table.GetSqlColumnAlias(refColumnMap);
                            SqlColumnAlias refColumn = rootTable.GetSqlColumnAlias(refColumnMap);

                            colName = refColumnMap.Name;
                            if (refPropertyMap.IsIdentity)
                                idColumns.Add(colName);

                            if (!(refPropertyMap.LazyLoad))
                            {
                                select.SqlSelectClause.AddSqlAliasSelectListItem(refColumn);
                                hashPropertyColumnMap[refPropertyMap.Name] = colName;
                                if (refPropertyMap == orderByMap)
                                    select.SqlOrderByClause.AddSqlOrderByItem(refColumn);
                            }
                        }
                    }
                }
            }

            select.SqlFromClause.AddSqlAliasTableSource(table);

            typeColumnMap = classMap.GetTypeColumnMap();
            if (typeColumnMap != null)
            {
                SqlColumnAlias typeColumn = rootTable.GetSqlColumnAlias(typeColumnMap);
                select.SqlSelectClause.AddSqlAliasSelectListItem(typeColumn);
                typeColumns.Add(typeColumnMap.Name);
            }

            if (table != rootTable)
            {
                select.SqlFromClause.AddSqlAliasTableSource(rootTable);
            }

            //if (tableMap.SourceMap.Schema.ToLower(CultureInfo.InvariantCulture) == myTableMap.SourceMap.Schema.ToLower(CultureInfo.InvariantCulture) && tableMap.Name.ToLower(CultureInfo.InvariantCulture) == myTableMap.Name.ToLower(CultureInfo.InvariantCulture))
            if (myTableMap == tableMap)
                myTable = select.GetSqlTableAlias(myTableMap, "NPersistSelfRefTable");
            else
                myTable = select.GetSqlTableAlias(myTableMap, "NPersistOwnerTable");

            myColumn = myTable.GetSqlColumnAlias(myColumnMap);
            select.SqlFromClause.AddSqlAliasTableSource(myTable);

            SqlSearchCondition search = select.SqlWhereClause.GetNextSqlSearchCondition();
            search.GetSqlComparePredicate(idColumn, SqlCompareOperatorType.Equals,  myColumn);

            foreach (IColumnMap iAddIdColumnMap in propertyMap.GetAdditionalIdColumnMaps())
            {
                addIdColumnMap = iAddIdColumnMap;
                addMyTableMap = addIdColumnMap.GetPrimaryKeyTableMap();
                addMyColumnMap = addIdColumnMap.MustGetPrimaryKeyColumnMap();
                if (addMyTableMap == null)
                    throw new MappingException("TableMap '" + addIdColumnMap.PrimaryKeyTable + "' Not Found!"); // do not localize
                if (addMyColumnMap == null)
                    throw new MappingException("ColumnMap '" + addIdColumnMap.PrimaryKeyColumn + "' Not Found!"); // do not localize

                SqlColumnAlias addIdColumn = table.GetSqlColumnAlias(addIdColumnMap);
                SqlColumnAlias addMyColumn = myTable.GetSqlColumnAlias(addMyColumnMap);

                search = select.SqlWhereClause.GetNextSqlSearchCondition();
                search.GetSqlComparePredicate(addIdColumn, SqlCompareOperatorType.Equals,  addMyColumn);
            }
            if (table != rootTable)
            {
                foreach (IPropertyMap testPropertyMap in classMap.GetAllPropertyMaps())
                {
                    if (testPropertyMap.MustGetTableMap() == propertyMap.MustGetTableMap())
                    {
                        foreach (IColumnMap iAddIdColumnMap in testPropertyMap.GetAllIdColumnMaps())
                        {
                            addIdColumnMap = iAddIdColumnMap;

                            SqlColumnAlias addIdColumn = table.GetSqlColumnAlias(addIdColumnMap);
                            SqlColumnAlias rootColumn = rootTable.GetSqlColumnAlias(addIdColumnMap.MustGetPrimaryKeyColumnMap());

                            search = select.SqlWhereClause.GetNextSqlSearchCondition();
                            search.GetSqlComparePredicate(addIdColumn, SqlCompareOperatorType.Equals,  rootColumn);
                        }
                        break;
                    }
                }
            }
            om = m_SqlEngineManager.Context.ObjectManager;
            foreach (IPropertyMap iMyPropertyMap in propertyMap.ClassMap.GetIdentityPropertyMaps())
            {
                myPropertyMap = iMyPropertyMap;
                columnMap = myPropertyMap.GetColumnMap();
                SqlColumnAlias column = myTable.GetSqlColumnAlias(columnMap);
                SqlParameter param;
                paramName = GetParameterName(myPropertyMap, "Id_");
                if (om.GetPropertyStatus(obj, propertyMap.Name) == PropertyStatus.Dirty)
                    param = AddSqlParameter(select, parameters, paramName, obj, myPropertyMap, om.GetOriginalPropertyValue(obj, myPropertyMap.Name), columnMap, true);
                else
                    param = AddSqlParameter(select, parameters, paramName, obj, myPropertyMap, om.GetPropertyValue(obj, myPropertyMap.Name), columnMap);

                search = select.SqlWhereClause.GetNextSqlSearchCondition();
                search.GetSqlComparePredicate(column, SqlCompareOperatorType.Equals,  param);
            }
            typeColumnMap = propertyMap.ClassMap.GetTypeColumnMap();
            if (typeColumnMap != null)
            {
                IClassMap actual = this.Context.DomainMap.MustGetClassMap(obj.GetType());

                SqlColumnAlias typeColumn = myTable.GetSqlColumnAlias(typeColumnMap);
                paramName = GetParameterName(propertyMap.ClassMap, "Type_");
                //SqlParameter param = AddSqlParameter(select, parameters, paramName, obj, null, propertyMap.ClassMap.TypeValue, typeColumnMap, true);
                SqlParameter param = AddSqlParameter(select, parameters, paramName, obj, null, actual.TypeValue, typeColumnMap, true);

                search = select.SqlWhereClause.GetNextSqlSearchCondition();
                search.GetSqlComparePredicate(typeColumn, SqlCompareOperatorType.Equals,  param);
            }

            return GenerateSql(select);
        }