diff Source/Mapping/MemberMapper.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/Mapping/MemberMapper.cs	Thu Mar 27 21:46:09 2014 +0400
@@ -0,0 +1,902 @@
+using System;
+using System.Data;
+using System.Data.SqlTypes;
+using System.Diagnostics;
+using System.IO;
+using System.Xml;
+
+using BLToolkit.Data.Sql;
+using BLToolkit.Reflection;
+using BLToolkit.TypeBuilder;
+
+using Convert = BLToolkit.Common.Convert;
+#if !SILVERLIGHT
+using System.Xml.Linq;
+#endif
+
+namespace BLToolkit.Mapping
+{
+	public partial class MemberMapper
+	{
+		#region Init
+
+		public virtual void Init(MapMemberInfo mapMemberInfo)
+		{
+			if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo");
+
+			MapMemberInfo          = mapMemberInfo;
+			Name                   = mapMemberInfo.Name;
+			MemberName             = mapMemberInfo.MemberName;
+			Storage                = mapMemberInfo.Storage;
+			DbType                 = mapMemberInfo.DbType;
+			_type                  = mapMemberInfo.Type;
+			MemberAccessor         = mapMemberInfo.MemberAccessor;
+			_complexMemberAccessor = mapMemberInfo.ComplexMemberAccessor;
+			MappingSchema          = mapMemberInfo.MappingSchema;
+
+			if (Storage != null)
+				MemberAccessor = ExprMemberAccessor.GetMemberAccessor(MemberAccessor.TypeAccessor, Storage);
+		}
+
+		internal static MemberMapper CreateMemberMapper(MapMemberInfo mi)
+		{
+			var type = mi.Type;
+			var mm   = null as MemberMapper;
+
+			if (type.IsPrimitive || type.IsEnum)
+				mm = GetPrimitiveMemberMapper(mi);
+
+			if (mm == null)
+			{
+				mm = GetNullableMemberMapper(mi);
+
+				//if (mm != null)
+				//    mi.IsNullable = true;
+			}
+
+			if (mm == null) mm = GetSimpleMemberMapper(mi);
+#if !SILVERLIGHT
+			if (mm == null) mm = GetSqlTypeMemberMapper(mi);
+#endif
+			return mm ?? new DefaultMemberMapper();
+		}
+
+		#endregion
+
+		#region Public Properties
+
+		public MappingSchema  MappingSchema  { get; private set; }
+		public string         Name           { get; private set; }
+		public string         MemberName     { get; private set; }
+		public string         Storage        { get; private set; }
+		public DbType         DbType         { get; private set; }
+		public MapMemberInfo  MapMemberInfo  { get; private set; }
+		public int            Ordinal        { get; private set; }
+		public MemberAccessor MemberAccessor { get; private set; }
+		public bool           IsExplicit     { get; set;         }
+
+		internal void SetOrdinal(int ordinal)
+		{
+			Ordinal = ordinal;
+		}
+
+		private MemberAccessor _complexMemberAccessor;
+		public  MemberAccessor  ComplexMemberAccessor
+		{
+			[DebuggerStepThrough]
+			get { return _complexMemberAccessor ?? MemberAccessor; }
+		}
+
+		Type _type;
+		public virtual Type Type
+		{
+			get { return _type; }
+		}
+
+		public DbType GetDbType()
+		{
+			if (MapMemberInfo.IsDbTypeSet)
+				return DbType;
+
+			if (DbType != DbType.Object)
+				return DbType;
+
+			var dataType = SqlDataType.GetDataType(_type);
+
+			switch (dataType.SqlDbType)
+			{
+				case SqlDbType.BigInt           : return DbType.Int64;
+				case SqlDbType.Binary           : return DbType.Binary;
+				case SqlDbType.Bit              : return DbType.Boolean;
+				case SqlDbType.Char             : return DbType.AnsiStringFixedLength;
+				case SqlDbType.DateTime         : return DbType.DateTime;
+				case SqlDbType.Decimal          : return DbType.Decimal;
+				case SqlDbType.Float            : return DbType.Double;
+				case SqlDbType.Image            : return DbType.Binary;
+				case SqlDbType.Int              : return DbType.Int32;
+				case SqlDbType.Money            : return DbType.Currency;
+				case SqlDbType.NChar            : return DbType.StringFixedLength;
+				case SqlDbType.NText            : return DbType.String;
+				case SqlDbType.NVarChar         : return DbType.String;
+				case SqlDbType.Real             : return DbType.Single;
+				case SqlDbType.UniqueIdentifier : return DbType.Guid;
+				case SqlDbType.SmallDateTime    : return DbType.DateTime;
+				case SqlDbType.SmallInt         : return DbType.Int16;
+				case SqlDbType.SmallMoney       : return DbType.Currency;
+				case SqlDbType.Text             : return DbType.AnsiString;
+				case SqlDbType.Timestamp        : return DbType.Binary;
+				case SqlDbType.TinyInt          : return DbType.Byte;
+				case SqlDbType.VarBinary        : return DbType.Binary;
+				case SqlDbType.VarChar          : return DbType.AnsiString;
+				case SqlDbType.Variant          : return DbType.Object;
+				case SqlDbType.Xml              : return DbType.Xml;
+				case SqlDbType.Udt              : return DbType.Binary;
+				case SqlDbType.Date             : return DbType.Date;
+				case SqlDbType.Time             : return DbType.Time;
+#if !MONO
+				case SqlDbType.Structured       : return DbType.Binary;
+				case SqlDbType.DateTime2        : return DbType.DateTime2;
+				case SqlDbType.DateTimeOffset   : return DbType.DateTimeOffset;
+#endif
+			}
+
+			return DbType.Object;
+		}
+
+		public int GetDbSize(object value)
+		{
+			if (MapMemberInfo.IsDbSizeSet)
+				return MapMemberInfo.DbSize;
+
+			if (value == null)
+				return 0;
+
+			if (value is string)
+				return ((string)value).Length;
+
+			if (value is byte[])
+				return ((byte[])value).Length;
+
+
+			var dataType = SqlDataType.GetDataType(_type);
+
+			switch (dataType.SqlDbType)
+			{
+				case SqlDbType.BigInt           : return 0;
+				case SqlDbType.Binary           : return 0;
+				case SqlDbType.Bit              : return 0;
+				case SqlDbType.Char             : return 0;
+				case SqlDbType.DateTime         : return 0;
+				case SqlDbType.Decimal          : return 0;
+				case SqlDbType.Float            : return 0;
+				case SqlDbType.Image            : return 0;
+				case SqlDbType.Int              : return 0;
+				case SqlDbType.Money            : return 0;
+				case SqlDbType.NChar            : return 0;
+				case SqlDbType.NText            : return 0;
+				case SqlDbType.NVarChar         : return 0;
+				case SqlDbType.Real             : return 0;
+				case SqlDbType.UniqueIdentifier : return 0;
+				case SqlDbType.SmallDateTime    : return 0;
+				case SqlDbType.SmallInt         : return 0;
+				case SqlDbType.SmallMoney       : return 0;
+				case SqlDbType.Text             : return 0;
+				case SqlDbType.Timestamp        : return 0;
+				case SqlDbType.TinyInt          : return 0;
+				case SqlDbType.VarBinary        : return 0;
+				case SqlDbType.VarChar          : return 0;
+				case SqlDbType.Variant          : return 0;
+				case SqlDbType.Xml              : return 0;
+				case SqlDbType.Udt              : return 0;
+				case SqlDbType.Date             : return 0;
+				case SqlDbType.Time             : return 0;
+#if !MONO
+				case SqlDbType.Structured       : return 0;
+				case SqlDbType.DateTime2        : return 0;
+				case SqlDbType.DateTimeOffset   : return 0;
+#endif
+			}
+
+			return 0;
+		}
+
+		#endregion
+
+		#region Default Members (GetValue, SetValue)
+
+		public virtual bool SupportsValue { get { return !IsExplicit; } }
+
+		public virtual object GetValue(object o)
+		{
+			return MemberAccessor.GetValue(o);
+		}
+
+		public virtual bool     IsNull     (object o) { return GetValue(o) == null; }
+
+		// Simple type getters.
+		//
+		[CLSCompliant(false)]
+		public virtual SByte    GetSByte   (object o) { return MemberAccessor.GetSByte   (o); }
+		public virtual Int16    GetInt16   (object o) { return MemberAccessor.GetInt16   (o); }
+		public virtual Int32    GetInt32   (object o) { return MemberAccessor.GetInt32   (o); }
+		public virtual Int64    GetInt64   (object o) { return MemberAccessor.GetInt64   (o); }
+
+		public virtual Byte     GetByte    (object o) { return MemberAccessor.GetByte    (o); }
+		[CLSCompliant(false)]
+		public virtual UInt16   GetUInt16  (object o) { return MemberAccessor.GetUInt16  (o); }
+		[CLSCompliant(false)]
+		public virtual UInt32   GetUInt32  (object o) { return MemberAccessor.GetUInt32  (o); }
+		[CLSCompliant(false)]
+		public virtual UInt64   GetUInt64  (object o) { return MemberAccessor.GetUInt64  (o); }
+
+		public virtual Boolean  GetBoolean (object o) { return MemberAccessor.GetBoolean (o); }
+		public virtual Char     GetChar    (object o) { return MemberAccessor.GetChar    (o); }
+		public virtual Single   GetSingle  (object o) { return MemberAccessor.GetSingle  (o); }
+		public virtual Double   GetDouble  (object o) { return MemberAccessor.GetDouble  (o); }
+		public virtual Decimal  GetDecimal (object o) { return MemberAccessor.GetDecimal (o); }
+		public virtual Guid     GetGuid    (object o) { return MemberAccessor.GetGuid    (o); }
+		public virtual DateTime GetDateTime(object o) { return MemberAccessor.GetDateTime(o); }
+		public virtual DateTimeOffset GetDateTimeOffset(object o) { return MemberAccessor.GetDateTimeOffset(o); }
+
+		// Nullable type getters.
+		//
+		[CLSCompliant(false)]
+		public virtual SByte?    GetNullableSByte   (object o) { return MemberAccessor.GetNullableSByte   (o); }
+		public virtual Int16?    GetNullableInt16   (object o) { return MemberAccessor.GetNullableInt16   (o); }
+		public virtual Int32?    GetNullableInt32   (object o) { return MemberAccessor.GetNullableInt32   (o); }
+		public virtual Int64?    GetNullableInt64   (object o) { return MemberAccessor.GetNullableInt64   (o); }
+
+		public virtual Byte?     GetNullableByte    (object o) { return MemberAccessor.GetNullableByte    (o); }
+		[CLSCompliant(false)]
+		public virtual UInt16?   GetNullableUInt16  (object o) { return MemberAccessor.GetNullableUInt16  (o); }
+		[CLSCompliant(false)]
+		public virtual UInt32?   GetNullableUInt32  (object o) { return MemberAccessor.GetNullableUInt32  (o); }
+		[CLSCompliant(false)]
+		public virtual UInt64?   GetNullableUInt64  (object o) { return MemberAccessor.GetNullableUInt64  (o); }
+
+		public virtual Boolean?  GetNullableBoolean (object o) { return MemberAccessor.GetNullableBoolean (o); }
+		public virtual Char?     GetNullableChar    (object o) { return MemberAccessor.GetNullableChar    (o); }
+		public virtual Single?   GetNullableSingle  (object o) { return MemberAccessor.GetNullableSingle  (o); }
+		public virtual Double?   GetNullableDouble  (object o) { return MemberAccessor.GetNullableDouble  (o); }
+		public virtual Decimal?  GetNullableDecimal (object o) { return MemberAccessor.GetNullableDecimal (o); }
+		public virtual Guid?     GetNullableGuid    (object o) { return MemberAccessor.GetNullableGuid    (o); }
+		public virtual DateTime? GetNullableDateTime(object o) { return MemberAccessor.GetNullableDateTime(o); }
+		public virtual DateTimeOffset? GetNullableDateTimeOffset(object o) { return MemberAccessor.GetNullableDateTimeOffset(o); }
+
+#if !SILVERLIGHT
+
+		// SQL type getters.
+		//
+		public virtual SqlByte     GetSqlByte    (object o) { return MemberAccessor.GetSqlByte    (o); }
+		public virtual SqlInt16    GetSqlInt16   (object o) { return MemberAccessor.GetSqlInt16   (o); }
+		public virtual SqlInt32    GetSqlInt32   (object o) { return MemberAccessor.GetSqlInt32   (o); }
+		public virtual SqlInt64    GetSqlInt64   (object o) { return MemberAccessor.GetSqlInt64   (o); }
+		public virtual SqlSingle   GetSqlSingle  (object o) { return MemberAccessor.GetSqlSingle  (o); }
+		public virtual SqlBoolean  GetSqlBoolean (object o) { return MemberAccessor.GetSqlBoolean (o); }
+		public virtual SqlDouble   GetSqlDouble  (object o) { return MemberAccessor.GetSqlDouble  (o); }
+		public virtual SqlDateTime GetSqlDateTime(object o) { return MemberAccessor.GetSqlDateTime(o); }
+		public virtual SqlDecimal  GetSqlDecimal (object o) { return MemberAccessor.GetSqlDecimal (o); }
+		public virtual SqlMoney    GetSqlMoney   (object o) { return MemberAccessor.GetSqlMoney   (o); }
+		public virtual SqlGuid     GetSqlGuid    (object o) { return MemberAccessor.GetSqlGuid    (o); }
+		public virtual SqlString   GetSqlString  (object o) { return MemberAccessor.GetSqlString  (o); }
+
+#endif
+
+		public virtual void SetValue(object o, object value)
+		{
+			MemberAccessor.SetValue(o, value);
+		}
+
+		public virtual void SetNull   (object o)                { SetValue(o, null); }
+
+		// Simple type setters.
+		//
+		[CLSCompliant(false)]
+		public virtual void SetSByte   (object o, SByte    value) { MemberAccessor.SetSByte   (o, value); }
+		public virtual void SetInt16   (object o, Int16    value) { MemberAccessor.SetInt16   (o, value); }
+		public virtual void SetInt32   (object o, Int32    value) { MemberAccessor.SetInt32   (o, value); }
+		public virtual void SetInt64   (object o, Int64    value) { MemberAccessor.SetInt64   (o, value); }
+
+		public virtual void SetByte    (object o, Byte     value) { MemberAccessor.SetByte    (o, value); }
+		[CLSCompliant(false)]
+		public virtual void SetUInt16  (object o, UInt16   value) { MemberAccessor.SetUInt16  (o, value); }
+		[CLSCompliant(false)]
+		public virtual void SetUInt32  (object o, UInt32   value) { MemberAccessor.SetUInt32  (o, value); }
+		[CLSCompliant(false)]
+		public virtual void SetUInt64  (object o, UInt64   value) { MemberAccessor.SetUInt64  (o, value); }
+
+		public virtual void SetBoolean (object o, Boolean  value) { MemberAccessor.SetBoolean (o, value); }
+		public virtual void SetChar    (object o, Char     value) { MemberAccessor.SetChar    (o, value); }
+		public virtual void SetSingle  (object o, Single   value) { MemberAccessor.SetSingle  (o, value); }
+		public virtual void SetDouble  (object o, Double   value) { MemberAccessor.SetDouble  (o, value); }
+		public virtual void SetDecimal (object o, Decimal  value) { MemberAccessor.SetDecimal (o, value); }
+		public virtual void SetGuid    (object o, Guid     value) { MemberAccessor.SetGuid    (o, value); }
+		public virtual void SetDateTime(object o, DateTime value) { MemberAccessor.SetDateTime(o, value); }
+		public virtual void SetDateTimeOffset(object o, DateTimeOffset value) { MemberAccessor.SetDateTimeOffset(o, value); }
+
+		// Nullable type setters.
+		//
+		[CLSCompliant(false)]
+		public virtual void SetNullableSByte   (object o, SByte?    value) { MemberAccessor.SetNullableSByte   (o, value); }
+		public virtual void SetNullableInt16   (object o, Int16?    value) { MemberAccessor.SetNullableInt16   (o, value); }
+		public virtual void SetNullableInt32   (object o, Int32?    value) { MemberAccessor.SetNullableInt32   (o, value); }
+		public virtual void SetNullableInt64   (object o, Int64?    value) { MemberAccessor.SetNullableInt64   (o, value); }
+
+		public virtual void SetNullableByte    (object o, Byte?     value) { MemberAccessor.SetNullableByte    (o, value); }
+		[CLSCompliant(false)]
+		public virtual void SetNullableUInt16  (object o, UInt16?   value) { MemberAccessor.SetNullableUInt16  (o, value); }
+		[CLSCompliant(false)]
+		public virtual void SetNullableUInt32  (object o, UInt32?   value) { MemberAccessor.SetNullableUInt32  (o, value); }
+		[CLSCompliant(false)]
+		public virtual void SetNullableUInt64  (object o, UInt64?   value) { MemberAccessor.SetNullableUInt64  (o, value); }
+
+		public virtual void SetNullableBoolean (object o, Boolean?  value) { MemberAccessor.SetNullableBoolean (o, value); }
+		public virtual void SetNullableChar    (object o, Char?     value) { MemberAccessor.SetNullableChar    (o, value); }
+		public virtual void SetNullableSingle  (object o, Single?   value) { MemberAccessor.SetNullableSingle  (o, value); }
+		public virtual void SetNullableDouble  (object o, Double?   value) { MemberAccessor.SetNullableDouble  (o, value); }
+		public virtual void SetNullableDecimal (object o, Decimal?  value) { MemberAccessor.SetNullableDecimal (o, value); }
+		public virtual void SetNullableGuid    (object o, Guid?     value) { MemberAccessor.SetNullableGuid    (o, value); }
+		public virtual void SetNullableDateTime(object o, DateTime? value) { MemberAccessor.SetNullableDateTime(o, value); }
+		public virtual void SetNullableDateTimeOffset(object o, DateTimeOffset? value) { MemberAccessor.SetNullableDateTimeOffset(o, value); }
+
+#if !SILVERLIGHT
+
+		// SQL type setters.
+		//
+		public virtual void SetSqlByte    (object o, SqlByte     value) { MemberAccessor.SetSqlByte    (o, value); }
+		public virtual void SetSqlInt16   (object o, SqlInt16    value) { MemberAccessor.SetSqlInt16   (o, value); }
+		public virtual void SetSqlInt32   (object o, SqlInt32    value) { MemberAccessor.SetSqlInt32   (o, value); }
+		public virtual void SetSqlInt64   (object o, SqlInt64    value) { MemberAccessor.SetSqlInt64   (o, value); }
+		public virtual void SetSqlSingle  (object o, SqlSingle   value) { MemberAccessor.SetSqlSingle  (o, value); }
+		public virtual void SetSqlBoolean (object o, SqlBoolean  value) { MemberAccessor.SetSqlBoolean (o, value); }
+		public virtual void SetSqlDouble  (object o, SqlDouble   value) { MemberAccessor.SetSqlDouble  (o, value); }
+		public virtual void SetSqlDateTime(object o, SqlDateTime value) { MemberAccessor.SetSqlDateTime(o, value); }
+		public virtual void SetSqlDecimal (object o, SqlDecimal  value) { MemberAccessor.SetSqlDecimal (o, value); }
+		public virtual void SetSqlMoney   (object o, SqlMoney    value) { MemberAccessor.SetSqlMoney   (o, value); }
+		public virtual void SetSqlGuid    (object o, SqlGuid     value) { MemberAccessor.SetSqlGuid    (o, value); }
+		public virtual void SetSqlString  (object o, SqlString   value) { MemberAccessor.SetSqlString  (o, value); }
+
+#endif
+
+		public virtual void CloneValue    (object source, object dest)  { MemberAccessor.CloneValue(source, dest); }
+
+		#endregion
+
+		#region Intermal Mappers
+
+		#region Complex Mapper
+
+		internal sealed class ComplexMapper : MemberMapper
+		{
+			public ComplexMapper(MemberMapper memberMapper)
+			{
+				_mapper = memberMapper;
+			}
+
+			private readonly MemberMapper _mapper;
+
+			public override void Init(MapMemberInfo mapMemberInfo)
+			{
+				base.Init(mapMemberInfo);
+
+				var attr = MemberAccessor.GetAttribute<NoInstanceAttribute>();
+
+				if (attr != null)
+				{
+					_createInstance = true;
+				}
+			}
+
+			bool         _createInstance;
+			TypeAccessor _typeAccessor;
+
+			object GetObject(object o)
+			{
+				var obj = MemberAccessor.GetValue(o);
+
+				if (_createInstance && obj == null)
+				{
+					if (_typeAccessor == null)
+						_typeAccessor = TypeAccessor.GetAccessor(MemberAccessor.Type);
+
+					obj = _typeAccessor.CreateInstanceEx();
+
+					MemberAccessor.SetValue(o, obj);
+				}
+
+				return obj;
+			}
+
+			#region GetValue
+
+			public override object GetValue(object o)
+			{
+				var obj = MemberAccessor.GetValue(o);
+				return obj == null? null: _mapper.GetValue(obj);
+			}
+
+			// Simple type getters.
+			//
+			public override SByte    GetSByte   (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultSByteNullValue:    _mapper.GetSByte   (obj); }
+			public override Int16    GetInt16   (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultInt16NullValue:    _mapper.GetInt16   (obj); }
+			public override Int32    GetInt32   (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultInt32NullValue:    _mapper.GetInt32   (obj); }
+			public override Int64    GetInt64   (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultInt64NullValue:    _mapper.GetInt64   (obj); }
+
+			public override Byte     GetByte    (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultByteNullValue:     _mapper.GetByte    (obj); }
+			public override UInt16   GetUInt16  (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultUInt16NullValue:   _mapper.GetUInt16  (obj); }
+			public override UInt32   GetUInt32  (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultUInt32NullValue:   _mapper.GetUInt32  (obj); }
+			public override UInt64   GetUInt64  (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultUInt64NullValue:   _mapper.GetUInt64  (obj); }
+
+			public override Boolean  GetBoolean (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultBooleanNullValue:  _mapper.GetBoolean (obj); }
+			public override Char     GetChar    (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultCharNullValue:     _mapper.GetChar    (obj); }
+			public override Single   GetSingle  (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultSingleNullValue:   _mapper.GetSingle  (obj); }
+			public override Double   GetDouble  (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultDoubleNullValue:   _mapper.GetDouble  (obj); }
+			public override Decimal  GetDecimal (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultDecimalNullValue:  _mapper.GetDecimal (obj); }
+			public override Guid     GetGuid    (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultGuidNullValue:     _mapper.GetGuid    (obj); }
+			public override DateTime GetDateTime(object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultDateTimeNullValue: _mapper.GetDateTime(obj); }
+			public override DateTimeOffset GetDateTimeOffset(object o) { var obj = MemberAccessor.GetValue(o); return obj == null? MappingSchema.DefaultDateTimeOffsetNullValue: _mapper.GetDateTimeOffset(obj); }
+
+			// Nullable type getters.
+			//
+			public override SByte?    GetNullableSByte   (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableSByte   (obj); }
+			public override Int16?    GetNullableInt16   (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableInt16   (obj); }
+			public override Int32?    GetNullableInt32   (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableInt32   (obj); }
+			public override Int64?    GetNullableInt64   (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableInt64   (obj); }
+
+			public override Byte?     GetNullableByte    (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableByte    (obj); }
+			public override UInt16?   GetNullableUInt16  (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableUInt16  (obj); }
+			public override UInt32?   GetNullableUInt32  (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableUInt32  (obj); }
+			public override UInt64?   GetNullableUInt64  (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableUInt64  (obj); }
+
+			public override Boolean?  GetNullableBoolean (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableBoolean (obj); }
+			public override Char?     GetNullableChar    (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableChar    (obj); }
+			public override Single?   GetNullableSingle  (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableSingle  (obj); }
+			public override Double?   GetNullableDouble  (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableDouble  (obj); }
+			public override Decimal?  GetNullableDecimal (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableDecimal (obj); }
+			public override Guid?     GetNullableGuid    (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableGuid    (obj); }
+			public override DateTime? GetNullableDateTime(object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableDateTime(obj); }
+			public override DateTimeOffset? GetNullableDateTimeOffset(object o) { var obj = MemberAccessor.GetValue(o); return obj == null? null: _mapper.GetNullableDateTimeOffset(obj); }
+
+#if !SILVERLIGHT
+
+			// SQL type getters.
+			//
+			public override SqlByte     GetSqlByte    (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlByte.    Null: _mapper.GetSqlByte    (obj); }
+			public override SqlInt16    GetSqlInt16   (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlInt16.   Null: _mapper.GetSqlInt16   (obj); }
+			public override SqlInt32    GetSqlInt32   (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlInt32.   Null: _mapper.GetSqlInt32   (obj); }
+			public override SqlInt64    GetSqlInt64   (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlInt64.   Null: _mapper.GetSqlInt64   (obj); }
+			public override SqlSingle   GetSqlSingle  (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlSingle.  Null: _mapper.GetSqlSingle  (obj); }
+			public override SqlBoolean  GetSqlBoolean (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlBoolean. Null: _mapper.GetSqlBoolean (obj); }
+			public override SqlDouble   GetSqlDouble  (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlDouble.  Null: _mapper.GetSqlDouble  (obj); }
+			public override SqlDateTime GetSqlDateTime(object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlDateTime.Null: _mapper.GetSqlDateTime(obj); }
+			public override SqlDecimal  GetSqlDecimal (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlDecimal. Null: _mapper.GetSqlDecimal (obj); }
+			public override SqlMoney    GetSqlMoney   (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlMoney.   Null: _mapper.GetSqlMoney   (obj); }
+			public override SqlGuid     GetSqlGuid    (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlGuid.    Null: _mapper.GetSqlGuid    (obj); }
+			public override SqlString   GetSqlString  (object o) { var obj = MemberAccessor.GetValue(o); return obj == null? SqlString.  Null: _mapper.GetSqlString  (obj); }
+
+#endif
+
+			#endregion
+
+			#region SetValue
+
+			public override void SetValue(object o, object value)
+			{
+				var obj = MemberAccessor.GetValue(o);
+
+				if (obj != null)
+					_mapper.SetValue(obj, value);
+			}
+
+			public override void SetSByte   (object o, SByte    value) { var obj = GetObject(o); if (obj != null) _mapper.SetSByte   (obj, value); }
+			public override void SetInt16   (object o, Int16    value) { var obj = GetObject(o); if (obj != null) _mapper.SetInt16   (obj, value); }
+			public override void SetInt32   (object o, Int32    value) { var obj = GetObject(o); if (obj != null) _mapper.SetInt32   (obj, value); }
+			public override void SetInt64   (object o, Int64    value) { var obj = GetObject(o); if (obj != null) _mapper.SetInt64   (obj, value); }
+
+			public override void SetByte    (object o, Byte     value) { var obj = GetObject(o); if (obj != null) _mapper.SetByte    (obj, value); }
+			public override void SetUInt16  (object o, UInt16   value) { var obj = GetObject(o); if (obj != null) _mapper.SetUInt16  (obj, value); }
+			public override void SetUInt32  (object o, UInt32   value) { var obj = GetObject(o); if (obj != null) _mapper.SetUInt32  (obj, value); }
+			public override void SetUInt64  (object o, UInt64   value) { var obj = GetObject(o); if (obj != null) _mapper.SetUInt64  (obj, value); }
+
+			public override void SetBoolean (object o, Boolean  value) { var obj = GetObject(o); if (obj != null) _mapper.SetBoolean (obj, value); }
+			public override void SetChar    (object o, Char     value) { var obj = GetObject(o); if (obj != null) _mapper.SetChar    (obj, value); }
+			public override void SetSingle  (object o, Single   value) { var obj = GetObject(o); if (obj != null) _mapper.SetSingle  (obj, value); }
+			public override void SetDouble  (object o, Double   value) { var obj = GetObject(o); if (obj != null) _mapper.SetDouble  (obj, value); }
+			public override void SetDecimal (object o, Decimal  value) { var obj = GetObject(o); if (obj != null) _mapper.SetDecimal (obj, value); }
+			public override void SetGuid    (object o, Guid     value) { var obj = GetObject(o); if (obj != null) _mapper.SetGuid    (obj, value); }
+			public override void SetDateTime(object o, DateTime value) { var obj = GetObject(o); if (obj != null) _mapper.SetDateTime(obj, value); }
+			public override void SetDateTimeOffset(object o, DateTimeOffset value) { var obj = GetObject(o); if (obj != null) _mapper.SetDateTimeOffset(obj, value); }
+
+			// Nullable type setters.
+			//
+			public override void SetNullableSByte   (object o, SByte?    value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableSByte   (obj, value); }
+			public override void SetNullableInt16   (object o, Int16?    value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableInt16   (obj, value); }
+			public override void SetNullableInt32   (object o, Int32?    value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableInt32   (obj, value); }
+			public override void SetNullableInt64   (object o, Int64?    value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableInt64   (obj, value); }
+
+			public override void SetNullableByte    (object o, Byte?     value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableByte    (obj, value); }
+			public override void SetNullableUInt16  (object o, UInt16?   value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableUInt16  (obj, value); }
+			public override void SetNullableUInt32  (object o, UInt32?   value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableUInt32  (obj, value); }
+			public override void SetNullableUInt64  (object o, UInt64?   value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableUInt64  (obj, value); }
+
+			public override void SetNullableBoolean (object o, Boolean?  value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableBoolean (obj, value); }
+			public override void SetNullableChar    (object o, Char?     value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableChar    (obj, value); }
+			public override void SetNullableSingle  (object o, Single?   value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableSingle  (obj, value); }
+			public override void SetNullableDouble  (object o, Double?   value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableDouble  (obj, value); }
+			public override void SetNullableDecimal (object o, Decimal?  value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableDecimal (obj, value); }
+			public override void SetNullableGuid    (object o, Guid?     value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableGuid    (obj, value); }
+			public override void SetNullableDateTime(object o, DateTime? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableDateTime(obj, value); }
+			public override void SetNullableDateTimeOffset(object o, DateTimeOffset? value) { var obj = GetObject(o); if (obj != null) _mapper.SetNullableDateTimeOffset(obj, value); }
+
+#if !SILVERLIGHT
+
+			// SQL type setters.
+			//
+			public override void SetSqlByte    (object o, SqlByte     value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlByte    (obj, value); }
+			public override void SetSqlInt16   (object o, SqlInt16    value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlInt16   (obj, value); }
+			public override void SetSqlInt32   (object o, SqlInt32    value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlInt32   (obj, value); }
+			public override void SetSqlInt64   (object o, SqlInt64    value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlInt64   (obj, value); }
+			public override void SetSqlSingle  (object o, SqlSingle   value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlSingle  (obj, value); }
+			public override void SetSqlBoolean (object o, SqlBoolean  value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlBoolean (obj, value); }
+			public override void SetSqlDouble  (object o, SqlDouble   value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlDouble  (obj, value); }
+			public override void SetSqlDateTime(object o, SqlDateTime value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlDateTime(obj, value); }
+			public override void SetSqlDecimal (object o, SqlDecimal  value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlDecimal (obj, value); }
+			public override void SetSqlMoney   (object o, SqlMoney    value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlMoney   (obj, value); }
+			public override void SetSqlGuid    (object o, SqlGuid     value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlGuid    (obj, value); }
+			public override void SetSqlString  (object o, SqlString   value) { var obj = GetObject(o); if (obj != null) _mapper.SetSqlString  (obj, value); }
+
+#endif
+
+			#endregion
+		}
+
+		#endregion
+
+		#region Primitive Mappers
+
+		private static MemberMapper GetPrimitiveMemberMapper(MapMemberInfo mi)
+		{
+			if (mi.MapValues != null)
+				return null;
+
+			var n    = mi.Nullable;
+			var type = mi.MemberAccessor.UnderlyingType;
+ 
+			if (type == typeof(SByte))   return n? new SByteMapper.  Nullable(): new SByteMapper();
+			if (type == typeof(Int16))   return n? new Int16Mapper.  Nullable(): new Int16Mapper();
+			if (type == typeof(Int32))   return n? new Int32Mapper.  Nullable(): new Int32Mapper();
+			if (type == typeof(Int64))   return n? new Int64Mapper.  Nullable(): new Int64Mapper();
+			if (type == typeof(Byte))    return n? new ByteMapper.   Nullable(): new ByteMapper();
+			if (type == typeof(UInt16))  return n? new UInt16Mapper. Nullable(): new UInt16Mapper();
+			if (type == typeof(UInt32))  return n? new UInt32Mapper. Nullable(): new UInt32Mapper();
+			if (type == typeof(UInt64))  return n? new UInt64Mapper. Nullable(): new UInt64Mapper();
+			if (type == typeof(Single))  return n? new SingleMapper. Nullable(): new SingleMapper();
+			if (type == typeof(Double))  return n? new DoubleMapper. Nullable(): new DoubleMapper();
+			if (type == typeof(Char))    return n? new CharMapper.   Nullable(): new CharMapper();
+			if (type == typeof(Boolean)) return n? new BooleanMapper.Nullable(): new BooleanMapper();
+
+			throw new InvalidOperationException();
+		}
+
+		#endregion
+
+		#region Simple Mappers
+
+		private static MemberMapper GetSimpleMemberMapper(MapMemberInfo mi)
+		{
+			if (mi.MapValues != null)
+				return null;
+
+			var n    = mi.Nullable;
+			var type = mi.Type;
+
+			if (type == typeof(String))
+				if (mi.Trimmable) return n? new StringMapper.Trimmable.NullableT(): new StringMapper.Trimmable();
+				else              return n? new StringMapper.Nullable()           : new StringMapper();
+
+			if (type == typeof(DateTime))       return n? new DateTimeMapper.Nullable()       : new DateTimeMapper();
+			if (type == typeof(DateTimeOffset)) return n? new DateTimeOffsetMapper.Nullable() : new DateTimeOffsetMapper();
+			if (type == typeof(Decimal))        return n? new DecimalMapper.Nullable()        : new DecimalMapper();
+			if (type == typeof(Guid))           return n? new GuidMapper.Nullable()           : new GuidMapper();
+			if (type == typeof(Stream))         return n? new StreamMapper.Nullable()         : new StreamMapper();
+#if !SILVERLIGHT
+			if (type == typeof(XmlReader))      return n? new XmlReaderMapper.Nullable()      : new XmlReaderMapper();
+			if (type == typeof(XmlDocument))    return n? new XmlDocumentMapper.Nullable()    : new XmlDocumentMapper();
+            if (type == typeof(XElement))       return n? new XElementMapper.Nullable()       : new XElementMapper();
+#endif
+			return null;
+		}
+
+		class StringMapper : MemberMapper
+		{
+			string _nullValue;
+
+			public override void SetValue(object o, object value)
+			{
+				MemberAccessor.SetValue(
+					o,
+					value is string? value:
+					value == null?   _nullValue:
+					                 MappingSchema.ConvertToString(value));
+			}
+
+			public override void Init(MapMemberInfo mapMemberInfo)
+			{
+				if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo");
+
+				if (mapMemberInfo.NullValue != null)
+					_nullValue = Convert.ToString(mapMemberInfo.NullValue);
+
+				base.Init(mapMemberInfo);
+			}
+
+			public class Nullable : StringMapper
+			{
+				public override object GetValue(object o)
+				{
+					var value = MemberAccessor.GetValue(o);
+					return (string)value == _nullValue? null: value;
+				}
+			}
+
+			public class Trimmable : StringMapper
+			{
+				public override void SetValue(object o, object value)
+				{
+					MemberAccessor.SetValue(
+						o, value == null? _nullValue: MappingSchema.ConvertToString(value).TrimEnd(_trim));
+				}
+
+				public class NullableT : Trimmable
+				{
+					public override object GetValue(object o)
+					{
+						var value = MemberAccessor.GetValue(o);
+						return (string)value == _nullValue? null: value;
+					}
+				}
+			}
+		}
+
+		#endregion
+
+		#region Nullable Mappers
+
+		private static MemberMapper GetNullableMemberMapper(MapMemberInfo mi)
+		{
+			var type = mi.Type;
+
+			if (type.IsGenericType == false || mi.MapValues != null)
+				return null;
+
+			var underlyingType = Nullable.GetUnderlyingType(type);
+
+			if (underlyingType == null)
+				return null;
+
+			if (underlyingType.IsEnum)
+			{
+				underlyingType = Enum.GetUnderlyingType(underlyingType);
+
+				if (underlyingType == typeof(SByte))    return new NullableSByteMapper. Enum();
+				if (underlyingType == typeof(Int16))    return new NullableInt16Mapper. Enum();
+				if (underlyingType == typeof(Int32))    return new NullableInt32Mapper. Enum();
+				if (underlyingType == typeof(Int64))    return new NullableInt64Mapper. Enum();
+				if (underlyingType == typeof(Byte))     return new NullableByteMapper.  Enum();
+				if (underlyingType == typeof(UInt16))   return new NullableUInt16Mapper.Enum();
+				if (underlyingType == typeof(UInt32))   return new NullableUInt32Mapper.Enum();
+				if (underlyingType == typeof(UInt64))   return new NullableUInt64Mapper.Enum();
+			}
+			else
+			{
+				if (underlyingType == typeof(SByte))    return new NullableSByteMapper();
+				if (underlyingType == typeof(Int16))    return new NullableInt16Mapper();
+				if (underlyingType == typeof(Int32))    return new NullableInt32Mapper();
+				if (underlyingType == typeof(Int64))    return new NullableInt64Mapper();
+				if (underlyingType == typeof(Byte))     return new NullableByteMapper();
+				if (underlyingType == typeof(UInt16))   return new NullableUInt16Mapper();
+				if (underlyingType == typeof(UInt32))   return new NullableUInt32Mapper();
+				if (underlyingType == typeof(UInt64))   return new NullableUInt64Mapper();
+				if (underlyingType == typeof(Char))     return new NullableCharMapper();
+				if (underlyingType == typeof(Single))   return new NullableSingleMapper();
+				if (underlyingType == typeof(Boolean))  return new NullableBooleanMapper();
+				if (underlyingType == typeof(Double))   return new NullableDoubleMapper();
+				if (underlyingType == typeof(DateTime)) return new NullableDateTimeMapper();
+				if (underlyingType == typeof(Decimal))  return new NullableDecimalMapper();
+				if (underlyingType == typeof(Guid))     return new NullableGuidMapper();
+			}
+
+			return null;
+		}
+
+		abstract class NullableEnumMapper : MemberMapper
+		{
+			protected Type MemberType;
+			protected Type UnderlyingType;
+
+			public override void Init(MapMemberInfo mapMemberInfo)
+			{
+				if (mapMemberInfo == null) throw new ArgumentNullException("mapMemberInfo");
+
+				MemberType     = Nullable.GetUnderlyingType(mapMemberInfo.Type);
+				UnderlyingType = mapMemberInfo.MemberAccessor.UnderlyingType;
+
+				base.Init(mapMemberInfo);
+			}
+		}
+
+		#endregion
+
+		#region SqlTypes
+
+#if !SILVERLIGHT
+
+		private static MemberMapper GetSqlTypeMemberMapper(MapMemberInfo mi)
+		{
+			var type = mi.Type;
+
+			if (TypeHelper.IsSameOrParent(typeof(INullable), type) == false)
+				return null;
+
+			var d = mi.MapValues != null;
+
+			if (type == typeof(SqlByte))     return d? new SqlByteMapper.    Default(): new SqlByteMapper();
+			if (type == typeof(SqlInt16))    return d? new SqlInt16Mapper.   Default(): new SqlInt16Mapper();
+			if (type == typeof(SqlInt32))    return d? new SqlInt32Mapper.   Default(): new SqlInt32Mapper();
+			if (type == typeof(SqlInt64))    return d? new SqlInt64Mapper.   Default(): new SqlInt64Mapper();
+			if (type == typeof(SqlSingle))   return d? new SqlSingleMapper.  Default(): new SqlSingleMapper();
+			if (type == typeof(SqlBoolean))  return d? new SqlBooleanMapper. Default(): new SqlBooleanMapper();
+			if (type == typeof(SqlDouble))   return d? new SqlDoubleMapper.  Default(): new SqlDoubleMapper();
+			if (type == typeof(SqlDateTime)) return d? new SqlDateTimeMapper.Default(): new SqlDateTimeMapper();
+			if (type == typeof(SqlDecimal))  return d? new SqlDecimalMapper. Default(): new SqlDecimalMapper();
+			if (type == typeof(SqlMoney))    return d? new SqlMoneyMapper.   Default(): new SqlMoneyMapper();
+			if (type == typeof(SqlGuid))     return d? new SqlGuidMapper.    Default(): new SqlGuidMapper();
+			if (type == typeof(SqlString))   return d? new SqlStringMapper.  Default(): new SqlStringMapper();
+
+			return null;
+		}
+
+#endif
+
+		#endregion
+
+		#endregion
+
+		#region MapFrom, MapTo
+
+		protected object MapFrom(object value)
+		{
+			return MapFrom(value, MapMemberInfo);
+		}
+
+		static readonly char[] _trim = { ' ' };
+
+		protected object MapFrom(object value, MapMemberInfo mapInfo)
+		{
+			if (mapInfo == null) throw new ArgumentNullException("mapInfo");
+
+			if (value == null)
+				return mapInfo.NullValue;
+
+			if (mapInfo.Trimmable && value is string)
+				value = value.ToString().TrimEnd(_trim);
+
+			if (mapInfo.MapValues != null)
+			{
+				object origValue;
+				if (mapInfo.TryGetOrigValue(value, out origValue))
+					return origValue;
+
+				// 2012-09-18 ili: this is too slow when we have for ex. enum with 50+ values
+				//
+				//var comp = (IComparable)value;
+
+				//foreach (var mv       in mapInfo.MapValues)
+				//foreach (var mapValue in mv.MapValues)
+				//{
+				//    try
+				//    {
+				//        if (comp.CompareTo(mapValue) == 0)
+				//            return mv.OrigValue;
+				//    }
+				//    catch
+				//    {
+				//    }
+				//}
+
+				// Default value.
+				//
+				if (mapInfo.DefaultValue != null)
+					return mapInfo.DefaultValue;
+			}
+
+			var valueType  = value.GetType();
+			var memberType = mapInfo.Type;
+
+			if (!TypeHelper.IsSameOrParent(memberType, valueType))
+			{
+				if (memberType.IsGenericType)
+				{
+					var underlyingType = Nullable.GetUnderlyingType(memberType);
+
+					if (valueType == underlyingType)
+						return value;
+
+					memberType = underlyingType;
+				}
+
+				if (memberType.IsEnum)
+				{
+					var underlyingType = mapInfo.MemberAccessor.UnderlyingType;
+
+					if (valueType != underlyingType)
+						//value = _mappingSchema.ConvertChangeType(value, underlyingType);
+						return MapFrom(MappingSchema.ConvertChangeType(value, underlyingType), mapInfo);
+
+					//value = Enum.Parse(type, Enum.GetName(type, value));
+					value = Enum.ToObject(memberType, value);
+				}
+				else
+				{
+					value = MappingSchema.ConvertChangeType(value, memberType);
+				}
+			}
+
+			return value;
+		}
+
+		protected object MapTo(object value)
+		{
+			return MapTo(value, MapMemberInfo);
+		}
+
+		protected static object MapTo(object value, MapMemberInfo mapInfo)
+		{
+			if (mapInfo == null) throw new ArgumentNullException("mapInfo");
+
+			if (value == null)
+				return null;
+
+			if (mapInfo.Nullable && mapInfo.NullValue != null)
+			{
+				try
+				{
+					var comp = (IComparable)value;
+
+					if (comp.CompareTo(mapInfo.NullValue) == 0)
+						return null;
+				}
+				catch
+				{
+				}
+			}
+
+			if (mapInfo.MapValues != null)
+			{
+				object mapValue;
+				if (mapInfo.TryGetMapValue(value, out mapValue))
+					return mapValue;
+
+				//2011-11-16 ili: this is too slow when we have for ex. enum with 50+ values
+				//
+				//var comp = (IComparable)value;
+
+				//foreach (var mv in mapInfo.MapValues)
+				//{
+				//    try
+				//    {
+				//        if (comp.CompareTo(mv.OrigValue) == 0)
+				//            return mv.MapValues[0];
+				//    }
+				//    catch
+				//    {
+				//    }
+				//}
+			}
+
+			return value;
+		}
+
+		#endregion
+	}
+}