private void System_ReplicaRemoved(Replica replica)
        {
            if (options.MasterOnly && !replica.Master)
            {
                return;
            }

            if (!options.AllowAddOrRemove || !replica.AddOrRemove)
            {
                return;
            }

            WriteRemove(GetNextMessage(), replica);
        }
        private void System_ReplicaUpdated(Replica replica)
        {
            if (options.MasterOnly && !replica.Master)
            {
                return;
            }

            if (!options.AllowUpdatedOnly || !replica.UpdatedOnly)
            {
                return;
            }

            updated.Add(replica);
        }
        private void WriteAdd(Protobuf.ReplicationMessage message, Replica replica)
        {
            var addMessage = new Protobuf.AddMessage()
            {
                TypeId    = system.GetTypeId(replica.Value.GetType()),
                ReplicaId = replica.Id.Value,
                Replica   = replica.Value.ToByteString()
            };

            message.Actions.Add(new Protobuf.ReplicationMessage.Types.ActionMessage()
            {
                Add = addMessage
            });
        }
        private void WriteUpdate(Protobuf.ReplicationMessage message, Replica replica)
        {
            var value = replica.Value.ToByteString();

            if (options.AllowDifferentOnly && replica.DifferentOnly)
            {
                if (lastValues.TryGetValue(replica.Id, out ByteString lastState) && value.Equals(lastState))
                {
                    // Identical to last state, skip it
                    return;
                }
                lastValues[replica.Id] = value;
            }

            var updateMessage = new Protobuf.UpdateMessage();

            updateMessage.ReplicaId = replica.Id;
            updateMessage.Replica   = value;
            message.Updates.Add(updateMessage);
        }