protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            buildKDInJob = !buildKDInJob;
            PrintMessages();
        }

        int count = m_Group.CalculateEntityCount();

        if (count == 0)
        {
            return(inputDeps);
        }

        if (!translations.IsCreated)
        {
            translations = new NativeArray <float2>(count, Allocator.Persistent);
        }
        else if (translations.Length != count)
        {
            translations.Dispose();
            translations = new NativeArray <float2>(count, Allocator.Persistent);
        }

        if (!velocities.IsCreated)
        {
            velocities = new NativeArray <float3>(count, Allocator.Persistent);
        }
        else if (velocities.Length != count)
        {
            velocities.Dispose();
            velocities = new NativeArray <float3>(count, Allocator.Persistent);
        }

        CopyTranslations copyTranslationsJob = new CopyTranslations
        {
            translations    = translations,
            translationType = GetComponentTypeHandle <Translation>()
        };

        CopyVelocities copyVelocitiesJob = new CopyVelocities
        {
            velocities   = velocities,
            velocityType = GetComponentTypeHandle <Velocity>()
        };

        JobHandle copyTranslationsJobHandle = copyTranslationsJob.Schedule(m_Group, inputDeps);
        JobHandle copyVelocitiesJobHandle   = copyVelocitiesJob.Schedule(m_Group, inputDeps);
        JobHandle copyJobsHandle            = JobHandle.CombineDependencies(copyTranslationsJobHandle, copyVelocitiesJobHandle);

        if (!kd.isCreated)
        {
            kd.InitializeArrays(translations);
        }

        JobHandle kdBuildHandle = copyJobsHandle;

        if (buildKDInJob)
        {
            kdBuildHandle = kd.Schedule(copyJobsHandle);
        }
        else
        {
            copyJobsHandle.Complete();
            kd.Execute();
        }

        KDCollisions kDCollisionsJob = new KDCollisions
        {
            kdTree       = kd,
            positions    = translations,
            velocities   = velocities,
            dt           = Time.DeltaTime,
            velocityType = GetComponentTypeHandle <Velocity>()
        };
        JobHandle kDCollisionsJobHandle = kDCollisionsJob.Schedule(m_Group, kdBuildHandle);

        return(kDCollisionsJobHandle);
    }
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        int count = m_Group.CalculateEntityCount();

        if (count == 0)
        {
            return(inputDeps);
        }

        if (!translations.IsCreated)
        {
            translations = new NativeArray <float3>(count, Allocator.Persistent);
        }
        else if (translations.Length != count)
        {
            translations.Dispose();
            translations = new NativeArray <float3>(count, Allocator.Persistent);
        }

        if (!velocities.IsCreated)
        {
            velocities = new NativeArray <float3>(count, Allocator.Persistent);
        }
        else if (velocities.Length != count)
        {
            velocities.Dispose();
            velocities = new NativeArray <float3>(count, Allocator.Persistent);
        }

        CopyTranslations copyTranslationsJob = new CopyTranslations
        {
            translations    = translations,
            translationType = GetComponentTypeHandle <Translation>()
        };

        CopyVelocities copyVelocitiesJob = new CopyVelocities
        {
            velocities   = velocities,
            velocityType = GetComponentTypeHandle <Velocity>()
        };

        JobHandle copyTranslationsJobHandle = copyTranslationsJob.Schedule(m_Group, inputDeps);
        JobHandle copyVelocitiesJobHandle   = copyVelocitiesJob.Schedule(m_Group, inputDeps);
        JobHandle copyJobsHandle            = JobHandle.CombineDependencies(copyTranslationsJobHandle, copyVelocitiesJobHandle);

        if (CollisionBuckets.IsCreated)
        {
            CollisionBuckets.Dispose();
        }
        CollisionBuckets = new NativeMultiHashMap <int, int>(count, Allocator.Persistent);

        PrepareBucketsJob prepareBucketsJob = new PrepareBucketsJob
        {
            positions = translations,
            buckets   = CollisionBuckets
        };

        JobHandle prepareBucketsHandle = prepareBucketsJob.Schedule(copyJobsHandle);

        CollisionJob collisionJob = new CollisionJob
        {
            dt             = Time.DeltaTime,
            positions      = translations,
            velocities     = velocities,
            buckets        = CollisionBuckets,
            maxIterations  = m_maxIterations,
            maxClosestDone = m_maxClosestDone,
            maxForce       = m_maxForce,
            damping        = m_damping,
            radiusSqr      = m_radiusSqr,
            maxVelocity    = m_maxVelocity,
            maxVelocitySqr = m_maxVelocitySqr,
            velocityType   = GetComponentTypeHandle <Velocity>()
        };

        return(collisionJob.Schedule(m_Group, prepareBucketsHandle));
    }