public object Deserialize(byte[] data)
        {
            PayloadReader pr = new PayloadReader(data);
            ObjectTypes   Id = (ObjectTypes)pr.ReadByte();

            switch (Id)
            {
            case ObjectTypes.Null: return(null);

            case ObjectTypes.Other:
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Binder = new DeserializationBinder();
                return(bf.Deserialize(new MemoryStream(pr.ReadBytes(pr.Length - pr.Offset))));
            }

            case ObjectTypes.Byte: return(pr.ReadByte());

            case ObjectTypes.Short: return(pr.ReadShort());

            case ObjectTypes.UShort: return(pr.ReadUShort());

            case ObjectTypes.Int: return(pr.ReadInteger());

            case ObjectTypes.UINT: return(pr.ReadUInteger());

            case ObjectTypes.Long: return(pr.ReadLong());

            case ObjectTypes.Bool: return(pr.ReadByte() == 1);

            case ObjectTypes.String: return(pr.ReadString());

            case ObjectTypes.SolidBrush: return(new SolidBrush(Color.FromArgb(pr.ReadByte(), pr.ReadByte(), pr.ReadByte(), pr.ReadByte())));

            case ObjectTypes.Rectangle: return(new Rectangle(pr.ReadInteger(), pr.ReadInteger(), pr.ReadInteger(), pr.ReadInteger()));

            case ObjectTypes.Size: return(new Size(pr.ReadInteger(), pr.ReadInteger()));

            case ObjectTypes.ByteArray: return(pr.ReadBytes(pr.ReadInteger()));

            case ObjectTypes.Bitmap:
            {
                using (MemoryStream stream = new MemoryStream(pr.Buffer, pr.Offset, pr.Length - pr.Offset))
                {
                    long   oldPos = stream.Position;
                    Bitmap bmp    = (Bitmap)Bitmap.FromStream(stream);
                    pr.Offset += (int)(stream.Position - oldPos);
                    return(bmp);
                }
            }

            default: throw new Exception("Error deserializing");
            }
        }