void PetManagerImplementation::handleChat(CreatureObject* speaker, AiAgent* pet, const String& message){

	if( speaker == NULL || pet == NULL )
		return;

	if( message.isEmpty() )
		return;

	ManagedReference<PetControlDevice*> pcd = pet->getControlDevice().get().castTo<PetControlDevice*>();

	if( pcd == NULL )
		return;

	// Handle command training
	if( pcd->getTrainingCommand() > 0 ){
		bool ownerChat = handleCommandTraining( speaker, pet, message );
		if (ownerChat)
			pcd->setTrainingCommand(0); // no longer training

		return;
	}

	ManagedWeakReference< CreatureObject*> linkedCreature = pet->getLinkedCreature();
	if( linkedCreature == NULL )
		return;

	// Check if speaker has permission to command pet
	// TODO: Add check for players other than owner that are on pet's friend list
	if( linkedCreature != speaker)
		return;

	ManagedWeakReference<SceneObject*> speakerParent = speaker->getRootParent();
	ManagedWeakReference<SceneObject*> petParent = pet->getRootParent();

	// If speaker is mounted, pet must be outdoors
	if( speaker->isRidingMount() && petParent != NULL )
		return;

	// If speaker is unmounted, pet and speaker must both be outdoors or inside same building
	if( !speaker->isRidingMount() && speakerParent != petParent )
		return;

	// Handle trained command
	if( isTrainedCommand( pcd, STAY, message ) ){
		enqueuePetCommand(speaker, pet, String("petStay").toLowerCase().hashCode(), "");
	}
	else if( isTrainedCommand( pcd, FOLLOW, message ) ){
		enqueuePetCommand(speaker, pet, String("petFollow").toLowerCase().hashCode(), "", true);
	}
	else if( isTrainedCommand( pcd, STORE, message ) ){
		enqueueOwnerOnlyPetCommand(speaker, pet, String("petStore").toLowerCase().hashCode(), "");
	}
	else if( isTrainedCommand( pcd, ATTACK, message ) ){
		enqueuePetCommand(speaker, pet, String("petAttack").toLowerCase().hashCode(), "");
	}
	else if( isTrainedCommand( pcd, GUARD, message ) ){
		speaker->sendSystemMessage("GUARD pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, FRIEND, message ) ){
		speaker->sendSystemMessage("FRIEND pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, FOLLOWOTHER, message ) ){
		enqueuePetCommand(speaker, pet, String("petFollow").toLowerCase().hashCode(), "");
	}
	else if( isTrainedCommand( pcd, TRICK1, message ) ){
		enqueuePetCommand(speaker, pet, String("petTrick").toLowerCase().hashCode(), "1", true);
	}
	else if( isTrainedCommand( pcd, TRICK2, message ) ){
		enqueuePetCommand(speaker, pet, String("petTrick").toLowerCase().hashCode(), "2", true);
	}
	else if( isTrainedCommand( pcd, PATROL, message ) ){
		speaker->sendSystemMessage("PATROL pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, FORMATION1, message ) ){
		speaker->sendSystemMessage("FORMATION2 pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, FORMATION2, message ) ){
		speaker->sendSystemMessage("FORMATION2 pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, SPECIAL_ATTACK1, message ) ){
		speaker->sendSystemMessage("SPECIAL_ATTACK1 pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, SPECIAL_ATTACK2, message ) ){
		speaker->sendSystemMessage("SPECIAL_ATTACK2 pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, RANGED_ATTACK, message ) ){
		speaker->sendSystemMessage("RANGED_ATTACK pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, GROUP, message ) ){
		enqueueOwnerOnlyPetCommand(speaker, pet, String("petGroup").toLowerCase().hashCode(), "");
	}
	else if( isTrainedCommand( pcd, RECHARGEOTHER, message ) ){
		enqueuePetCommand(speaker, pet, String("petRechargeOther").toLowerCase().hashCode(), "");
	}
	else if( isTrainedCommand( pcd, TRANSFER, message ) ){
		enqueueOwnerOnlyPetCommand(speaker, pet, String("petTransfer").toLowerCase().hashCode(), "");
	}

}
void PetManagerImplementation::handleChat(CreatureObject* speaker, AiAgent* pet, const String& message){
	if( speaker == NULL || pet == NULL )
		return;

	if( message.isEmpty() )
		return;

	if (pet->isDead() || pet->isIncapacitated())
		return;

	ManagedReference<PetControlDevice*> pcd = pet->getControlDevice().get().castTo<PetControlDevice*>();

	if( pcd == NULL )
		return;

	// Handle command training
	if( pcd->getTrainingCommand() > 0 ){
		bool ownerChat = handleCommandTraining( speaker, pet, message );
		if (ownerChat) {
			Locker locker(pcd);
			pcd->setTrainingCommand(0); // no longer training
		}

		return;
	}

	ManagedWeakReference< CreatureObject*> linkedCreature = pet->getLinkedCreature();
	if( linkedCreature == NULL )
		return;

	// Check if speaker has permission to command pet
	if( linkedCreature != speaker && !pcd->isFriend(speaker->getObjectID()))
		return;

	ManagedWeakReference<SceneObject*> speakerParent = speaker->getRootParent();
	ManagedWeakReference<SceneObject*> petParent = pet->getRootParent();

	// If speaker is mounted, pet must be outdoors
	if( speaker->isRidingMount() && petParent != NULL )
		return;

	// If speaker is unmounted, pet and speaker must both be outdoors or inside same building
	if( !speaker->isRidingMount() && speakerParent != petParent )
		return;

	// Handle trained command
	if( isTrainedCommand( pcd, STAY, message ) ){
		enqueuePetCommand(speaker, pet, STRING_HASHCODE("petstay"), "");
	}
	else if( isTrainedCommand( pcd, FOLLOW, message ) ){
		enqueuePetCommand(speaker, pet, STRING_HASHCODE("petfollow"), "", true);
	}
	else if( isTrainedCommand( pcd, STORE, message ) ){
		enqueueOwnerOnlyPetCommand(speaker, pet, STRING_HASHCODE("petstore"), "");
	}
	else if( isTrainedCommand( pcd, ATTACK, message ) ){
		enqueuePetCommand(speaker, pet, STRING_HASHCODE("petattack"), "");
	}
	else if( isTrainedCommand( pcd, GUARD, message ) ){
		enqueuePetCommand(speaker, pet, STRING_HASHCODE("petguard"), "", true);
	}
	else if( isTrainedCommand( pcd, FRIEND, message ) ){
		enqueueOwnerOnlyPetCommand(speaker, pet, STRING_HASHCODE("petfriend"), "");
	}
	else if( isTrainedCommand( pcd, FOLLOWOTHER, message ) ){
		enqueuePetCommand(speaker, pet, STRING_HASHCODE("petfollow"), "");
	}
	else if( isTrainedCommand( pcd, TRICK1, message ) ){
		enqueuePetCommand(speaker, pet, STRING_HASHCODE("pettrick"), "1", true);
	}
	else if( isTrainedCommand( pcd, TRICK2, message ) ){
		enqueuePetCommand(speaker, pet, STRING_HASHCODE("pettrick"), "2", true);
	}
	else if( isTrainedCommand( pcd, PATROL, message ) ){
		enqueuePetCommand(speaker, pet, STRING_HASHCODE("petpatrol"), "");
	}
	else if( isTrainedCommand( pcd, GETPATROLPOINT, message ) ){
		enqueuePetCommand(speaker, pet, STRING_HASHCODE("petgetpatrolpoint"), "", true);
	}
	else if( isTrainedCommand( pcd, CLEARPATROLPOINTS, message ) ){
		enqueuePetCommand(speaker, pet, STRING_HASHCODE("petclearpatrolpoints"), "", true);
	}
	else if( isTrainedCommand( pcd, FORMATION1, message ) ){
		speaker->sendSystemMessage("FORMATION2 pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, FORMATION2, message ) ){
		speaker->sendSystemMessage("FORMATION2 pet command is not yet implemented.");
	}
	else if( isTrainedCommand( pcd, SPECIAL_ATTACK1, message ) ){
		enqueuePetCommand(speaker, pet, STRING_HASHCODE("petspecialattack"), "1");
	}
	else if( isTrainedCommand( pcd, SPECIAL_ATTACK2, message ) ){
		enqueuePetCommand(speaker, pet, STRING_HASHCODE("petspecialattack"), "2");
	}
	else if( isTrainedCommand( pcd, RANGED_ATTACK, message ) ){
		enqueuePetCommand(speaker, pet, STRING_HASHCODE("petrangedattack"), "", true);
	}
	else if( isTrainedCommand( pcd, GROUP, message ) ){
		enqueueOwnerOnlyPetCommand(speaker, pet, STRING_HASHCODE("petgroup"), "");
	}
	else if( isTrainedCommand( pcd, RECHARGEOTHER, message ) ){
		enqueuePetCommand(speaker, pet, STRING_HASHCODE("petrechargeother"), "");
	}
	else if( isTrainedCommand( pcd, TRANSFER, message ) ){
		enqueueOwnerOnlyPetCommand(speaker, pet, STRING_HASHCODE("pettransfer"), "");
	}

	// Hand off to droid modules for handling
	if( pcd->getPetType() == PetManager::DROIDPET ){

		DroidObject* droidObject = cast<DroidObject*>(pet);
		if( droidObject != NULL ){
			droidObject->handleChat(speaker, message);
		}

	}

}