object ReadValue(Type type, string name)
        {
            var    valueType = type;
            object value     = null;
            bool   shouldAssignNullableValue = false;
            int    nullables = 0;

            while (type.IsGenericType && type.GetGenericTypeDefinition() == Globals.TypeOfNullable)
            {
                nullables++;
                type = type.GetGenericArguments() [0];
            }

            PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(type);

            if ((primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject) || nullables != 0 || type.IsValueType)
            {
                context.ReadAttributes(xmlReader);
                string objectId = context.ReadIfNullOrRef(xmlReader, type, DataContract.IsTypeSerializable(type));
                // Deserialize null
                if (objectId == Globals.NullObjectId)
                {
                    if (nullables != 0)
                    {
                        value = Activator.CreateInstance(valueType);
                    }
                    else if (type.IsValueType)
                    {
                        throw new SerializationException(SR.GetString(SR.ValueTypeCannotBeNull, DataContract.GetClrTypeFullName(type)));
                    }
                    else
                    {
                        value = null;
                    }
                }
                else if (objectId == string.Empty)
                {
                    // Deserialize value

                    // Compare against Globals.NewObjectId, which is set to string.Empty

                    objectId = context.GetObjectId();

                    if (type.IsValueType)
                    {
                        if (!string.IsNullOrEmpty(objectId))
                        {
                            throw new SerializationException(SR.GetString(SR.ValueTypeCannotHaveId, DataContract.GetClrTypeFullName(type)));
                        }
                    }
                    object innerValueRead = null;
                    if (nullables != 0)
                    {
                        shouldAssignNullableValue = true;
                    }

                    if (primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject)
                    {
                        value = primitiveContract.XmlFormatReaderMethod.Invoke(xmlReader, new object [0]);
                        if (!type.IsValueType)
                        {
                            context.AddNewObject(value);
                        }
                    }
                    else
                    {
                        value = InternalDeserialize(type, name);
                    }
                }
                else
                {
                    // Deserialize ref
                    if (type.IsValueType)
                    {
                        throw new SerializationException(SR.GetString(SR.ValueTypeCannotHaveRef, DataContract.GetClrTypeFullName(type)));
                    }
                    else
                    {
                        value = CodeInterpreter.ConvertValue(context.GetExistingObject(objectId, type, name, string.Empty), Globals.TypeOfObject, type);
                    }
                }

                if (shouldAssignNullableValue)
                {
                    if (objectId != Globals.NullObjectId)
                    {
                        value = WrapNullableObject(type, value, valueType, nullables);
                    }
                }
            }
            else
            {
                value = InternalDeserialize(type, name);
            }

            return(value);
        }