/// <summary>
        /// Deserialize a TypeAlias object
        /// </summary>
        /// <param name="node"></param>
        /// <param name="configScope"></param>
        /// <returns></returns>
        public static void Deserialize(XmlNode node, ConfigurationScope configScope)
        {
            TypeAlias typeAlias = new TypeAlias();
            configScope.ErrorContext.MoreInfo = "loading type alias";

            NameValueCollection prop = NodeUtils.ParseAttributes(node, configScope.Properties);
            typeAlias.Name = NodeUtils.GetStringAttribute(prop,"alias");
            typeAlias.ClassName = NodeUtils.GetStringAttribute(prop, "type");

            configScope.ErrorContext.ObjectId = typeAlias.ClassName;
            configScope.ErrorContext.MoreInfo = "initialize type alias";

            typeAlias.Initialize();

            configScope.SqlMapper.TypeHandlerFactory.AddTypeAlias( typeAlias.Name, typeAlias );
        }
 /// <summary>
 /// Adds a named TypeAlias to the list of available TypeAlias.
 /// </summary>
 /// <param name="key">The key name.</param>
 /// <param name="typeAlias"> The TypeAlias.</param>
 internal void AddTypeAlias(string key, TypeAlias typeAlias)
 {
     if (_typeAliasMaps.Contains(key) == true)
     {
         throw new DataMapperException(" Alias name conflict occurred.  The type alias '" + key + "' is already mapped to the value '" + typeAlias.ClassName + "'.");
     }
     _typeAliasMaps.Add(key, typeAlias);
 }
        /// <summary>
        /// Intialize the internal ISqlMapper instance.
        /// </summary>
        private void Initialize()
        {
            Reset();

            #region Load Global Properties
            if (_configScope.IsCallFromDao == false)
            {
                _configScope.NodeContext = _configScope.SqlMapConfigDocument.SelectSingleNode( ApplyDataMapperNamespacePrefix(XML_DATAMAPPER_CONFIG_ROOT), _configScope.XmlNamespaceManager);

                ParseGlobalProperties();
            }
            #endregion

            #region Load settings

            _configScope.ErrorContext.Activity = "loading global settings";

            XmlNodeList settings = _configScope.SqlMapConfigDocument.SelectNodes( ApplyDataMapperNamespacePrefix(XML_CONFIG_SETTINGS), _configScope.XmlNamespaceManager);

            if (settings!=null)
            {
                foreach (XmlNode setting in settings)
                {
                    if (setting.Attributes[ATR_USE_STATEMENT_NAMESPACES] != null )
                    {
                        string value = NodeUtils.ParsePropertyTokens(setting.Attributes[ATR_USE_STATEMENT_NAMESPACES].Value, _configScope.Properties);
                        _configScope.UseStatementNamespaces =  Convert.ToBoolean( value );
                    }
                    if (setting.Attributes[ATR_CACHE_MODELS_ENABLED] != null )
                    {
                        string value = NodeUtils.ParsePropertyTokens(setting.Attributes[ATR_CACHE_MODELS_ENABLED].Value, _configScope.Properties);
                        _configScope.IsCacheModelsEnabled =  Convert.ToBoolean( value );
                    }
                    if (setting.Attributes[ATR_USE_REFLECTION_OPTIMIZER] != null )
                    {
                        string value = NodeUtils.ParsePropertyTokens(setting.Attributes[ATR_USE_REFLECTION_OPTIMIZER].Value, _configScope.Properties);
                        _configScope.UseReflectionOptimizer =  Convert.ToBoolean( value );
                    }
                    if (setting.Attributes[ATR_VALIDATE_SQLMAP] != null )
                    {
                        string value = NodeUtils.ParsePropertyTokens(setting.Attributes[ATR_VALIDATE_SQLMAP].Value, _configScope.Properties);
                        _configScope.ValidateSqlMap =  Convert.ToBoolean( value );
                    }
                }
            }

            #endregion

            if (_objectFactory == null)
            {
                _objectFactory = new ObjectFactory(_configScope.UseReflectionOptimizer);
            }
            if (_setAccessorFactory == null)
            {
                _setAccessorFactory = new SetAccessorFactory(_configScope.UseReflectionOptimizer);
            }
            if (_getAccessorFactory == null)
            {
                _getAccessorFactory = new GetAccessorFactory(_configScope.UseReflectionOptimizer);
            }
            if (_sqlMapper == null)
            {
                AccessorFactory accessorFactory = new AccessorFactory(_setAccessorFactory, _getAccessorFactory);
                _configScope.SqlMapper = new SqlMapper(_objectFactory, accessorFactory);
            }
            else
            {
                _configScope.SqlMapper = _sqlMapper;
            }

            ParameterMap emptyParameterMap = new ParameterMap(_configScope.DataExchangeFactory);
            emptyParameterMap.Id = ConfigurationScope.EMPTY_PARAMETER_MAP;
            _configScope.SqlMapper.AddParameterMap( emptyParameterMap );

            _configScope.SqlMapper.IsCacheModelsEnabled = _configScope.IsCacheModelsEnabled;

            #region Cache Alias

            TypeAlias cacheAlias = new TypeAlias(typeof(MemoryCacheControler));
            cacheAlias.Name = "MEMORY";
            _configScope.SqlMapper.TypeHandlerFactory.AddTypeAlias(cacheAlias.Name, cacheAlias);
            cacheAlias = new TypeAlias(typeof(LruCacheController));
            cacheAlias.Name = "LRU";
            _configScope.SqlMapper.TypeHandlerFactory.AddTypeAlias(cacheAlias.Name, cacheAlias);
            cacheAlias = new TypeAlias(typeof(FifoCacheController));
            cacheAlias.Name = "FIFO";
            _configScope.SqlMapper.TypeHandlerFactory.AddTypeAlias(cacheAlias.Name, cacheAlias);
            cacheAlias = new TypeAlias(typeof(AnsiStringTypeHandler));
            cacheAlias.Name = "AnsiStringTypeHandler";
            _configScope.SqlMapper.TypeHandlerFactory.AddTypeAlias(cacheAlias.Name, cacheAlias);

            #endregion

            #region Load providers
            if (_configScope.IsCallFromDao == false)
            {
                GetProviders();
            }
            #endregion

            #region Load DataBase
            #region Choose the  provider
            IDbProvider provider = null;
            if ( _configScope.IsCallFromDao==false )
            {
                provider = ParseProvider();
                _configScope.ErrorContext.Reset();
            }
            #endregion

            #region Load the DataSources

            _configScope.ErrorContext.Activity = "loading Database DataSource";
            XmlNode nodeDataSource = _configScope.SqlMapConfigDocument.SelectSingleNode( ApplyDataMapperNamespacePrefix(XML_DATABASE_DATASOURCE), _configScope.XmlNamespaceManager );

            if (nodeDataSource == null)
            {
                if (_configScope.IsCallFromDao == false)
                {
                    throw new ConfigurationException("There's no dataSource tag in SqlMap.config.");
                }
                else  // patch from Luke Yang
                {
                    _configScope.SqlMapper.DataSource = _configScope.DataSource;
                }
            }
            else
            {
                if (_configScope.IsCallFromDao == false)
                {
                    _configScope.ErrorContext.Resource = nodeDataSource.OuterXml.ToString();
                    _configScope.ErrorContext.MoreInfo = "parse DataSource";

                    DataSource dataSource = DataSourceDeSerializer.Deserialize( nodeDataSource );

                    dataSource.DbProvider = provider;
                    dataSource.ConnectionString = NodeUtils.ParsePropertyTokens(dataSource.ConnectionString, _configScope.Properties);

                    _configScope.DataSource = dataSource;
                    _configScope.SqlMapper.DataSource = _configScope.DataSource;
                }
                else
                {
                    _configScope.SqlMapper.DataSource = _configScope.DataSource;
                }
                _configScope.ErrorContext.Reset();
            }
            #endregion
            #endregion

            #region Load Global TypeAlias
            foreach (XmlNode xmlNode in _configScope.SqlMapConfigDocument.SelectNodes( ApplyDataMapperNamespacePrefix(XML_GLOBAL_TYPEALIAS), _configScope.XmlNamespaceManager))
            {
                _configScope.ErrorContext.Activity = "loading global Type alias";
                TypeAliasDeSerializer.Deserialize(xmlNode, _configScope);
            }
            _configScope.ErrorContext.Reset();
            #endregion

            #region Load TypeHandlers
            foreach (XmlNode xmlNode in _configScope.SqlMapConfigDocument.SelectNodes( ApplyDataMapperNamespacePrefix(XML_GLOBAL_TYPEHANDLER), _configScope.XmlNamespaceManager))
            {
                try
                {
                    _configScope.ErrorContext.Activity = "loading typeHandler";
                    TypeHandlerDeSerializer.Deserialize( xmlNode, _configScope );
                }
                catch (Exception e)
                {
                    NameValueCollection prop = NodeUtils.ParseAttributes(xmlNode, _configScope.Properties);

                    throw new ConfigurationException(
                        String.Format("Error registering TypeHandler class \"{0}\" for handling .Net type \"{1}\" and dbType \"{2}\". Cause: {3}",
                        NodeUtils.GetStringAttribute(prop, "callback"),
                        NodeUtils.GetStringAttribute(prop, "type"),
                        NodeUtils.GetStringAttribute(prop, "dbType"),
                        e.Message), e);
                }
            }
            _configScope.ErrorContext.Reset();
            #endregion

            #region Load sqlMap mapping files

            foreach (XmlNode xmlNode in _configScope.SqlMapConfigDocument.SelectNodes( ApplyDataMapperNamespacePrefix(XML_SQLMAP), _configScope.XmlNamespaceManager))
            {
                _configScope.NodeContext = xmlNode;
                ConfigureSqlMap();
            }

            #endregion

            #region Attach CacheModel to statement

            if (_configScope.IsCacheModelsEnabled)
            {
                foreach(DictionaryEntry entry in _configScope.SqlMapper.MappedStatements)
                {
                    _configScope.ErrorContext.Activity = "Set CacheModel to statement";

                    IMappedStatement mappedStatement = (IMappedStatement)entry.Value;
                    if (mappedStatement.Statement.CacheModelName.Length >0)
                    {
                        _configScope.ErrorContext.MoreInfo = "statement : "+mappedStatement.Statement.Id;
                        _configScope.ErrorContext.Resource = "cacheModel : " +mappedStatement.Statement.CacheModelName;
                        mappedStatement.Statement.CacheModel = _configScope.SqlMapper.GetCache(mappedStatement.Statement.CacheModelName);
                    }
                }
            }
            _configScope.ErrorContext.Reset();
            #endregion

            #region Register Trigger Statements for Cache Models
            foreach (DictionaryEntry entry in _configScope.CacheModelFlushOnExecuteStatements)
            {
                string cacheModelId = (string)entry.Key;
                IList statementsToRegister = (IList)entry.Value;

                if (statementsToRegister != null && statementsToRegister.Count > 0)
                {
                    foreach (string statementName in statementsToRegister)
                    {
                        IMappedStatement mappedStatement = _configScope.SqlMapper.MappedStatements[statementName] as IMappedStatement;

                        if (mappedStatement != null)
                        {
                            CacheModel cacheModel = _configScope.SqlMapper.GetCache(cacheModelId);

                            if (_logger.IsDebugEnabled)
                            {
                                _logger.Debug("Registering trigger statement [" + mappedStatement.Id + "] to cache model [" + cacheModel.Id + "]");
                            }

                            cacheModel.RegisterTriggerStatement(mappedStatement);
                        }
                        else
                        {
                            if (_logger.IsWarnEnabled)
                            {
                                _logger.Warn("Unable to register trigger statement [" + statementName + "] to cache model [" + cacheModelId + "]. Statement does not exist.");
                            }
                        }
                    }
                }
            }
            #endregion

            #region Resolve resultMap / Discriminator / PropertyStategy attributes on Result/Argument Property

            foreach(DictionaryEntry entry in _configScope.SqlMapper.ResultMaps)
            {
                _configScope.ErrorContext.Activity = "Resolve 'resultMap' attribute on Result Property";

                ResultMap resultMap = (ResultMap)entry.Value;
                for(int index=0; index< resultMap.Properties.Count; index++)
                {
                    ResultProperty result = resultMap.Properties[index];
                    if(result.NestedResultMapName.Length >0)
                    {
                        result.NestedResultMap = _configScope.SqlMapper.GetResultMap(result.NestedResultMapName);
                    }
                    result.PropertyStrategy = PropertyStrategyFactory.Get(result);
                }
                for(int index=0; index< resultMap.Parameters.Count; index++)
                {
                    ResultProperty result = resultMap.Parameters[index];
                    if(result.NestedResultMapName.Length >0)
                    {
                        result.NestedResultMap = _configScope.SqlMapper.GetResultMap(result.NestedResultMapName);
                    }
                    result.ArgumentStrategy = ArgumentStrategyFactory.Get( (ArgumentProperty)result );
                }
                if (resultMap.Discriminator != null)
                {
                    resultMap.Discriminator.Initialize(_configScope);
                }
            }

            _configScope.ErrorContext.Reset();

            #endregion
        }