void WriteValue(BinaryWriter writer, MemberInfo itemMemInfo, object value)
        {
            if (!itemMemInfo.IsSupportedPrimitive && !itemMemInfo.IsContainerObject)
            {
                if (value == null)
                {
                    WriteNullableType(writer, true);
                    return;
                }
                else if (itemMemInfo.IsNullable)
                {
                    WriteNullableType(writer, false);
                }
            }

            switch (itemMemInfo.KnownType)
            {
            case EnKnownType.Unknown:

                if (itemMemInfo.IsContainerObject)
                {
                    WriteObject(writer, itemMemInfo, value);
                }
                else if (itemMemInfo.IsStringDictionary)
                {
                    WriteStringDictionary(writer, value as IDictionary);
                }
                else if (itemMemInfo.IsDictionary)
                {
                    WriteDictionary(writer, value as IDictionary);
                }
                else if (itemMemInfo.IsCollection || itemMemInfo.IsArray)
                {
                    if (itemMemInfo.IsGeneric)
                    {
                        WriteGenericList(writer, value as IEnumerable);
                    }
                    else
                    {
                        WriteArray(writer, value);
                    }
                }
                break;

            case EnKnownType.Int16:
                if (value == null || itemMemInfo.IsNullable)
                {
                    PrimitivesConvertion.WriteVarInt(writer, (short?)value);
                }
                else
                {
                    PrimitivesConvertion.WriteVarInt(writer, (short)value);
                }
                break;

            case EnKnownType.UInt16:
                if (value == null || itemMemInfo.IsNullable)
                {
                    PrimitivesConvertion.WriteVarInt(writer, (ushort?)value);
                }
                else
                {
                    PrimitivesConvertion.WriteVarInt(writer, (ushort)value);
                }
                break;

            case EnKnownType.Int32:
                if (value == null || itemMemInfo.IsNullable)
                {
                    PrimitivesConvertion.WriteVarInt(writer, (int?)value);
                }
                else
                {
                    PrimitivesConvertion.WriteVarInt(writer, (int)value);
                }

                break;

            case EnKnownType.Int64:
                if (value == null || itemMemInfo.IsNullable)
                {
                    PrimitivesConvertion.WriteVarInt(writer, (long?)value);
                }
                else
                {
                    PrimitivesConvertion.WriteVarInt(writer, (long)value);
                }
                break;

            case EnKnownType.UInt64:
                if (value == null || itemMemInfo.IsNullable)
                {
                    PrimitivesConvertion.WriteVarInt(writer, (ulong?)value);
                }
                else
                {
                    PrimitivesConvertion.WriteVarInt(writer, (ulong)value);
                }
                break;

            case EnKnownType.UInt32:
                if (value == null || itemMemInfo.IsNullable)
                {
                    PrimitivesConvertion.WriteVarInt(writer, (uint?)value);
                }
                else
                {
                    PrimitivesConvertion.WriteVarInt(writer, (uint)value);
                }
                break;

            case EnKnownType.Double:
                if (value == null || itemMemInfo.IsNullable)
                {
                    PrimitivesConvertion.WriteVarDecimal(writer, (double?)value);
                }
                else
                {
                    PrimitivesConvertion.WriteVarDecimal(writer, (double)value);
                }
                break;

            case EnKnownType.Decimal:
                if (value == null || itemMemInfo.IsNullable)
                {
                    PrimitivesConvertion.WriteVarDecimal(writer, (decimal?)value);
                }
                else
                {
                    PrimitivesConvertion.WriteVarDecimal(writer, (decimal)value);
                }
                break;

            case EnKnownType.Single:
                if (value == null || itemMemInfo.IsNullable)
                {
                    PrimitivesConvertion.WriteVarDecimal(writer, (float?)value);
                }
                else
                {
                    PrimitivesConvertion.WriteVarDecimal(writer, (float)value);
                }
                break;

            case EnKnownType.Byte:
                writer.Write((byte)value);
                break;

            case EnKnownType.SByte:
                writer.Write((sbyte)value);
                break;

            case EnKnownType.ByteArray:
                WriteBytes(writer, (byte[])value);
                break;

            case EnKnownType.String:
                WriteString(writer, value as string);
                break;

            case EnKnownType.Char:
                writer.Write((ushort)((char)value));
                break;

            case EnKnownType.Bool:
                writer.Write((byte)(((bool)value) ? 1 : 0));
                break;

            case EnKnownType.Enum:
                WriteEnum(writer, (Enum)value);
                break;

            case EnKnownType.DateTime:
                WriteDateTime(writer, (DateTime)value);
                break;

            case EnKnownType.DateTimeOffset:
                WriteDateTimeOffset(writer, (DateTimeOffset)value);
                break;

            case EnKnownType.TimeSpan:
                WriteTimeSpan(writer, (TimeSpan)value);
                break;

            case EnKnownType.DataSet:
                WriteDataset(writer, value as DataSet);
                break;

            case EnKnownType.DataTable:
                WriteDataTable(writer, value as DataTable);
                break;

            case EnKnownType.NameValueColl:
                WriteCollectionNameValue(writer, value as NameValueCollection);
                break;

            case EnKnownType.Color:
                WriteColor(writer, (Color)value);
                break;

            case EnKnownType.Version:
                WriteVersion(writer, value as Version);
                break;

            case EnKnownType.DbNull:
                // Do not write anything, it is already written as Nullable object. //WriteNullableType(true);
                break;

            case EnKnownType.Guid:
                WriteGuid(writer, (Guid)value);
                break;

            case EnKnownType.Uri:
                WriteUri(writer, value as Uri);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }