bool SessionImpl::Join()
{
    // Cannot join a session while we're joined or currently attempting to join.
	if (MachineSessionState::DISCONNECTED == m_curState) 
	{
		LogInfo("Attempting to join session %s at %s:%i", m_name->GetString().c_str(), m_address.c_str(), m_port);

        // Verify that no other sessions are already in a joining state.
        int sessionCount = m_sessionMgr->GetSessionCount();
        for (int i = 0; i < sessionCount; i++)
        {
            SessionPtr curSession = m_sessionMgr->GetSession(i);

            // Fail if any sessions are in a pending state.
            // TODO: Instead, we should just auto leave all non-disconnected sessions.
            if (curSession->GetMachineSessionState() == MachineSessionState::JOINING)
            {
                LogError("SessionImpl::Join called while another session %s was in a joining state", curSession->GetName()->GetString().c_str());

				curSession->Leave();

				XTASSERT(curSession->GetMachineSessionState() == MachineSessionState::DISCONNECTED);

                return false;
            }
        }

        SessionPtr oldSession = m_sessionMgr->GetCurrentSession();

        if (oldSession)
        {
            LogInfo("Automatically leaving existing session %s", oldSession->GetName()->GetString().c_str());
            oldSession->Leave();

			XTASSERT(oldSession->GetMachineSessionState() == MachineSessionState::DISCONNECTED);
			XTASSERT(m_sessionMgr->GetCurrentSession() == NULL);
        }

		// Set out state to joining
		SetState(MachineSessionState::JOINING);

		// Set this as the current session for this machine
		m_sessionMgr->SetCurrentSession(this);

		// Attempting to join a new session; notify the listeners
		m_listenerList->NotifyListeners(&SessionListener::OnJoiningSession);

		// Attempt to open a connection to this session
		XSocketPtr socket = m_context->GetXSocketManager()->OpenConnection(m_address, m_port);
		if (XTVERIFY(socket))
		{
			// Initiate the handshake
			HandshakeCallback callback = CreateCallback3(this, &SessionImpl::OnHandshakeComplete);
			m_handshake = new NetworkHandshake(socket, new SessionHandshakeLogic(false), callback);

			return true;
		}
        else
        {
            LogError("Join failed we failed to create a socket to the session at %s:%u.", m_address.c_str(), m_port);
        }
	}
    else
    {
        LogError("Join failed because the current state is %s instead of DISCONNECTED", (m_curState == MachineSessionState::JOINING) ? "JOINING" : "JOINED");
    }
	
	return false;
}