private object InternalDeserializeInstance(BinaryReader reader, object o, Type t)
        {
            object ret = null;

            if (o != null)
            {
                //This allows PrepareForDeserialize to subclass the expected type if appropriate
                t = o.GetType();

                //Debug.WriteLine("Deserializing instance " + t.Name);
            }

            switch (TypeExtensions.GetTypeCode(t))
            {
            case TypeExtensions.TypeCode.Boolean: ret = reader.ReadBoolean(); break;

            case TypeExtensions.TypeCode.Char: ret = reader.ReadChar(); break;

            case TypeExtensions.TypeCode.SByte: ret = reader.ReadSByte(); break;

            case TypeExtensions.TypeCode.Byte: ret = reader.ReadByte(); break;

            case TypeExtensions.TypeCode.Int16: ret = reader.ReadInt16(); break;

            case TypeExtensions.TypeCode.UInt16: ret = reader.ReadUInt16(); break;

            case TypeExtensions.TypeCode.Int32: ret = reader.ReadInt32(); break;

            case TypeExtensions.TypeCode.UInt32: ret = reader.ReadUInt32(); break;

            case TypeExtensions.TypeCode.Int64: ret = reader.ReadInt64(); break;

            case TypeExtensions.TypeCode.UInt64: ret = reader.ReadUInt64(); break;

            case TypeExtensions.TypeCode.Single:
                if (Capabilities.FloatingPoint)
                {
                    ret = reader.ReadSingle();
                }
                else
                {
                    ret = (float)reader.ReadInt32() / 1024;
                }
                break;

            case TypeExtensions.TypeCode.Double:
                if (Capabilities.FloatingPoint)
                {
                    ret = reader.ReadDouble();
                }
                else
                {
                    ret = (double)reader.ReadInt64() / 65536;
                }
                break;

            case TypeExtensions.TypeCode.String:
                int    num = reader.ReadInt32();
                byte[] buf = reader.ReadBytes(num);

                ret = Encoding.UTF8.GetString(buf, 0, num);

                break;

            default:
                if (t.IsArray)
                {
                    Array arr = (Array)o;

                    for (int i = 0; i < arr.Length; i++)
                    {
                        object objValue = arr.GetValue(i);

                        //if(reader.BaseStream.Position >= reader.BaseStream.Length)
                        //{
                        //    Debug.WriteLine("######################################################");
                        //    Debug.WriteLine("################ trying to read after end of stream ");
                        //}

                        objValue = InternalDeserializeInstance(reader, objValue, t.GetElementType());
                        arr.SetValue(objValue, i);
                    }

                    ret = o;
                }
                else if (t.GetRuntimeProperties().FirstOrDefault(n => n.Name == "Count") != null)
                {
                    // type implements Count property so it's a list

                    // cast to IList
                    IList list = (IList)o;

                    // go through each list item and deserialize it
                    for (int i = 0; i < list.Count; i++)
                    {
                        list[i] = InternalDeserializeInstance(reader, list[i], list[i].GetType());
                    }

                    // done here, return the de-serialized list
                    ret = list;
                }
                else if (t.GetTypeInfo().IsValueType || t.GetTypeInfo().IsClass)
                {
                    if (o != null)
                    {
                        if (o.GetType() != t)
                        {
                            throw new SerializationException();
                        }
                    }
                    else
                    {
                        o = Activator.CreateInstance(t);
                    }

                    InternalDeserializeFields(reader, o);

                    ret = o;
                }
                else
                {
                    throw new SerializationException();
                }

                break;
            }

            return(ret);
        }
        private void InternalSerializeInstance(BinaryWriter writer, object o)
        {
            Type t = o.GetType();

            switch (TypeExtensions.GetTypeCode(t))
            {
            case TypeExtensions.TypeCode.Boolean: writer.Write((bool)o); break;

            case TypeExtensions.TypeCode.Char: writer.Write((char)o); break;

            case TypeExtensions.TypeCode.SByte: writer.Write((sbyte)o); break;

            case TypeExtensions.TypeCode.Byte: writer.Write((byte)o); break;

            case TypeExtensions.TypeCode.Int16: writer.Write((short)o); break;

            case TypeExtensions.TypeCode.UInt16: writer.Write((ushort)o); break;

            case TypeExtensions.TypeCode.Int32: writer.Write((int)o); break;

            case TypeExtensions.TypeCode.UInt32: writer.Write((uint)o); break;

            case TypeExtensions.TypeCode.Int64: writer.Write((long)o); break;

            case TypeExtensions.TypeCode.UInt64: writer.Write((ulong)o); break;

            case TypeExtensions.TypeCode.Single:
                if (Capabilities.FloatingPoint)
                {
                    writer.Write((float)o);
                }
                else
                {
                    writer.Write((int)((float)o * 1024));
                }
                break;

            case TypeExtensions.TypeCode.Double:
                if (Capabilities.FloatingPoint)
                {
                    writer.Write((double)o);
                }
                else
                {
                    writer.Write((long)((double)o * 65536));
                }
                break;

            case TypeExtensions.TypeCode.String:
                byte[] buf = Encoding.UTF8.GetBytes((string)o);

                writer.Write(buf.Length);
                writer.Write(buf);
                break;

            default:
                if (t == typeof(void))
                {
                }
                else if (t.IsArray)
                {
                    Array arr = (Array)o;

                    foreach (object arrItem in arr)
                    {
                        InternalSerializeInstance(writer, arrItem);
                    }
                }
                else if (t.GetRuntimeProperties().FirstOrDefault(n => n.Name == "Count") != null)
                {
                    // type implements Count property so it's a list

                    // cast to IList
                    IList list = (IList)o;

                    // go through each list item and serialize it
                    foreach (object arrItem in list)
                    {
                        InternalSerializeInstance(writer, arrItem);
                    }
                }
                else if (t.GetTypeInfo().IsValueType || t.GetTypeInfo().IsClass)
                {
                    InternalSerializeFields(writer, o);
                }
                else
                {
                    throw new SerializationException();
                }

                break;
            }
        }