void FullyConnectedMesh2::OnClosedConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
{
	(void) lostConnectionReason;
	(void) systemAddress;
	(void) rakNetGUID;

	unsigned int idx;
	for (idx=0; idx < participantList.Size(); idx++)
	{
		if (participantList[idx].rakNetGuid==rakNetGUID)
		{
			participantList[idx]=participantList[participantList.Size()-1];
#ifdef DEBUG_FCM2
			printf("Popping participant %s\n", participantList[participantList.Size()-1].rakNetGuid.ToString());
#endif

			participantList.Pop();
			if (rakNetGUID==hostRakNetGuid && ourFCMGuid!=0)
			{	
				if (participantList.Size()==0)
				{
					hostRakNetGuid=UNASSIGNED_RAKNET_GUID;
					hostFCM2Guid=ourFCMGuid;
				}
				else
				{
					CalculateHost(&hostRakNetGuid, &hostFCM2Guid);
				}
				PushNewHost(hostRakNetGuid);
			}
			return;
		}
	}

}
void FullyConnectedMesh2::OnRespondFCMGuid(Packet *packet)
{
	RakNet::BitStream bsIn(packet->data,packet->length,false);
	bsIn.IgnoreBytes(sizeof(MessageID));
	unsigned int responseAssignedConnectionCount;
	unsigned int responseTotalConnectionCount;
	bsIn.Read(responseAssignedConnectionCount);
	bsIn.Read(responseTotalConnectionCount);
	if (ourFCMGuid==0)
	{
		AssignOurFCMGuid(responseAssignedConnectionCount);
		guidRequestRetryList.Clear(true,__FILE__,__LINE__);
		// printf("Total connection count updated from %i to %i\n", totalConnectionCount, responseTotalConnectionCount);
		totalConnectionCount=responseTotalConnectionCount;
		if (participantList.Size()!=0)
		{
			CalculateHost(&hostSystemAddress, &hostRakNetGuid, &hostFCM2Guid);
			PushNewHost(hostSystemAddress, hostRakNetGuid);
		}
	}
	SendOurFCMGuid(packet->systemAddress);
	DataStructures::DefaultIndexType idx;
	for (idx=0; idx < participantList.Size(); idx++)
		SendOurFCMGuid(participantList[idx].systemAddress);
}
void FullyConnectedMesh2::OnClosedConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
{
	(void) lostConnectionReason;
	(void) systemAddress;
	(void) rakNetGUID;

	DataStructures::DefaultIndexType idx;
	idx = guidRequestRetryList.GetIndexOf(rakNetGUID);
	if (idx!=-1)
	{
		guidRequestRetryList.RemoveAtIndex(idx,__FILE__,__LINE__);
		// If ourFCMGuid is UNASSIGNED, SendFCMGuidRequest to all in guidRequestRetryList
		if (ourFCMGuid==0)
		{
			for (idx=0; idx < guidRequestRetryList.GetSize(); idx++)
			{
				SendFCMGuidRequest(rakPeerInterface->GetSystemAddressFromGuid(guidRequestRetryList[idx]));
			}
		}
	}

	for (idx=0; idx < participantList.Size(); idx++)
	{
		if (participantList[idx].systemAddress==systemAddress)
		{
			participantList[idx]=participantList[participantList.Size()-1];
#ifdef DEBUG_FCM2
			printf("Popping participant %s\n", participantList[participantList.Size()-1].rakNetGuid.ToString());
#endif

			participantList.Pop();
			if (systemAddress==hostSystemAddress && ourFCMGuid!=0)
			{	
				if (participantList.Size()==0)
				{
					hostSystemAddress=UNASSIGNED_SYSTEM_ADDRESS;
					hostRakNetGuid=rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
					hostFCM2Guid=ourFCMGuid;
				}
				else
				{
					CalculateHost(&hostSystemAddress, &hostRakNetGuid, &hostFCM2Guid);
				}
				PushNewHost(hostSystemAddress,hostRakNetGuid);
			}
			return;
		}
	}

}
void FullyConnectedMesh2::CalculateAndPushHost(void)
{
	RakNetGUID newHostGuid;
	FCM2Guid newFcmGuid;
	if (ParticipantListComplete())
	{
		CalculateHost(&newHostGuid, &newFcmGuid);
		if (newHostGuid!=lastPushedHost)
		{
			hostRakNetGuid=newHostGuid;
			hostFCM2Guid=newFcmGuid;
			PushNewHost(hostRakNetGuid);
		}
	}
}
void FullyConnectedMesh2::OnInformFCMGuid(Packet *packet)
{
	RakNet::BitStream bsIn(packet->data,packet->length,false);
	bsIn.IgnoreBytes(sizeof(MessageID));

	DataStructures::DefaultIndexType idx;
	for (idx=0; idx < participantList.Size(); idx++)
	{
		if (participantList[idx].rakNetGuid==packet->guid)
		{
//#ifdef DEBUG_FCM2
//			printf("Duplicate participant %s\n", packet->guid.ToString());
//#endif

			// Duplicate message, just ignore since they are already in the pqqqqqqarticipantList
			return;
		}
	}

	SystemAddress theirSystemAddress;
	if (rakPeerInterface->GetSystemAddressFromGuid(packet->guid)!=UNASSIGNED_SYSTEM_ADDRESS)
		theirSystemAddress=rakPeerInterface->GetSystemAddressFromGuid(packet->guid);
	else
		theirSystemAddress=packet->systemAddress;

	FCM2Guid theirFCMGuid;
	unsigned int theirTotalConnectionCount;
	bsIn.Read(theirFCMGuid);
	bsIn.Read(theirTotalConnectionCount);

#ifdef DEBUG_FCM2
	printf("Pushing participant %s\n", packet->guid.ToString());
#endif

	idx = guidRequestRetryList.GetIndexOf(packet->guid);
	if (idx!=-1)
		guidRequestRetryList.RemoveAtIndex(idx,__FILE__,__LINE__);

	participantList.Push(FCM2Participant(theirFCMGuid, packet->guid, theirSystemAddress), __FILE__,__LINE__);
	if (theirTotalConnectionCount>totalConnectionCount)
	{
	//	printf("Total connection count IS  updated from %i to %i\n", totalConnectionCount, theirTotalConnectionCount);
		totalConnectionCount=theirTotalConnectionCount;
	}
	else
	{
	//	printf("Total connection count NOT updated from %i to %i\n", totalConnectionCount, theirTotalConnectionCount);
	}

	if (ourFCMGuid!=0)
	{
		SystemAddress systemAddress;
		RakNetGUID rakNetGuid;
		FCM2Guid fcm2Guid;
		CalculateHost(&systemAddress, &rakNetGuid, &fcm2Guid);

		if (rakNetGuid!=hostRakNetGuid)
		{
			hostSystemAddress=systemAddress;
			hostRakNetGuid=rakNetGuid;
			hostFCM2Guid=fcm2Guid;
			PushNewHost(hostSystemAddress, hostRakNetGuid);
		}

		SendOurFCMGuid(packet->systemAddress);
	}
}