/// <summary>
        /// Unwrap object wrapped in <see cref="SerializedObjectWrapper"/>
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
		object Unwrap(SerializedObjectWrapper item)
        {
            if (item.Data.Array == null)
                return null;

            if (item.Flags == RawDataFlag)
            {
                ArraySegment<byte> tmp = item.Data;

                if (tmp.Count == tmp.Array.Length)
                    return tmp.Array;

                // we should never arrive here, but it's better to be safe than sorry
                var retval = new byte[tmp.Count];

                Array.Copy(tmp.Array, tmp.Offset, retval, 0, tmp.Count);

                return retval;
            }

            var code = (TypeCode)(item.Flags & 0x00ff);

            byte[] data = item.Data.Array;
            int offset = item.Data.Offset;
            int count = item.Data.Count;

            switch (code)
            {
                // incrementing a non-existing key then getting it
                // returns as a string, but the flag will be 0
                // so treat all 0 flagged items as string
                // this may help inter-client data management as well
                //
                // however we store 'null' as Empty + an empty array, 
                // so this must special-cased for compatibilty with 
                // earlier versions. we introduced DBNull as null marker in emc2.6
                case TypeCode.Empty:
                    return (data == null || count == 0)
                            ? null
                            : Encoding.UTF8.GetString(data, offset, count);

                case TypeCode.DBNull:
                    return null;

                case TypeCode.String:
                    return Encoding.UTF8.GetString(data, offset, count);

                case TypeCode.Boolean:
                    return BitConverter.ToBoolean(data, offset);

                case TypeCode.Int16:
                    return BitConverter.ToInt16(data, offset);

                case TypeCode.Int32:
                    return BitConverter.ToInt32(data, offset);

                case TypeCode.Int64:
                    return BitConverter.ToInt64(data, offset);

                case TypeCode.UInt16:
                    return BitConverter.ToUInt16(data, offset);

                case TypeCode.UInt32:
                    return BitConverter.ToUInt32(data, offset);

                case TypeCode.UInt64:
                    return BitConverter.ToUInt64(data, offset);

                case TypeCode.Char:
                    return BitConverter.ToChar(data, offset);

                case TypeCode.DateTime:
                    return DateTime.FromBinary(BitConverter.ToInt64(data, offset));

                case TypeCode.Double:
                    return BitConverter.ToDouble(data, offset);

                case TypeCode.Single:
                    return BitConverter.ToSingle(data, offset);

                case TypeCode.Object:
                    using (var ms = new MemoryStream(data, offset, count))
                    {
#if NETSTANDARD1_3
	            		return null;
#else
                        return bf.Deserialize(ms);
#endif
                    }

                default: throw new InvalidOperationException("Unknown TypeCode was returned: " + code);
            }
        }
        /// <summary>
        /// Unwrap object wrapped in <see cref="SerializedObjectWrapper"/>
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        object Unwrap(SerializedObjectWrapper item)
        {
            if (item.Data.Array == null)
            {
                return(null);
            }

            if (item.Flags == RawDataFlag)
            {
                ArraySegment <byte> tmp = item.Data;

                if (tmp.Count == tmp.Array.Length)
                {
                    return(tmp.Array);
                }

                // we should never arrive here, but it's better to be safe than sorry
                var retval = new byte[tmp.Count];

                Array.Copy(tmp.Array, tmp.Offset, retval, 0, tmp.Count);

                return(retval);
            }

            var code = (TypeCode)(item.Flags & 0x00ff);

            byte[] data   = item.Data.Array;
            int    offset = item.Data.Offset;
            int    count  = item.Data.Count;

            switch (code)
            {
            // incrementing a non-existing key then getting it
            // returns as a string, but the flag will be 0
            // so treat all 0 flagged items as string
            // this may help inter-client data management as well
            //
            // however we store 'null' as Empty + an empty array,
            // so this must special-cased for compatibilty with
            // earlier versions. we introduced DBNull as null marker in emc2.6
            case TypeCode.Empty:
                return((data == null || count == 0)
                            ? null
                            : Encoding.UTF8.GetString(data, offset, count));

            case TypeCode.DBNull:
                return(null);

            case TypeCode.String:
                return(Encoding.UTF8.GetString(data, offset, count));

            case TypeCode.Boolean:
                return(BitConverter.ToBoolean(data, offset));

            case TypeCode.Int16:
                return(BitConverter.ToInt16(data, offset));

            case TypeCode.Int32:
                return(BitConverter.ToInt32(data, offset));

            case TypeCode.Int64:
                return(BitConverter.ToInt64(data, offset));

            case TypeCode.UInt16:
                return(BitConverter.ToUInt16(data, offset));

            case TypeCode.UInt32:
                return(BitConverter.ToUInt32(data, offset));

            case TypeCode.UInt64:
                return(BitConverter.ToUInt64(data, offset));

            case TypeCode.Char:
                return(BitConverter.ToChar(data, offset));

            case TypeCode.DateTime:
                return(DateTime.FromBinary(BitConverter.ToInt64(data, offset)));

            case TypeCode.Double:
                return(BitConverter.ToDouble(data, offset));

            case TypeCode.Single:
                return(BitConverter.ToSingle(data, offset));

            case TypeCode.Object:
                using (var ms = new MemoryStream(data, offset, count))
                {
                    return(bf.Deserialize(ms));
                }

            default: throw new InvalidOperationException("Unknown TypeCode was returned: " + code);
            }
        }