/// <summary>
        /// Updates the rebuild system.
        /// </summary>
        private void RebuildUpdate()
        {
            if (this.runningJobs.Count == 0)
            {
                return;
            }

            // Get first finished job
            uint dataId = 0;
            StaticBatchingRebuildJobData jobData = default(StaticBatchingRebuildJobData);
            bool found = false;

            foreach (var kvp in this.runningJobs)
            {
                var val = kvp.Value;
                if (val.jobHandle.IsCompleted)
                {
                    dataId  = kvp.Key;
                    jobData = val;
                    found   = true;
                    break;
                }
            }

            if (!found)
            {
                return;
            }

            FinishMeshRebuild(jobData);
        }
        /// <summary>
        /// Queues new or rebuild of the specified group.
        /// </summary>
        /// <param name="group">The group to rebuild.</param>
        private void QueueRebuild(StaticBatchingGroupKey group)
        {
            // Read instances
            List <StaticMeshInstance> instances;

            if (!this.meshInstances.TryGetValue(group, out instances))
            {
                return;
            }

            // Prepare data arrays for job
            int vCounter = 0, iCounter = 0; // Vertex and index counter
            StaticBatchingRebuildJobData jobData = new StaticBatchingRebuildJobData()
            {
                groupKey = group
            };

            jobData.PreAllocate();

            foreach (var instance in instances)
            {
                var cache = GetVisCache(instance.mesh);
                jobData.meshInstances.Add(instance);
                jobData.vertexOffsets.Add(vCounter);
                jobData.indexOffsets.Add(iCounter);
                vCounter += cache.vertices.Length;
                iCounter += cache.indices.Length;
            }

            // Allocate job data memory
            jobData.Allocate(vCounter, iCounter);

            // Dispatch jobs
            var dep = new TransformJob()
            {
                dataId = this.runningJobDataCounter
            }.Schedule(jobData.meshInstances.Count, 4);

            dep = new CopyJob()
            {
                dataId = this.runningJobDataCounter
            }.Schedule(dep);
            jobData.jobHandle = dep;

            jobData.jobId = this.runningJobDataCounter++;
            this.runningJobs.Add(jobData.jobId, jobData);
            JobHandle.ScheduleBatchedJobs();
        }
        /// <summary>
        /// Finishes the mesh rebuild, should only be called if the running job was finished.
        /// </summary>
        private void FinishMeshRebuild(StaticBatchingRebuildJobData jobData)
        {
            var groupKey = jobData.groupKey;

            // Flush rebuild
            Mesh m;

            if (this.meshes.TryGetValue(groupKey, out m))
            {
                Destroy(m);
                this.meshes.Remove(groupKey);
            }

            // Create mesh
            m             = new Mesh();
            m.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
            this.meshes.Add(groupKey, m);
            m.RecalculateBounds();

            // Flush
            jobData.Flush(m);
            this.runningJobs.Remove(jobData.jobId);
        }