public void MakeSerializable(MutableType proxyType, MethodInfo initializationMethod)
        {
            ArgumentUtility.CheckNotNull("proxyType", proxyType);
            // initializationMethod may be null

            // Base fields are always serialized by the standard .NET serialization or by an implementation of ISerializable on the base type.
            // Added fields are also serialized by the standard .NET serialization, unless the proxy type implements ISerializable. In that case,
            // we need to extend the ISerializable implementation to include the added fields.

            var serializedFieldMapping     = _serializableFieldFinder.GetSerializableFieldMapping(proxyType.AddedFields.Cast <FieldInfo>()).ToArray();
            var deserializationConstructor = GetDeserializationConstructor(proxyType);

            // If the base type implements ISerializable but has no deserialization constructor, we can't implement ISerializable correctly, so
            // we don't even try. (ComplexSerializationEnabler relies on this behavior.)
            var needsCustomFieldSerialization =
                serializedFieldMapping.Length != 0 && typeof(ISerializable).IsTypePipeAssignableFrom(proxyType) && deserializationConstructor != null;

            if (needsCustomFieldSerialization)
            {
                OverrideGetObjectData(proxyType, serializedFieldMapping);
                AdaptDeserializationConstructor(deserializationConstructor, serializedFieldMapping);
            }

            if (initializationMethod != null)
            {
                if (typeof(IDeserializationCallback).IsTypePipeAssignableFrom(proxyType))
                {
                    OverrideOnDeserialization(proxyType, initializationMethod);
                }
                else if (proxyType.IsTypePipeSerializable())
                {
                    ExplicitlyImplementOnDeserialization(proxyType, initializationMethod);
                }
            }
        }
        public void MakeSerializable(
            MutableType proxyType,
            string participantConfigurationID,
            IAssembledTypeIdentifierProvider assembledTypeIdentifierProvider,
            AssembledTypeID typeID)
        {
            ArgumentUtility.CheckNotNull("proxyType", proxyType);
            ArgumentUtility.CheckNotNullOrEmpty("participantConfigurationID", participantConfigurationID);
            ArgumentUtility.CheckNotNull("assembledTypeIdentifierProvider", assembledTypeIdentifierProvider);

            if (!proxyType.IsTypePipeSerializable())
            {
                return;
            }

            var assembledTypeIDData = assembledTypeIdentifierProvider.GetAssembledTypeIDDataExpression(typeID);

            if (typeof(ISerializable).IsTypePipeAssignableFrom(proxyType))
            {
                // If the mutable type already implements ISerializable, we only need to extend the implementation to include the metadata required for
                // deserialization. Existing fields will be serialized by the base ISerialization implementation. Added fields will be serialized by
                // the TypePipe (ProxySerializationEnabler).
                try
                {
                    proxyType
                    .GetOrAddImplementation(s_getObjectDataMethod)
                    .SetBody(
                        ctx => Expression.Block(
                            ctx.PreviousBody,
                            CreateMetaDataSerializationExpression(
                                ctx.Parameters[0], typeof(ObjectWithDeserializationConstructorProxy), participantConfigurationID, assembledTypeIDData)));
                }
                catch (NotSupportedException)
                {
                    // Overriding and re-implementation failed because the base implementation of GetObjectData is not accessible from the proxy.
                    // Do nothing here; error reporting code will be generated in the ProxySerializationEnabler.
                    // Reasoning: Users often cannot influence the requested type and do not care about any serialization problem.
                }
            }
            else
            {
                // If the mutable type does not implement ISerializable, we need to add the interface and then also serialize all the fields on the object.
                // We cannot add a deserialization constructor because there is no base constructor that we could call. Therefore, ProxySerializationEnabler
                // cannot take care of serializing the added fields, and we thus have to serialize both existing and added fields ourselves via
                // ReflectionSerializationHelper.AddFieldValues.

                proxyType.AddInterface(typeof(ISerializable));

                proxyType.AddExplicitOverride(
                    s_getObjectDataMethod,
                    ctx => Expression.Block(
                        CreateMetaDataSerializationExpression(
                            ctx.Parameters[0], typeof(ObjectWithoutDeserializationConstructorProxy), participantConfigurationID, assembledTypeIDData),
                        Expression.Call(s_addFieldValuesMethod, ctx.Parameters[0], ctx.This)));
            }
        }