protected override void OnUpdate( )
        {
            this.Dependency = JobHandle.CombineDependencies(m_validatePhysicEntitySnapshots.GetOutputDependency( ), Dependency);

            var snapshotsToProcess = m_validatePhysicEntitySnapshots.GetSnapshots( );

            var ghostLookup = m_ghostLookupSystem.GhostLookup;

            var interpolationBuffersFromEntity = GetBufferFromEntity <PhysicsSnapshotBufferElement>( );

            Job.WithCode(() =>
            {
                while (snapshotsToProcess.Length > 0)
                {
                    var snapshotToProcess = snapshotsToProcess[snapshotsToProcess.Length - 1];
                    snapshotsToProcess.RemoveAt(snapshotsToProcess.Length - 1);

                    if (!ghostLookup.TryGetValue(snapshotToProcess.GhostHash, out var ghostEnt) || !interpolationBuffersFromEntity.HasComponent(ghostEnt))
                    {
                        continue;
                    }

                    if (GetComponent <PhysicsSnapshotSyncData>(ghostEnt).LastTimeWeSendData > snapshotToProcess.SampledForServerTime)
                    {
                        continue;
                    }

                    var interpolationBuffer = interpolationBuffersFromEntity[ghostEnt];

                    { //Insert snapshot. Snapshots are ordered by time.
                        int snapshotBeforeTheOneThatWeProcess = 0;

                        for (int i = 0; i < interpolationBuffer.Length; ++i)
                        {
                            if (interpolationBuffer[i].Time > snapshotToProcess.SampledForServerTime)
                            {
                                snapshotBeforeTheOneThatWeProcess = i + 1;
                            }
                            else
                            {
                                break;
                            }
                        }

                        if (snapshotBeforeTheOneThatWeProcess == interpolationBuffer.Capacity)
                        {
                            continue; //Snapshot to old to be queued.
                        }
                        if (interpolationBuffer.Length >= interpolationBuffer.Capacity)
                        {
                            interpolationBuffer.RemoveAt(interpolationBuffer.Length - 1);   //Make space for new element
                        }
                        interpolationBuffer.Insert(snapshotBeforeTheOneThatWeProcess, new PhysicsSnapshotBufferElement( )
                        {
                            Time  = snapshotToProcess.SampledForServerTime,
                            Value = snapshotToProcess.Snapshot
                        });
                    }
                }
            }).Schedule( );

            m_barrier.AddJobHandleForProducer(Dependency);
        }
        protected override void OnUpdate( )
        {
            ClientServerTickRate tickRate = default;

            tickRate.ResolveDefaults( );


            if (HasSingleton <ClientServerTickRate>( ))
            {
                tickRate = GetSingleton <ClientServerTickRate>( );
            }

            //Interpolation delay should be simulation send interval in seconds + rtt in seconds + extra buffer

            var isServer      = m_isServer;
            var commandBuffer = m_barrier.CreateCommandBuffer( );

            var tick = m_isServer ? m_serverSimulationSystemGroup.ServerTick : m_clientSimulationSystemGroup.ServerTick;

            var serverTickInSeconds = tick / ( float )tickRate.SimulationTickRate;

            if (!m_isServer)
            {
                serverTickInSeconds += m_clientSimulationSystemGroup.ServerTickFraction / tickRate.SimulationTickRate;
            }

            var hashLookup = m_ghostLookupSystem.HashLookup;

            Dependency = JobHandle.CombineDependencies(Dependency, m_validatePhysicEntitySnapshots.GetOutputDependency( ));

            m_validatePhysicEntitySnapshots.AddInputDependency(Dependency);

            var snapshotsToStoreLocally = m_validatePhysicEntitySnapshots.GetSnapshots( );

            Entities.WithAll <HasAuthorityOverPhysicsBody, ShouldSimulatePhysicsBody>().ForEach((Entity ent, ref PhysicsSnapshotSyncData sendData, in PhysicsSnapshot snapshot, in PhysicsBodyReference bodyReference, in GhostComponent ghostComponent) =>
            {
                if (serverTickInSeconds - sendData.LastTimeWeSendData < sendData.SendIntervalInSeconds)
                {
                    return;
                }

                if (!hashLookup.TryGetValue(ent, out var hash))
                {
                    return; //Not registered yet or not a valid ghost.
                }
                sendData.LastTimeWeSendData = serverTickInSeconds;

                var rpcEnt = commandBuffer.CreateEntity( );

                var physicsSnapshotRpc = new PhysicsSnapshotRpc
                {
                    Snapshot             = snapshot,
                    SampledForServerTime = serverTickInSeconds,
                    GhostHash            = hash,
                };
                commandBuffer.AddComponent(rpcEnt, physicsSnapshotRpc);

                if (!isServer)
                {
                    commandBuffer.AddComponent <SendRpcCommandRequestComponent>(rpcEnt);
                }
                else
                {
                    commandBuffer.AddComponent <ReceiveRpcCommandRequestComponent>(rpcEnt);
                }

                snapshotsToStoreLocally.Add(physicsSnapshotRpc);
            }).Schedule( );