/// <summary>
        /// Synchronizes the contact set collections with self-overlaps in the spatial partition.
        /// </summary>
        private void Synchronize()
        {
            var overlaps = SpatialPartition.GetOverlaps();

            // We know that SAP uses a HashSet. If possible use a HashSet in foreach to
            // avoid allocating an enumerator on the heap.
            var overlapsHashSet = overlaps as HashSet <Pair <CollisionObject> >;

            if (overlapsHashSet != null)
            {
                // Use struct Enumerator of HashSet.
                foreach (var overlap in overlapsHashSet)
                {
                    CandidatePairs.AddOrMarkAsUsed(overlap);
                }
            }
            else
            {
                // Use IEnumerator<T>.
                foreach (var overlap in overlaps)
                {
                    CandidatePairs.AddOrMarkAsUsed(overlap);
                }
            }

            CandidatePairs.RemoveUnused(_obsoleteContactSetList);
            Debug.Assert(overlaps.Count() == CandidatePairs.Count);
        }
        /// <summary>
        /// Called when the spatial partition detected that an old overlap was removed.
        /// </summary>
        /// <param name="overlap">The overlapping pair of collision objects.</param>
        void IBroadPhase <CollisionObject> .Remove(Pair <CollisionObject> overlap)
        {
            var contactSet = CandidatePairs.Remove(overlap);

            if (contactSet != null)
            {
                _obsoleteContactSetList.Add(contactSet);
            }
        }
        /// <summary>
        /// Called when all self-overlaps of the spatial partition were removed.
        /// </summary>
        void IBroadPhase <CollisionObject> .Clear()
        {
            foreach (var contactSet in CandidatePairs)
            {
                _obsoleteContactSetList.Add(contactSet);
            }

            CandidatePairs.Clear();
        }
 void IBroadPhase <CollisionObject> .RemoveUnused()
 {
     CandidatePairs.RemoveUnused(_obsoleteContactSetList);
 }
 void IBroadPhase <CollisionObject> .AddOrMarkAsUsed(Pair <CollisionObject> overlap)
 {
     CandidatePairs.AddOrMarkAsUsed(overlap);
 }
 /// <summary>
 /// Called when the spatial partition detected that a collision object was removed.
 /// </summary>
 /// <param name="collisionObject">The collision objects to remove.</param>
 void IBroadPhase <CollisionObject> .Remove(CollisionObject collisionObject)
 {
     CandidatePairs.Remove(collisionObject, _obsoleteContactSetList);
 }