int CreatureManagerImplementation::notifyDestruction(TangibleObject* destructor, AiAgent* destructedObject, int condition) {
	if (destructedObject->isDead())
		return 1;

	destructedObject->setPosture(CreaturePosture::DEAD, true);

	destructedObject->updateTimeOfDeath();

	ManagedReference<PlayerManager*> playerManager = zoneServer->getPlayerManager();

	// lets unlock destructor so we dont get into complicated deadlocks

	// lets copy the damage map before we remove it all
	ThreatMap* threatMap = destructedObject->getThreatMap();
	ThreatMap copyThreatMap(*threatMap);

	threatMap->removeObservers();
	threatMap->removeAll(); // we can clear the original one

	if (destructedObject != destructor)
		destructor->unlock();

	bool shouldRescheduleCorpseDestruction = false;

	try {
		ManagedReference<CreatureObject*> player = copyThreatMap.getHighestDamageGroupLeader();

		uint64 ownerID = 0;

		if (player != NULL) {

			if(player->isGrouped()) {
				ownerID = player->getGroupID();
			} else {
				ownerID = player->getObjectID();
			}

			if (player->isPlayerCreature()) {
				Locker locker(player, destructedObject);

				player->notifyObservers(ObserverEventType::KILLEDCREATURE, destructedObject);

				FactionManager* factionManager = FactionManager::instance();

				if (!destructedObject->getPvPFaction().isEmpty() && !destructedObject->isEventMob()) {
					int level = destructedObject->getLevel();
					if(!player->isGrouped())
						factionManager->awardFactionStanding(player, destructedObject->getPvPFaction(), level);
					else
						factionManager->awardFactionStanding(copyThreatMap.getHighestDamagePlayer(), destructedObject->getPvPFaction(), level);
				}
			}

		}

		if (playerManager != NULL)
			playerManager->disseminateExperience(destructedObject, &copyThreatMap);

		SceneObject* creatureInventory = destructedObject->getSlottedObject("inventory");

		if (creatureInventory != NULL && player != NULL && player->isPlayerCreature()) {
			LootManager* lootManager = zoneServer->getLootManager();

			if (destructedObject->isNonPlayerCreatureObject() && !destructedObject->isEventMob())
				destructedObject->setCashCredits(lootManager->calculateLootCredits(destructedObject->getLevel()));

			creatureInventory->setContainerOwnerID(ownerID);

			lootManager->createLoot(creatureInventory, destructedObject);
		}

		CombatManager::instance()->attemptPeace(destructedObject);

		// Check to see if we can expedite the despawn of this corpse
		// We can expedite the despawn when corpse has no loot, no credits, player cannot harvest, and no group members in range can harvest
		shouldRescheduleCorpseDestruction = playerManager->shouldRescheduleCorpseDestruction(player, destructedObject);

	} catch (...) {
		destructedObject->scheduleDespawn();

		// now we can safely lock destructor again
		if (destructedObject != destructor)
			destructor->wlock(destructedObject);

		throw;
	}

	destructedObject->scheduleDespawn();

	if (shouldRescheduleCorpseDestruction) {

		Reference<DespawnCreatureTask*> despawn = destructedObject->getPendingTask("despawn").castTo<DespawnCreatureTask*>();

		if (despawn != NULL) {
			despawn->cancel();
			despawn->reschedule(10000);
		}
	}

	// now we can safely lock destructor again
	if (destructedObject != destructor)
		destructor->wlock(destructedObject);

	return 1;
}