// Release the usage of a body.
        // Called when releasing use of a BSBody. BSShape is handled separately.
        public void DereferenceBody(BulletBody body, bool inTaintTime, BodyDestructionCallback bodyCallback)
        {
            if (body.ptr == IntPtr.Zero)
            {
                return;
            }

            lock (m_collectionActivityLock)
            {
                BodyDesc bodyDesc;
                if (Bodies.TryGetValue(body.ID, out bodyDesc))
                {
                    bodyDesc.referenceCount--;
                    bodyDesc.lastReferenced = System.DateTime.Now;
                    Bodies[body.ID]         = bodyDesc;
                    DetailLog("{0},BSShapeCollection.DereferenceBody,ref={1}", body.ID, bodyDesc.referenceCount);

                    // If body is no longer being used, free it -- bodies are never shared.
                    if (bodyDesc.referenceCount == 0)
                    {
                        Bodies.Remove(body.ID);
                        BSScene.TaintCallback removeOperation = delegate()
                        {
                            DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. ptr={1}",
                                      body.ID, body.ptr.ToString("X"));
                            // If the caller needs to know, pass the event up.
                            if (bodyCallback != null)
                            {
                                bodyCallback(body);
                            }

                            // Zero any reference to the shape so it is not freed when the body is deleted.
                            BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero);
                            // It may have already been removed from the world in which case the next is a NOOP.
                            BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr);
                            BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr);
                        };
                        // If already in taint-time, do the operations now. Otherwise queue for later.
                        if (inTaintTime)
                        {
                            removeOperation();
                        }
                        else
                        {
                            PhysicsScene.TaintedObject("BSShapeCollection.DereferenceBody", removeOperation);
                        }
                    }
                }
                else
                {
                    DetailLog("{0},BSShapeCollection.DereferenceBody,DID NOT FIND BODY", body.ID, bodyDesc.referenceCount);
                }
            }
        }