IXmlExchange *
IApplication::S_PaAllocateApplication_YZ(POBJECT poProfileParent, const CXmlNode * pXmlNodeElement)
    {
    Assert(pXmlNodeElement != NULL);
    TProfile * pProfileParent = (TProfile *)poProfileParent;
    Assert(pProfileParent->EGetRuntimeClass() == RTI(TProfile));
    // Find the type of application to allocate
    PSZUC pszClass = pXmlNodeElement->PszuFindAttributeValue_NZ(c_szaApplicationClass_);
    const SApplicationAllocator * pApplicationAllocator = c_rgzApplicationAllocators;
    while (TRUE)
        {
        if (pApplicationAllocator->pszClass == NULL)
            break;
        Assert(pApplicationAllocator->pfnAllocator != NULL);
        if (FCompareStrings(pApplicationAllocator->pszClass, pszClass))
            return pApplicationAllocator->pfnAllocator(pProfileParent);
        pApplicationAllocator++;	// Search the next application
        } // while
    MessageLog_AppendTextFormatSev(eSeverityErrorWarning, "Unable to find application of class '$s'\n", pszClass);
    return NULL;
    }
//	Core routine to populate the Navigation Tree.
//
//	IMPLEMENTATION NOTES
//	At the moment the routine is written for a single configuration.  This code will have to be revised to support multiple configurations.
void
NavigationTree_PopulateTreeItemsAccordingToSelectedProfile(TProfile * pProfileSelected, BOOL fCreateNewProfile)
	{
	Endorse(pProfileSelected == NULL);	// Display all profiles
	Assert(g_pwNavigationTree != NULL);
	g_oConfiguration.m_pProfileSelected = pProfileSelected;

	// Flush the existing content of the Navigation Tree
	g_pwNavigationTree->NavigationTree_TreeItemUnselect();
	WTreeWidget * pwTreeView = g_pwNavigationTree->m_pwTreeView;
	QTreeWidgetItemIterator oIterator(pwTreeView);
	while (TRUE)
		{
		CTreeItemW * pTreeWidgetItem = (CTreeItemW *)*oIterator++;
		if (pTreeWidgetItem == NULL)
			break;
		ITreeItem * piTreeItem = pTreeWidgetItem->m_piTreeItem;
		Assert(piTreeItem != NULL);
		Assert(PGetRuntimeInterfaceOf_ITreeItem(piTreeItem) == piTreeItem);	// Make sure the pointer is valid
		Assert(piTreeItem->m_paTreeItemW_YZ != NULL);
		// Remember the state of each Tree Item before switching profile, so next time the profile is re-selected, then the entire arborescence is restored.
		if (piTreeItem->m_paTreeItemW_YZ->isExpanded())
			piTreeItem->m_uFlagsTreeItem |= ITreeItem::FTI_kfTreeItem_IsExpanded;
		else
			piTreeItem->m_uFlagsTreeItem &= ~ITreeItem::FTI_kfTreeItem_IsExpanded;

		//MessageLog_AppendTextFormatSev(eSeverityWarningToErrorLog, "0x$p: $s  m_uFlagsTreeItem = 0x$x\n", piTreeItem, piTreeItem->TreeItem_PszGetNameDisplay(), piTreeItem->m_uFlagsTreeItem);
		piTreeItem->m_paTreeItemW_YZ = NULL;	// This would cause a memory leak in the absence of pwTreeView->clear()
		} // while
	pwTreeView->clear();
	delete g_pTreeItemInbox;
	g_pTreeItemInbox = NULL;
	delete g_pTreeItemProfiles;
	g_pTreeItemProfiles = NULL;

	int cProfiles;
	TProfile ** prgpProfiles = g_oConfiguration.m_arraypaProfiles.PrgpGetProfiles(OUT &cProfiles);
	if (cProfiles == 1 && !fCreateNewProfile)
		pProfileSelected = prgpProfiles[0];	// If there is only one profile, then pretend the user selected that profile.  There is no need to show extra nodes which may confuse the user
	if (pProfileSelected != NULL)
		{
		// Display a single profile.  This is done by displaying the contacts first, and then the profile at the bottom
		pProfileSelected->TreeItemProfile_DisplayContactsWithinNavigationTree();
		if (pProfileSelected->m_arraypaAccountsXmpp.FIsEmpty())
			pProfileSelected->TreeItemProfile_DisplayProfileInfoWithinNavigationTree();
		pProfileSelected->TreeItemProfile_DisplayApplicationsWithinNavigationTree();
		}
	else
		{
		// Since we are displaying multiple profiles, we need to create two root items for the 'Inbox' and the 'Profiles'
		g_pTreeItemInbox = new TTreeItemInbox;
		g_pTreeItemProfiles = new TProfiles;

		for (int iProfile = 0; iProfile < cProfiles; iProfile++)
			{
			TProfile * pProfile = prgpProfiles[iProfile];
			Assert(pProfile->EGetRuntimeClass() == RTI(TProfile));
			pProfile->TreeItemProfile_DisplayContactsWithinNavigationTree();
			pProfile->TreeItemProfile_DisplayProfileInfoWithinNavigationTree();
			pProfile->TreeItemProfile_DisplayApplicationsWithinNavigationTree();
			}
		}
	NavigationTree_UpdateNameOfSelectedProfile();
	if (fCreateNewProfile || cProfiles == 0)
		{
		// Set the focus to "Profiles" if creating a new profile, or if there is no profile
		Assert(g_pTreeItemProfiles != NULL);
		g_pTreeItemProfiles->TreeItemLayout_SetFocus();
		}
	else
		pwTreeView->setCurrentItem(pwTreeView->topLevelItem(0));	// Select the first item
	} // NavigationTree_PopulateTreeItemsAccordingToSelectedProfile()