/// <summary>
        /// Constructs a new <see cref="ImmutableSurrogate"/>.
        /// </summary>
        /// <param name="context"><see cref="FudgeContext"/> to use.</param>
        /// <param name="typeData"><see cref="TypeData"/> for the type for this surrogate.</param>
        public ImmutableSurrogate(FudgeContext context, TypeData typeData)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            if (typeData == null)
                throw new ArgumentNullException("typeData");
            if (!CanHandle(typeData))
                throw new ArgumentOutOfRangeException("typeData", "ImmutableSurrogate cannot handle " + typeData.Type.FullName);

            this.context = context;
            this.type = typeData.Type;
            this.constructor = FindConstructor(typeData.Constructors, typeData.Properties, out constructorParams);
            Debug.Assert(constructor != null);  // Else how did it pass CanHandle?

            this.helper = new PropertyBasedSerializationSurrogate.PropertySerializerMixin(context, typeData, typeData.Properties, new DotNetSerializableSurrogate.BeforeAfterMethodMixin(context, typeData));
        }
        /// <summary>
        /// Constructs a new <see cref="SerializableAttributeSurrogate"/>.
        /// </summary>
        /// <param name="context"><see cref="FudgeContext"/> to use.</param>
        /// <param name="typeData"><see cref="TypeData"/> for the type for this surrogate.</param>
        public SerializableAttributeSurrogate(FudgeContext context, TypeData typeData)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            if (typeData == null)
                throw new ArgumentNullException("typeData");
            if (!CanHandle(typeData))
                throw new ArgumentOutOfRangeException("typeData", "SerializableAttributeSurrogate cannot handle " + typeData.Type.FullName);

            this.type = typeData.Type;

            var fields = from field in typeData.Fields
                         where field.GetCustomAttribute<NonSerializedAttribute>() == null
                         select field;

            var beforeAfterMixin = new DotNetSerializableSurrogate.BeforeAfterMethodMixin(context, typeData);
            this.serializerMixin = new PropertyBasedSerializationSurrogate.PropertySerializerMixin(context, typeData, fields, beforeAfterMixin);
        }
        /// <summary>
        /// Constructs a new instance for a specific type
        /// </summary>
        /// <param name="context"><see cref="FudgeContext"/> for this surrogate.</param>
        /// <param name="typeData"><see cref="TypeData"/> describing the type to serialize.</param>
        public DataContractSurrogate(FudgeContext context, TypeData typeData)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            if (typeData == null)
                throw new ArgumentNullException("typeData");
            if (!CanHandle(typeData))
                throw new ArgumentOutOfRangeException("typeData", "ImmutableSurrogate cannot handle " + typeData.Type.FullName);

            this.context = context;
            this.type = typeData.Type;

            Debug.Assert(typeData.DefaultConstructor != null);      // Should have been caught in CanHandle()

            var properties = from prop in typeData.Properties.Concat(typeData.Fields)
                             where prop.GetCustomAttribute<DataMemberAttribute>() != null
                             select prop;

            this.helper = new PropertyBasedSerializationSurrogate.PropertySerializerMixin(context, typeData, properties, new DotNetSerializableSurrogate.BeforeAfterMethodMixin(context, typeData));
        }