/// <summary>
		/// Generates IL to read a single item from the stream and leaves the result on the stack.
		/// </summary>
		/// <param name="type">The <see cref="Type"/> of item to read.</param>
		/// <param name="args">The arguments for generating the il.</param>
		void GenerateReadTypeIL(Type type, GenerateArgs args)
		{
			MethodInfo method = GetTypeMethod(type, TypeMethodType.Deserialize);
			DynamicMethodHelper il = args.il;
			bool dynamic = IsDynamic && (type.IsValueType == false);

			//  Variable names
			const string valueVar = "_readValue";
			const string dynamicTypeIndexVar = "_typeIndex";
			const string dynamicTypeVar = "_dynamicType";
			const string dynamicTypeNameVar = "_dynamicTypeName";
			const string dynamicTypeResolvedLabel = "_dynamicTypeResolved";
			const string dynamicTypeNotNullLabel = "_dynamicTypeNotNull";
			const string dynamicTypeDoneLabel = "_dynamicTypeDone";

			il.BeginScope();
			{
				if (dynamic)
				{
					il.DeclareLocal(dynamicTypeIndexVar, typeof(byte));
					il.DeclareLocal(valueVar, typeof(object));
					il.DeclareLocal(dynamicTypeNameVar, typeof(string));
					il.DeclareLocal(dynamicTypeVar, typeof(Type));

					//  Read type index
					il.PushLocal(args.streamVar);
					il.CallMethod(GetTypeMethod(typeof(byte), TypeMethodType.Deserialize));
					il.PopLocal(dynamicTypeIndexVar);

					//  if (typeIndex == -1) goto :dynamicInstanceNull
					il.PushLocal(dynamicTypeIndexVar);
					il.PushInt(SerializerHeaders.NullVersion);
					il.GotoIfNotEqual(dynamicTypeNotNullLabel);

					//  return null
					//  goto :dynamicTypeDone
					il.PushNull();
					il.Goto(dynamicTypeDoneLabel);

					//  :dynamicTypeNotNull
					il.MarkLabel(dynamicTypeNotNullLabel);

					//  Get type info for typeIndex
					il.PushLocal(args.nameTableVar);
					il.PushLocal(dynamicTypeIndexVar);
					il.PushLocalAsRef(dynamicTypeVar);
					il.PushLocalAsRef(dynamicTypeNameVar);
					il.CallMethod(typeof(TypeNameTable).GetMethod("GetTypeInfo"));

					//  If (type != null) goto :typeResolved
					il.PushLocal(dynamicTypeVar);
					il.GotoIfTrue(dynamicTypeResolvedLabel);

					//  Call Type.GetType to resolve type. We must do this
					//  in the context of the type being deserialized to
					//  get the appropriate visibility permissions
					il.PushLocal(dynamicTypeNameVar);
					il.PushBool(true);
					il.CallMethod(typeof(Type).GetMethod(
										 "GetType",
										 BindingFlags.Static | BindingFlags.Public,
										 null,
										 new [] { typeof(string), typeof(bool) },
										 null
										 ));
					il.PopLocal(dynamicTypeVar);

					//  Save the resolved type back to the type table so
					//  subsequent instances of the same type don't have to
					//  do it again
					il.PushLocal(args.nameTableVar);
					il.PushLocal(dynamicTypeIndexVar);
					il.PushLocal(dynamicTypeVar);
					il.CallMethod(typeof(TypeNameTable).GetMethod("SetResolvedType"));

					//  :typeResolved
					il.MarkLabel(dynamicTypeResolvedLabel);

					//  Create an empty instance of the resolved type
					il.PushLocal(dynamicTypeVar);
					il.PushBool(true);
					il.CallMethod(typeof(Activator).GetMethod(
										 "CreateInstance",
										 new [] { typeof(Type), typeof(bool) }
										 ));

					il.PopLocal(valueVar);

					//  Call the serializer to read it
					il.PushLocalAsRef(valueVar);
					il.PushArg(args.dataArg);
					il.CallMethod(method);
					il.Pop();

					//  return (baseType)dynamicInstance
					il.PushLocal(valueVar);
					il.Cast(type);

					//  :dynamicTypeDone
					il.MarkLabel(dynamicTypeDoneLabel);

				}
				else if (method.DeclaringType == typeof(IPrimitiveReader))
				{
					//  return reader.ReadXXXX()
					il.PushLocal(args.streamVar);
					il.CallMethod(method);
				}
				else //if (type.IsClass)
				{
					//  Create empty instance of type
					il.DeclareLocal(valueVar, typeof(object));
					if (type.IsClass)
					{
						il.NewObject(valueVar, type, Type.EmptyTypes);
					}

					//  Call the serializer to read it
					il.PushLocalAsRef(valueVar);
					il.PushArg(args.dataArg);
					il.CallMethod(method);
					il.Pop();                       // Ignore return value

					//  return (type)instance
					il.PushLocal(valueVar);
					if (type.IsClass)
					{
						il.Cast(type);
					}
					else
					{
						il.UnboxValueType(type);
					}
				}
			}
			il.EndScope();
		}