/// <summary>
        /// Reads and deserializes a new instance of a type object from the Stream object.
        /// </summary>
        /// <typeparam name="T">The type to read from the stream.</typeparam>
        /// <param name="stream">The stream.</param>
        /// <returns>An instance of type T.</returns>
        public static T Read <T>(this Stream stream) where T : IVersionSerializable, new()
        {
            var reader       = SerializerFactory.GetReader(stream);
            var resultObject = new T();

            resultObject.Deserialize(reader, resultObject.CurrentVersion);
            return(resultObject);
        }
        /// <summary>
        /// Deserializes an object of the specified type from <paramref name="input"/>.
        /// </summary>
        /// <typeparam name="T">The type of object to deserialize.</typeparam>
        /// <param name="input">The stream to read from.</param>
        /// <returns>The deserialized object. <see langword="null"/> values are possible
        /// if <see langword="null"/> was originally serialized into the stream.</returns>
        /// <exception cref="ArgumentNullException">
        ///		<para><paramref name="input"/> is <see langword="null"/>.</para>
        /// </exception>
        /// <exception cref="ArgumentException">
        ///		<para><paramref name="input.CanSeek"/> is <see langword="false"/>.</para>
        /// </exception>
        public static T Deserialize <T>(Stream input)
        {
            ArgumentAssert.IsNotNull(input, "input");
            if (!input.CanSeek)
            {
                throw new ArgumentException("input.CanSeek must be true", "input");
            }

            var serializer = BarfSerializers.Get <T>(PartFlags.None);
            var args       = new BarfDeserializationArgs(SerializerFactory.GetReader(input));

            return(serializer.Deserialize(args));
        }