/// <summary>
		/// Derived classes have to call this constructor.
		/// </summary>
		/// <param name="parameters">Contains many options.</param>
		protected DeserializationFormatter(Parameters parameters)
		{
			this.parameters = parameters;
			this.stream = this.parameters.Stream;
			this.typeManagerCollection =
				new L3TypeManagerCollection(this.parameters.customModifiers);
		}
        internal Object Deserialize()
        {
            if (this.DataEndMarkHasBeenPassed)
            {
                throw new EndOfStreamException();
            }
            this.DataEndMarkHasBeenPassed = false;
            this.instancesChannel         = new InstancesChannel();
            if (this.stream.CanSeek)
            {
                if (this.stream.Position == this.stream.Length)
                {
                    this.stream.Position = 0;
                }
                this.SetStreamPosition(this.stream.Position); // Useful if any cache memory.
            }

            this.PassPreamble();

            if (this.typeManagerCollection == null)
            {
                this.typeManagerCollection =
                    new L3TypeManagerCollection(this.parameters.customModifiers, this.Version);
            }

            this.TypeDescriptorTypeManager = this.typeManagerCollection.GetTypeManager((int)SerializationFormatter.CompulsoryType.SerializationTypeDescriptorIndex);

            if (this.Version == StreamFormatVersion.Version3_0)
            {
                // We load the Header (new in version 3.0):

                Header header = (Header)this.LookForObjectAndManagesChannels(
                    this.typeManagerCollection.GetTypeManager((int)SerializationFormatter.CompulsoryType.HeaderIndex),
                    null, null, false);

                // now we try to load these assemblies:
                foreach (var ai in header.AssemblyIdentifiers)
                {
                    ai.Load();
                }
            }

            object o = this.LookForObjectAndManagesChannels(null, null, null, false);

            if (!this.DataEndMarkHasBeenPassed)
            {
                this.PassDataEndMark();
            }
            this.PassTreeEndTag();

            return(o);
        }
		internal SerializationFormatter(
			Parameters parameters)
		{
			this.l3typeManagerCollection =
				new L3TypeManagerCollection(parameters.customModifiers);

			#region For Serializer.cs
#if !DEBUG
			var f2 =
	(delAddAllStructs<int>)(addAllStructs<int>);
			this.gfAddAllStructs = f2.Method.GetGenericMethodDefinition();
#endif
			#endregion For Serializer.cs


			if (this.IsStringFormatter && parameters.Stream != null)
				this.streamWriter = new StreamWriter(parameters.Stream, Encoding.UTF8);
			else
				this.binaryWriter = new FileTools.BinaryWriter2(parameters.Stream, Encoding.UTF8);

			parameters.TheStreamingMode =
			 (parameters.StreamingMode != null) ?
			 parameters.StreamingMode.Value
			 :
				(parameters.setOfStreams != null ?
					StreamingModes.SetOfStreams :
					(this.CanManageMultiplexStreams ? StreamingModes.MultiplexStream : StreamingModes.AssembledStream));

			this.parameters = parameters;

			{
				bool UseMemoryStreams = this.parameters.TheStreamingMode == StreamingModes.AssembledStream;

				if (parameters.SerializeTypeDescriptors)
					this.channelInfos[(int)ChannelNumber.TypeDescriptorsChannel] = new ChannelInfos(
						this,
											parameters.setOfStreams != null ? parameters.setOfStreams.TypesStream :
											UseMemoryStreams ? new MemoryStream() : parameters.Stream
#if DEBUG
, "Types branch"
#endif
, ChannelNumber.TypeDescriptorsChannel
					);
				this.channelInfos[(int)ChannelNumber.InstancesChannel] = new ChannelInfos(
					this,
										parameters.setOfStreams != null ? parameters.setOfStreams.InstancesStream :
										UseMemoryStreams ? new MemoryStream() : parameters.Stream
#if DEBUG
, "Instances branch"
#endif
, ChannelNumber.InstancesChannel
				);
			}

		}