protected virtual object DeserializeObject(object value, Type type, object defaultValue, PersistenceSerializationMode serializationMode)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if ((serializationMode & PersistenceSerializationMode.ModeMask) == PersistenceSerializationMode.None)
            {
                return(ConvertUtilities.ChangeType(value, type));
            }

            if (value == null)
            {
                return(ConvertUtilities.ChangeType(defaultValue, type));
            }

            if (type.IsInstanceOfType(value))
            {
                return(value);
            }

            byte[] bytes;
            if (typeof(XmlDocument).IsAssignableFrom(type))
            {
                string str = value as string;
                if (str != null)
                {
                    XmlDocument doc    = new XmlDocument();
                    string      svalue = str;
                    if (svalue.Trim().Length > 0)
                    {
                        doc.LoadXml(svalue);
                    }
                    return(doc);
                }

                bytes = value as byte[];
                if (bytes != null)
                {
                    XmlDocument doc = new XmlDocument();
                    if (bytes.Length > 0)
                    {
                        using (MemoryStream stream = new MemoryStream(bytes))
                        {
                            doc.Load(stream);
                        }
                    }
                    return(doc);
                }
            }

            if (typeof(IBinarySerialize).IsAssignableFrom(type))
            {
                string str = value as string;
                if (str != null)
                {
                    object           o            = type.Assembly.CreateInstance(type.FullName, false);
                    IBinarySerialize serializable = o as IBinarySerialize;
                    if (serializable != null)
                    {
                        using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(str)))
                        {
                            using (BinaryReader binaryReader = new BinaryReader(ms))
                            {
                                serializable.Read(binaryReader);
                                return(ConvertUtilities.ChangeType(o, type));
                            }
                        }
                    }
                }
                else
                {
                    bytes = value as byte[];
                    if (bytes != null)
                    {
                        object           o            = type.Assembly.CreateInstance(type.FullName, false);
                        IBinarySerialize serializable = o as IBinarySerialize;
                        if (serializable != null)
                        {
                            using (MemoryStream stream = new MemoryStream(bytes))
                            {
                                using (BinaryReader binaryReader = new BinaryReader(stream))
                                {
                                    serializable.Read(binaryReader);
                                    return(ConvertUtilities.ChangeType(o, type));
                                }
                            }
                        }
                    }
                }
            }

            if ((serializationMode & PersistenceSerializationMode.ModeMask) == PersistenceSerializationMode.Custom)
            {
                // note: value not null here
                object o = type.Assembly.CreateInstance(type.FullName, false);
                ICodeFluentSerializable serializable = o as ICodeFluentSerializable;
                if (serializable == null)
                {
                    throw new Exception(string.Format("Type '{0}' does not implement the ICodeFluentSerializable interface.", type.FullName));
                }

                return(serializable.Deserialize(type, serializationMode, value));
            }

            bytes = value as byte[];
            if (bytes != null)
            {
                if (bytes.Length == 0)
                {
                    return(ConvertUtilities.ChangeType(defaultValue, type));
                }

                using (MemoryStream stream = new MemoryStream(bytes))
                {
                    switch ((serializationMode & PersistenceSerializationMode.ModeMask))
                    {
                    case PersistenceSerializationMode.Xml:
                        XmlSerializer serializer = new XmlSerializer(type);
                        return(serializer.Deserialize(stream));

                    case PersistenceSerializationMode.Soap:
                        SoapFormatter soapFormatter = new SoapFormatter();
                        return(ConvertUtilities.ChangeType(soapFormatter.Deserialize(stream), type));

                    case PersistenceSerializationMode.Binary:
                        BinaryFormatter binaryFormatter = new BinaryFormatter();
                        return(ConvertUtilities.ChangeType(binaryFormatter.Deserialize(stream), type));

                    default:
                        throw new ArgumentOutOfRangeException("serializationMode", string.Format("Serialization mode '{0}' is not supported.", serializationMode));
                    }
                }
            }

            string s = value as string;

            if (s != null)
            {
                if (s.Length == 0)
                {
                    return(ConvertUtilities.ChangeType(defaultValue, type));
                }

                switch ((serializationMode & PersistenceSerializationMode.ModeMask))
                {
                case PersistenceSerializationMode.Xml:
                    using (StringReader sr = new StringReader(s))
                    {
                        XmlSerializer serializer = new XmlSerializer(type);
                        return(serializer.Deserialize(sr));
                    }

                case PersistenceSerializationMode.Soap:
                    SoapFormatter soapFormatter = new SoapFormatter();
                    using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(s)))
                    {
                        return(ConvertUtilities.ChangeType(soapFormatter.Deserialize(ms), type));
                    }

                case PersistenceSerializationMode.Binary:
                    BinaryFormatter binaryFormatter = new BinaryFormatter();
                    using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(s)))
                    {
                        return(ConvertUtilities.ChangeType(binaryFormatter.Deserialize(ms), type));
                    }

                default:
                    throw new ArgumentOutOfRangeException("serializationMode", string.Format("Serialization mode '{0}' is not supported.", serializationMode));
                }
            }

            return(ConvertUtilities.ChangeType(value, type, defaultValue));
        }
        protected virtual byte[] SerializeObject(object value, Type type, PersistenceSerializationMode serializationMode)
        {
            if (value == null)
            {
                return(null);
            }

            IBinarySerialize bs = value as IBinarySerialize;

            if (bs != null)
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    using (BinaryWriter writer = new BinaryWriter(stream))
                    {
                        bs.Write(writer);
                    }
                    return(stream.ToArray());
                }
            }


            if ((serializationMode & PersistenceSerializationMode.ModeMask) == PersistenceSerializationMode.Custom)
            {
                // note: value not null here
                object o = type.Assembly.CreateInstance(type.FullName, false);
                ICodeFluentSerializable serializable = o as ICodeFluentSerializable;
                if (serializable == null)
                {
                    throw new Exception(string.Format("Type '{0}' does not implement the ICodeFluentSerializable interface.", type.FullName));
                }

                return(ConvertUtilities.ChangeType(serializable.Serialize(serializationMode), (byte[])null));
            }

            using (MemoryStream stream = new MemoryStream())
            {
                switch ((serializationMode & PersistenceSerializationMode.ModeMask))
                {
                case PersistenceSerializationMode.Xml:
                    if (type == null)
                    {
                        throw new ArgumentNullException("type");
                    }

                    XmlSerializer serializer = new XmlSerializer(type);
                    serializer.Serialize(stream, value);
                    break;

                case PersistenceSerializationMode.Soap:
                    SoapFormatter soapFormatter = new SoapFormatter();
                    soapFormatter.Serialize(stream, value);
                    break;

                case PersistenceSerializationMode.Binary:
                    BinaryFormatter binaryFormatter = new BinaryFormatter();
                    binaryFormatter.Serialize(stream, value);
                    break;

                default:
                    throw new ArgumentOutOfRangeException("serializationMode", string.Format("Serialization mode '{0}' is not supported.", serializationMode));
                }
                return(stream.ToArray());
            }
        }