private void ProcessQuorumRequest(QuorumRequestEnvelope quorumRequestEnvelope)
        {
            ulong quorumHash = quorumRequestEnvelope.CommandEnvelope.Command.QuorumHash;

            if (this.state.ActiveQuorumVotesByHash.ContainsKey(quorumHash))
            {
                // quorum vote is active
                this.state.ActiveQuorumVotesByHash[quorumHash].Tell(quorumRequestEnvelope.CommandEnvelope);
                return;
            }

            if (quorumRequestEnvelope.VoterCount == QuorumRequestEnvelope.UNKNOWNVOTERCOUNT)
            {
                // we need to now the voter count to get a quorum.
                quorumRequestEnvelope.VotingAreaId = Locator.GetAreaIdFromWorldPosition(this.state.WorldPosition);
                this.log.Debug($"Requesting voter count for quorum '{quorumHash}' from area [{quorumRequestEnvelope.VotingAreaId}].");
                this.shardRegionArea.Tell(quorumRequestEnvelope);
                return;
            }

            // TODO: configure timeout
            IActorRef quorumActor = Context.ActorOf(Props.Create <QuorumActor>(quorumHash, quorumRequestEnvelope.VoterCount, TimeSpan.FromSeconds(1)), GetQuorumActorNameFromHash(quorumHash));

            Context.Watch(quorumActor);
            this.state.ActiveQuorumVotesByHash.Add(quorumHash, quorumActor);
            quorumActor.Tell(quorumRequestEnvelope.CommandEnvelope);
        }
        private T TellObject <T>(ObjectCommandEnvelope cmdMsg, Func <BaseCommand, T> createFunc)
            where T : BaseCommand, IObjectCommand
        {
            T      cmd             = createFunc(cmdMsg.Command);
            var    commandEnvelope = new ObjectCommandEnvelope(cmdMsg.SenderId, cmd, cmdMsg.ToObjectId);
            object message         = commandEnvelope;

            if ((cmd.Flags & CommandFlags.QuorumRequest) != 0)
            {
                message = new QuorumRequestEnvelope(commandEnvelope);
            }

            this.shardRegionObject.Tell(message);
            return(cmd);
        }