public MixinSerializationHelper(SerializationInfo info, StreamingContext context)
        {
            ArgumentUtility.CheckNotNull("info", info);

            _context = context;

            var identifierDeserializer = new SerializationInfoConcreteMixinTypeIdentifierDeserializer(info, "__identifier");
            var identifier             = ConcreteMixinTypeIdentifier.Deserialize(identifierDeserializer);

            var pipelineIdentifier = info.GetString("__participantConfigurationID");
            var pipeline           = SafeServiceLocator.Current.GetInstance <IPipelineRegistry>().Get(pipelineIdentifier);

            var mixinType = pipeline.ReflectionService.GetAdditionalType(identifier);

            _baseMemberValues = (object[])info.GetValue("__baseMemberValues", typeof(object[]));

            // Usually, instantiate a deserialized object using GetSafeUninitializedObject.
            // However, _baseMemberValues being null means that the object itself manages its member deserialization via ISerializable. In such a case, we
            // need to use the deserialization constructor to instantiate the object.
            if (_baseMemberValues != null)
            {
                _deserializedObject = FormatterServices.GetSafeUninitializedObject(mixinType);
            }
            else
            {
                Assertion.IsTrue(typeof(ISerializable).IsAssignableFrom(mixinType));
                _deserializedObject = Activator.CreateInstance(
                    mixinType,
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
                    null,
                    new object[] { info, context },
                    null);
            }
            SerializationImplementer.RaiseOnDeserializing(_deserializedObject, _context);
        }
        // Here, we can rely on everything being deserialized as needed.
        public void OnDeserialization(object sender)
        {
            if (_baseMemberValues != null)
            {
                var baseType = _deserializedObject.GetType().BaseType;
                Assertion.IsNotNull(baseType, "Mixed types always have a base type.");
                MemberInfo[] baseMembers = FormatterServices.GetSerializableMembers(baseType);
                FormatterServices.PopulateObjectMembers(_deserializedObject, baseMembers, _baseMemberValues);
            }

            SerializationImplementer.RaiseOnDeserialized(_deserializedObject, _context);
            SerializationImplementer.RaiseOnDeserialization(_deserializedObject, sender);

            // Note: This and Next properties are initialized from the target class via InitializeDeserializedMixinTarget
        }
        public void ImplementGetObjectData()
        {
            // TODO 5811: This does exactly the same as what ComplexSerializationEnabler does, but with a different ID (ConcreteMixinTypeIdentifier instead
            // of AssembledTypeID) and a different way to get the type back from the pipeline (GetAdditionalType instead of GetAssembledType).
            // Consider refactoring ComplexSerializationEnabler to allow this code to be replaced.

            SerializationImplementer.ImplementGetObjectDataByDelegation(
                _type,
                (ctx, baseIsISerializable) =>
                Expression.Call(
                    null,
                    s_getObjectDataForGeneratedTypesMethod,
                    ctx.Parameters[0],
                    ctx.Parameters[1],
                    ctx.This,
                    _identifierField,
                    Expression.Constant(!baseIsISerializable),
                    Expression.Constant(_pipelineIdentifier)));
        }