protected internal sealed override ReplicationOperation PrepareReplicationOperation(StatefulServiceExecutionContext executionContext, ReplicationOperationType type, IEnumerable <Replicable> replicables, IDictionary <string, string> operationMetadata)
        {
            if (this.IsDisposed)
            {
                AppTrace.TraceMsg(TraceLogEventType.Information, "StatefulServiceReplicaT.PrepareReplicationOperation", "PrepareReplicationOperation called after service was disposed");
                return(null);
            }

            ReplicationOperation replicationOperation = null;

            if (type == ReplicationOperationType.Replicate)
            {
                StatefulProgramInstance instance = this.instanceManager.GetInstance(StatefulProgramInstance.CurrentInstanceId);
                if (instance == null)
                {
                    AppTrace.TraceMsg(TraceLogEventType.Error, "StatefulServiceReplicaT.PrepareReplicationOperation", "Could not find StatefulProgramInstance with id '{0}'", StatefulProgramInstance.CurrentInstanceId);
                    throw new InvalidOperationException("Replication needs to be triggered in context of a program instance.");
                }

                IEnumerable <Replicable> attributedReplicables = instance.CollectAttributedReplicableMembers(replicables);
                if (attributedReplicables != null)
                {
                    replicables = Enumerable.Concat(replicables, attributedReplicables);
                }

                instance.SetContextInstanceId(replicables);

                IEnumerable <Replicable> invalidReplicables;
                if (!instance.ValidateReplicablesMapToTypeMembers(replicables, out invalidReplicables))
                {
                    string        missingReplicables = StatefulProgramInstance.GetReplicablesString(invalidReplicables);
                    StringBuilder error = new StringBuilder();
                    error.AppendFormat("Replication cannot be triggered as following members were not found in instance of type '{0}'.", instance.TypeInfo.ReplicableType.FullName);
                    error.AppendLine(missingReplicables.ToString());
                    AppTrace.TraceMsg(TraceLogEventType.Information, "StatefulServiceReplicaT.PrepareReplicationOperation", error.ToString());
                    throw new InvalidOperationException(error.ToString());
                }

                // TODO: When we make Replicable name to be IComparable, we can remove the ToString call from here.
                replicationOperation = new ReplicationOperation(
                    type,
                    new List <Replicable>()
                {
                    new Replicable <StatefulProgramInstance>(instance.Id.ToString(), new StatefulProgramInstance(this, instance.Id, instance.TypeInfo.ReplicableType, instance.InitializationParams, replicables, instance.Singleton))
                },
                    operationMetadata);
            }
            else if (type == ReplicationOperationType.Copy)
            {
                ItemCollection <IComparable, StatefulProgramInstance> instances;
                using (this.instanceManager.GetInstances(LockPermission.Read, out instances))
                {
                    List <Replicable <StatefulProgramInstance> > replicablesToCopy = new List <Replicable <StatefulProgramInstance> >();
                    foreach (StatefulProgramInstance instance in instances)
                    {
                        // TODO: When we make Replicable name to be IComparable, we can remove the ToString call from here.
                        replicablesToCopy.Add(new Replicable <StatefulProgramInstance>(instance.Id.ToString(), instance));
                    }

                    replicationOperation = new ReplicationOperation(
                        type,
                        replicablesToCopy,
                        operationMetadata);
                }
            }

            if (replicationOperation == null)
            {
                replicationOperation = new ReplicationOperation(type, replicables, operationMetadata);
            }

            return(replicationOperation);
        }